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_init_ticks
;
167 unsigned int ai_scan_ticks
;
168 unsigned int ai_chan_ticks
;
171 enum me4000_boardid
{
187 struct me4000_board
{
190 unsigned int can_do_diff_ai
:1;
191 unsigned int can_do_sh_ai
:1; /* sample & hold (8 channels) */
192 unsigned int ex_trig_analog
:1;
193 unsigned int has_ao
:1;
194 unsigned int has_ao_fifo
:1;
195 unsigned int has_counter
:1;
198 static const struct me4000_board me4000_boards
[] = {
304 * NOTE: the ranges here are inverted compared to the values
305 * written to the ME4000_AI_CHANNEL_LIST_REG,
307 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
309 static const struct comedi_lrange me4000_ai_range
= {
318 static int me4000_xilinx_download(struct comedi_device
*dev
,
319 const u8
*data
, size_t size
,
320 unsigned long context
)
322 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
323 struct me4000_private
*devpriv
= dev
->private;
324 unsigned long xilinx_iobase
= pci_resource_start(pcidev
, 5);
325 unsigned int file_length
;
333 * Set PLX local interrupt 2 polarity to high.
334 * Interrupt is thrown by init pin of xilinx.
336 outl(PLX9052_INTCSR_LI2POL
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
338 /* Set /CS and /WRITE of the Xilinx */
339 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
340 val
|= PLX9052_CNTRL_UIO2_DATA
;
341 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
343 /* Init Xilinx with CS1 */
344 inb(xilinx_iobase
+ 0xC8);
346 /* Wait until /INIT pin is set */
348 val
= inl(devpriv
->plx_regbase
+ PLX9052_INTCSR
);
349 if (!(val
& PLX9052_INTCSR_LI2STAT
)) {
350 dev_err(dev
->class_dev
, "Can't init Xilinx\n");
354 /* Reset /CS and /WRITE of the Xilinx */
355 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
356 val
&= ~PLX9052_CNTRL_UIO2_DATA
;
357 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
359 /* Download Xilinx firmware */
360 file_length
= (((unsigned int)data
[0] & 0xff) << 24) +
361 (((unsigned int)data
[1] & 0xff) << 16) +
362 (((unsigned int)data
[2] & 0xff) << 8) +
363 ((unsigned int)data
[3] & 0xff);
366 for (i
= 0; i
< file_length
; i
++) {
367 outb(data
[16 + i
], xilinx_iobase
);
370 /* Check if BUSY flag is low */
371 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
372 if (val
& PLX9052_CNTRL_UIO1_DATA
) {
373 dev_err(dev
->class_dev
,
374 "Xilinx is still busy (i = %d)\n", i
);
379 /* If done flag is high download was successful */
380 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
381 if (!(val
& PLX9052_CNTRL_UIO0_DATA
)) {
382 dev_err(dev
->class_dev
, "DONE flag is not set\n");
383 dev_err(dev
->class_dev
, "Download not successful\n");
387 /* Set /CS and /WRITE */
388 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
389 val
|= PLX9052_CNTRL_UIO2_DATA
;
390 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
395 static void me4000_reset(struct comedi_device
*dev
)
397 struct me4000_private
*devpriv
= dev
->private;
401 /* Make a hardware reset */
402 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
403 val
|= PLX9052_CNTRL_PCI_RESET
;
404 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
405 val
&= ~PLX9052_CNTRL_PCI_RESET
;
406 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
408 /* 0x8000 to the DACs means an output voltage of 0V */
409 for (chan
= 0; chan
< 4; chan
++)
410 outl(0x8000, dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
412 /* Set both stop bits in the analog input control register */
413 outl(ME4000_AI_CTRL_IMMEDIATE_STOP
| ME4000_AI_CTRL_STOP
,
414 dev
->iobase
+ ME4000_AI_CTRL_REG
);
416 /* Set both stop bits in the analog output control register */
417 val
= ME4000_AO_CTRL_IMMEDIATE_STOP
| ME4000_AO_CTRL_STOP
;
418 for (chan
= 0; chan
< 4; chan
++)
419 outl(val
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
421 /* Enable interrupts on the PLX */
422 outl(PLX9052_INTCSR_LI1ENAB
|
423 PLX9052_INTCSR_LI1POL
|
424 PLX9052_INTCSR_PCIENAB
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
426 /* Set the adustment register for AO demux */
427 outl(ME4000_AO_DEMUX_ADJUST_VALUE
,
428 dev
->iobase
+ ME4000_AO_DEMUX_ADJUST_REG
);
431 * Set digital I/O direction for port 0
432 * to output on isolated versions
434 if (!(inl(dev
->iobase
+ ME4000_DIO_DIR_REG
) & 0x1))
435 outl(0x1, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
438 static int me4000_ai_eoc(struct comedi_device
*dev
,
439 struct comedi_subdevice
*s
,
440 struct comedi_insn
*insn
,
441 unsigned long context
)
445 status
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
446 if (status
& ME4000_AI_STATUS_EF_DATA
)
451 static int me4000_ai_insn_read(struct comedi_device
*dev
,
452 struct comedi_subdevice
*s
,
453 struct comedi_insn
*insn
,
456 unsigned int chan
= CR_CHAN(insn
->chanspec
);
457 unsigned int range
= CR_RANGE(insn
->chanspec
);
458 unsigned int aref
= CR_AREF(insn
->chanspec
);
464 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
465 if (aref
== AREF_DIFF
) {
466 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
467 dev_err(dev
->class_dev
,
468 "Differential inputs are not available\n");
472 if (!comedi_range_is_bipolar(s
, range
)) {
473 dev_err(dev
->class_dev
,
474 "Range must be bipolar when aref = diff\n");
478 if (chan
>= (s
->n_chan
/ 2)) {
479 dev_err(dev
->class_dev
,
480 "Analog input is not available\n");
483 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
486 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
488 /* Clear channel list, data fifo and both stop bits */
489 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
490 tmp
&= ~(ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
|
491 ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
);
492 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
494 /* Set the acquisition mode to single */
495 tmp
&= ~(ME4000_AI_CTRL_MODE_0
| ME4000_AI_CTRL_MODE_1
|
496 ME4000_AI_CTRL_MODE_2
);
497 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
499 /* Enable channel list and data fifo */
500 tmp
|= ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
;
501 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
503 /* Generate channel list entry */
504 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
506 /* Set the timer to maximum sample rate */
507 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
508 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
510 for (i
= 0; i
< insn
->n
; i
++) {
513 /* start conversion by dummy read */
514 inl(dev
->iobase
+ ME4000_AI_START_REG
);
516 ret
= comedi_timeout(dev
, s
, insn
, me4000_ai_eoc
, 0);
520 /* read two's complement value and munge to offset binary */
521 val
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
);
522 data
[i
] = comedi_offset_munge(s
, val
);
528 static int me4000_ai_cancel(struct comedi_device
*dev
,
529 struct comedi_subdevice
*s
)
533 /* Stop any running conversion */
534 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
535 tmp
&= ~(ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
);
536 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
538 /* Clear the control register */
539 outl(0x0, dev
->iobase
+ ME4000_AI_CTRL_REG
);
544 static int me4000_ai_check_chanlist(struct comedi_device
*dev
,
545 struct comedi_subdevice
*s
,
546 struct comedi_cmd
*cmd
)
548 unsigned int aref0
= CR_AREF(cmd
->chanlist
[0]);
551 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
552 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
553 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
554 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
557 dev_dbg(dev
->class_dev
,
558 "Mode is not equal for all entries\n");
562 if (aref
== AREF_DIFF
) {
563 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
564 dev_err(dev
->class_dev
,
565 "Differential inputs are not available\n");
569 if (chan
>= (s
->n_chan
/ 2)) {
570 dev_dbg(dev
->class_dev
,
571 "Channel number to high\n");
575 if (!comedi_range_is_bipolar(s
, range
)) {
576 dev_dbg(dev
->class_dev
,
577 "Bipolar is not selected in differential mode\n");
586 static void me4000_ai_round_cmd_args(struct comedi_device
*dev
,
587 struct comedi_subdevice
*s
,
588 struct comedi_cmd
*cmd
)
590 struct me4000_private
*devpriv
= dev
->private;
593 devpriv
->ai_init_ticks
= 0;
594 devpriv
->ai_scan_ticks
= 0;
595 devpriv
->ai_chan_ticks
= 0;
597 if (cmd
->start_arg
) {
598 devpriv
->ai_init_ticks
= (cmd
->start_arg
* 33) / 1000;
599 rest
= (cmd
->start_arg
* 33) % 1000;
601 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
603 devpriv
->ai_init_ticks
++;
604 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
606 devpriv
->ai_init_ticks
++;
610 if (cmd
->scan_begin_arg
) {
611 devpriv
->ai_scan_ticks
= (cmd
->scan_begin_arg
* 33) / 1000;
612 rest
= (cmd
->scan_begin_arg
* 33) % 1000;
614 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
616 devpriv
->ai_scan_ticks
++;
617 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
619 devpriv
->ai_scan_ticks
++;
623 if (cmd
->convert_arg
) {
624 devpriv
->ai_chan_ticks
= (cmd
->convert_arg
* 33) / 1000;
625 rest
= (cmd
->convert_arg
* 33) % 1000;
627 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
629 devpriv
->ai_chan_ticks
++;
630 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
632 devpriv
->ai_chan_ticks
++;
637 static void ai_write_timer(struct comedi_device
*dev
)
639 struct me4000_private
*devpriv
= dev
->private;
641 outl(devpriv
->ai_init_ticks
- 1,
642 dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_LOW_REG
);
643 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_HIGH_REG
);
645 if (devpriv
->ai_scan_ticks
) {
646 outl(devpriv
->ai_scan_ticks
- 1,
647 dev
->iobase
+ ME4000_AI_SCAN_TIMER_LOW_REG
);
648 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_TIMER_HIGH_REG
);
651 outl(devpriv
->ai_chan_ticks
- 1,
652 dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
653 outl(devpriv
->ai_chan_ticks
- 1,
654 dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
657 static int me4000_ai_write_chanlist(struct comedi_device
*dev
,
658 struct comedi_subdevice
*s
,
659 struct comedi_cmd
*cmd
)
663 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
664 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
665 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
666 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
669 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
671 if (aref
== AREF_DIFF
)
672 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
674 if (i
== (cmd
->chanlist_len
- 1))
675 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
677 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
683 static int ai_prepare(struct comedi_device
*dev
,
684 struct comedi_subdevice
*s
,
685 struct comedi_cmd
*cmd
)
687 unsigned int tmp
= 0;
689 /* Write timer arguments */
692 /* Reset control register */
693 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
696 if ((cmd
->start_src
== TRIG_EXT
&&
697 cmd
->scan_begin_src
== TRIG_TIMER
&&
698 cmd
->convert_src
== TRIG_TIMER
) ||
699 (cmd
->start_src
== TRIG_EXT
&&
700 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
701 cmd
->convert_src
== TRIG_TIMER
)) {
702 tmp
= ME4000_AI_CTRL_MODE_1
|
703 ME4000_AI_CTRL_CHANNEL_FIFO
|
704 ME4000_AI_CTRL_DATA_FIFO
;
705 } else if (cmd
->start_src
== TRIG_EXT
&&
706 cmd
->scan_begin_src
== TRIG_EXT
&&
707 cmd
->convert_src
== TRIG_TIMER
) {
708 tmp
= ME4000_AI_CTRL_MODE_2
|
709 ME4000_AI_CTRL_CHANNEL_FIFO
|
710 ME4000_AI_CTRL_DATA_FIFO
;
711 } else if (cmd
->start_src
== TRIG_EXT
&&
712 cmd
->scan_begin_src
== TRIG_EXT
&&
713 cmd
->convert_src
== TRIG_EXT
) {
714 tmp
= ME4000_AI_CTRL_MODE_0
|
715 ME4000_AI_CTRL_MODE_1
|
716 ME4000_AI_CTRL_CHANNEL_FIFO
|
717 ME4000_AI_CTRL_DATA_FIFO
;
719 tmp
= ME4000_AI_CTRL_MODE_0
|
720 ME4000_AI_CTRL_CHANNEL_FIFO
|
721 ME4000_AI_CTRL_DATA_FIFO
;
725 if (cmd
->stop_src
== TRIG_COUNT
) {
726 outl(cmd
->chanlist_len
* cmd
->stop_arg
,
727 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
728 tmp
|= ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
;
729 } else if (cmd
->stop_src
== TRIG_NONE
&&
730 cmd
->scan_end_src
== TRIG_COUNT
) {
731 outl(cmd
->scan_end_arg
,
732 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
733 tmp
|= ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
;
735 tmp
|= ME4000_AI_CTRL_HF_IRQ
;
738 /* Write the setup to the control register */
739 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
741 /* Write the channel list */
742 me4000_ai_write_chanlist(dev
, s
, cmd
);
747 static int me4000_ai_do_cmd(struct comedi_device
*dev
,
748 struct comedi_subdevice
*s
)
751 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
753 /* Reset the analog input */
754 err
= me4000_ai_cancel(dev
, s
);
758 /* Prepare the AI for acquisition */
759 err
= ai_prepare(dev
, s
, cmd
);
763 /* Start acquistion by dummy read */
764 inl(dev
->iobase
+ ME4000_AI_START_REG
);
769 static int me4000_ai_do_cmd_test(struct comedi_device
*dev
,
770 struct comedi_subdevice
*s
,
771 struct comedi_cmd
*cmd
)
773 struct me4000_private
*devpriv
= dev
->private;
776 /* Step 1 : check if triggers are trivially valid */
778 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
779 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
780 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
781 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
782 TRIG_TIMER
| TRIG_EXT
);
783 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
,
784 TRIG_NONE
| TRIG_COUNT
);
785 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_NONE
| TRIG_COUNT
);
790 /* Step 2a : make sure trigger sources are unique */
792 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
793 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
794 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
795 err
|= comedi_check_trigger_is_unique(cmd
->scan_end_src
);
796 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
798 /* Step 2b : and mutually compatible */
800 if (cmd
->start_src
== TRIG_NOW
&&
801 cmd
->scan_begin_src
== TRIG_TIMER
&&
802 cmd
->convert_src
== TRIG_TIMER
) {
803 } else if (cmd
->start_src
== TRIG_NOW
&&
804 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
805 cmd
->convert_src
== TRIG_TIMER
) {
806 } else if (cmd
->start_src
== TRIG_EXT
&&
807 cmd
->scan_begin_src
== TRIG_TIMER
&&
808 cmd
->convert_src
== TRIG_TIMER
) {
809 } else if (cmd
->start_src
== TRIG_EXT
&&
810 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
811 cmd
->convert_src
== TRIG_TIMER
) {
812 } else if (cmd
->start_src
== TRIG_EXT
&&
813 cmd
->scan_begin_src
== TRIG_EXT
&&
814 cmd
->convert_src
== TRIG_TIMER
) {
815 } else if (cmd
->start_src
== TRIG_EXT
&&
816 cmd
->scan_begin_src
== TRIG_EXT
&&
817 cmd
->convert_src
== TRIG_EXT
) {
825 /* Step 3: check if arguments are trivially valid */
827 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
829 if (cmd
->chanlist_len
< 1) {
830 cmd
->chanlist_len
= 1;
834 /* Round the timer arguments */
835 me4000_ai_round_cmd_args(dev
, s
, cmd
);
837 if (devpriv
->ai_init_ticks
< 66) {
838 cmd
->start_arg
= 2000;
841 if (devpriv
->ai_scan_ticks
&& devpriv
->ai_scan_ticks
< 67) {
842 cmd
->scan_begin_arg
= 2031;
845 if (devpriv
->ai_chan_ticks
< 66) {
846 cmd
->convert_arg
= 2000;
850 if (cmd
->stop_src
== TRIG_COUNT
)
851 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
853 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
859 * Stage 4. Check for argument conflicts.
861 if (cmd
->start_src
== TRIG_NOW
&&
862 cmd
->scan_begin_src
== TRIG_TIMER
&&
863 cmd
->convert_src
== TRIG_TIMER
) {
864 /* Check timer arguments */
865 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
866 dev_err(dev
->class_dev
, "Invalid start arg\n");
867 cmd
->start_arg
= 2000; /* 66 ticks at least */
870 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
871 dev_err(dev
->class_dev
, "Invalid convert arg\n");
872 cmd
->convert_arg
= 2000; /* 66 ticks at least */
875 if (devpriv
->ai_scan_ticks
<=
876 cmd
->chanlist_len
* devpriv
->ai_chan_ticks
) {
877 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
879 /* At least one tick more */
880 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
883 } else if (cmd
->start_src
== TRIG_NOW
&&
884 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
885 cmd
->convert_src
== TRIG_TIMER
) {
886 /* Check timer arguments */
887 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
888 dev_err(dev
->class_dev
, "Invalid start arg\n");
889 cmd
->start_arg
= 2000; /* 66 ticks at least */
892 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
893 dev_err(dev
->class_dev
, "Invalid convert arg\n");
894 cmd
->convert_arg
= 2000; /* 66 ticks at least */
897 } else if (cmd
->start_src
== TRIG_EXT
&&
898 cmd
->scan_begin_src
== TRIG_TIMER
&&
899 cmd
->convert_src
== TRIG_TIMER
) {
900 /* Check timer arguments */
901 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
902 dev_err(dev
->class_dev
, "Invalid start arg\n");
903 cmd
->start_arg
= 2000; /* 66 ticks at least */
906 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
907 dev_err(dev
->class_dev
, "Invalid convert arg\n");
908 cmd
->convert_arg
= 2000; /* 66 ticks at least */
911 if (devpriv
->ai_scan_ticks
<=
912 cmd
->chanlist_len
* devpriv
->ai_chan_ticks
) {
913 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
915 /* At least one tick more */
916 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
919 } else if (cmd
->start_src
== TRIG_EXT
&&
920 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
921 cmd
->convert_src
== TRIG_TIMER
) {
922 /* Check timer arguments */
923 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
924 dev_err(dev
->class_dev
, "Invalid start arg\n");
925 cmd
->start_arg
= 2000; /* 66 ticks at least */
928 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
929 dev_err(dev
->class_dev
, "Invalid convert arg\n");
930 cmd
->convert_arg
= 2000; /* 66 ticks at least */
933 } else if (cmd
->start_src
== TRIG_EXT
&&
934 cmd
->scan_begin_src
== TRIG_EXT
&&
935 cmd
->convert_src
== TRIG_TIMER
) {
936 /* Check timer arguments */
937 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
938 dev_err(dev
->class_dev
, "Invalid start arg\n");
939 cmd
->start_arg
= 2000; /* 66 ticks at least */
942 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
943 dev_err(dev
->class_dev
, "Invalid convert arg\n");
944 cmd
->convert_arg
= 2000; /* 66 ticks at least */
947 } else if (cmd
->start_src
== TRIG_EXT
&&
948 cmd
->scan_begin_src
== TRIG_EXT
&&
949 cmd
->convert_src
== TRIG_EXT
) {
950 /* Check timer arguments */
951 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
952 dev_err(dev
->class_dev
, "Invalid start arg\n");
953 cmd
->start_arg
= 2000; /* 66 ticks at least */
957 if (cmd
->scan_end_src
== TRIG_COUNT
) {
958 if (cmd
->scan_end_arg
== 0) {
959 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
960 cmd
->scan_end_arg
= 1;
968 /* Step 5: check channel list if it exists */
969 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
970 err
|= me4000_ai_check_chanlist(dev
, s
, cmd
);
978 static irqreturn_t
me4000_ai_isr(int irq
, void *dev_id
)
981 struct comedi_device
*dev
= dev_id
;
982 struct comedi_subdevice
*s
= dev
->read_subdev
;
990 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
991 ME4000_IRQ_STATUS_AI_HF
) {
992 /* Read status register to find out what happened */
993 tmp
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
995 if (!(tmp
& ME4000_AI_STATUS_FF_DATA
) &&
996 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
997 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
998 c
= ME4000_AI_FIFO_COUNT
;
1001 * FIFO overflow, so stop conversion
1002 * and disable all interrupts
1004 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1005 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1006 ME4000_AI_CTRL_SC_IRQ
);
1007 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1009 s
->async
->events
|= COMEDI_CB_ERROR
;
1011 dev_err(dev
->class_dev
, "FIFO overflow\n");
1012 } else if ((tmp
& ME4000_AI_STATUS_FF_DATA
) &&
1013 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
1014 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
1015 c
= ME4000_AI_FIFO_COUNT
/ 2;
1017 dev_err(dev
->class_dev
,
1018 "Can't determine state of fifo\n");
1022 * Undefined state, so stop conversion
1023 * and disable all interrupts
1025 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1026 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1027 ME4000_AI_CTRL_SC_IRQ
);
1028 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1030 s
->async
->events
|= COMEDI_CB_ERROR
;
1032 dev_err(dev
->class_dev
, "Undefined FIFO state\n");
1035 for (i
= 0; i
< c
; i
++) {
1036 /* Read value from data fifo */
1037 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
1040 if (!comedi_buf_write_samples(s
, &lval
, 1)) {
1042 * Buffer overflow, so stop conversion
1043 * and disable all interrupts
1045 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1046 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1047 ME4000_AI_CTRL_SC_IRQ
);
1048 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1053 /* Work is done, so reset the interrupt */
1054 tmp
|= ME4000_AI_CTRL_HF_IRQ_RESET
;
1055 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1056 tmp
&= ~ME4000_AI_CTRL_HF_IRQ_RESET
;
1057 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1060 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
1061 ME4000_IRQ_STATUS_SC
) {
1062 s
->async
->events
|= COMEDI_CB_EOA
;
1065 * Acquisition is complete, so stop
1066 * conversion and disable all interrupts
1068 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
1069 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1070 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
);
1071 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1073 /* Poll data until fifo empty */
1074 while (inl(dev
->iobase
+ ME4000_AI_STATUS_REG
) &
1075 ME4000_AI_STATUS_EF_DATA
) {
1076 /* Read value from data fifo */
1077 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
1080 if (!comedi_buf_write_samples(s
, &lval
, 1))
1084 /* Work is done, so reset the interrupt */
1085 tmp
|= ME4000_AI_CTRL_SC_IRQ_RESET
;
1086 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1087 tmp
&= ~ME4000_AI_CTRL_SC_IRQ_RESET
;
1088 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1091 comedi_handle_events(dev
, s
);
1096 static int me4000_ao_insn_write(struct comedi_device
*dev
,
1097 struct comedi_subdevice
*s
,
1098 struct comedi_insn
*insn
,
1101 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1104 /* Stop any running conversion */
1105 tmp
= inl(dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1106 tmp
|= ME4000_AO_CTRL_IMMEDIATE_STOP
;
1107 outl(tmp
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1109 /* Clear control register and set to single mode */
1110 outl(0x0, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1112 /* Write data value */
1113 outl(data
[0], dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
1115 /* Store in the mirror */
1116 s
->readback
[chan
] = data
[0];
1121 static int me4000_dio_insn_bits(struct comedi_device
*dev
,
1122 struct comedi_subdevice
*s
,
1123 struct comedi_insn
*insn
,
1126 if (comedi_dio_update_state(s
, data
)) {
1127 outl((s
->state
>> 0) & 0xFF,
1128 dev
->iobase
+ ME4000_DIO_PORT_0_REG
);
1129 outl((s
->state
>> 8) & 0xFF,
1130 dev
->iobase
+ ME4000_DIO_PORT_1_REG
);
1131 outl((s
->state
>> 16) & 0xFF,
1132 dev
->iobase
+ ME4000_DIO_PORT_2_REG
);
1133 outl((s
->state
>> 24) & 0xFF,
1134 dev
->iobase
+ ME4000_DIO_PORT_3_REG
);
1137 data
[1] = ((inl(dev
->iobase
+ ME4000_DIO_PORT_0_REG
) & 0xFF) << 0) |
1138 ((inl(dev
->iobase
+ ME4000_DIO_PORT_1_REG
) & 0xFF) << 8) |
1139 ((inl(dev
->iobase
+ ME4000_DIO_PORT_2_REG
) & 0xFF) << 16) |
1140 ((inl(dev
->iobase
+ ME4000_DIO_PORT_3_REG
) & 0xFF) << 24);
1145 static int me4000_dio_insn_config(struct comedi_device
*dev
,
1146 struct comedi_subdevice
*s
,
1147 struct comedi_insn
*insn
,
1150 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1164 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, mask
);
1168 tmp
= inl(dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1169 tmp
&= ~(ME4000_DIO_CTRL_MODE_0
| ME4000_DIO_CTRL_MODE_1
|
1170 ME4000_DIO_CTRL_MODE_2
| ME4000_DIO_CTRL_MODE_3
|
1171 ME4000_DIO_CTRL_MODE_4
| ME4000_DIO_CTRL_MODE_5
|
1172 ME4000_DIO_CTRL_MODE_6
| ME4000_DIO_CTRL_MODE_7
);
1173 if (s
->io_bits
& 0x000000ff)
1174 tmp
|= ME4000_DIO_CTRL_MODE_0
;
1175 if (s
->io_bits
& 0x0000ff00)
1176 tmp
|= ME4000_DIO_CTRL_MODE_2
;
1177 if (s
->io_bits
& 0x00ff0000)
1178 tmp
|= ME4000_DIO_CTRL_MODE_4
;
1179 if (s
->io_bits
& 0xff000000)
1180 tmp
|= ME4000_DIO_CTRL_MODE_6
;
1183 * Check for optoisolated ME-4000 version.
1184 * If one the first port is a fixed output
1185 * port and the second is a fixed input port.
1187 if (inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1188 s
->io_bits
|= 0x000000ff;
1189 s
->io_bits
&= ~0x0000ff00;
1190 tmp
|= ME4000_DIO_CTRL_MODE_0
;
1191 tmp
&= ~(ME4000_DIO_CTRL_MODE_2
| ME4000_DIO_CTRL_MODE_3
);
1194 outl(tmp
, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1199 static int me4000_auto_attach(struct comedi_device
*dev
,
1200 unsigned long context
)
1202 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1203 const struct me4000_board
*board
= NULL
;
1204 struct me4000_private
*devpriv
;
1205 struct comedi_subdevice
*s
;
1208 if (context
< ARRAY_SIZE(me4000_boards
))
1209 board
= &me4000_boards
[context
];
1212 dev
->board_ptr
= board
;
1213 dev
->board_name
= board
->name
;
1215 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1219 result
= comedi_pci_enable(dev
);
1223 devpriv
->plx_regbase
= pci_resource_start(pcidev
, 1);
1224 dev
->iobase
= pci_resource_start(pcidev
, 2);
1225 if (!devpriv
->plx_regbase
|| !dev
->iobase
)
1228 result
= comedi_load_firmware(dev
, &pcidev
->dev
, ME4000_FIRMWARE
,
1229 me4000_xilinx_download
, 0);
1235 if (pcidev
->irq
> 0) {
1236 result
= request_irq(pcidev
->irq
, me4000_ai_isr
, IRQF_SHARED
,
1237 dev
->board_name
, dev
);
1239 dev
->irq
= pcidev
->irq
;
1242 result
= comedi_alloc_subdevices(dev
, 4);
1246 /* Analog Input subdevice */
1247 s
= &dev
->subdevices
[0];
1248 s
->type
= COMEDI_SUBD_AI
;
1249 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
;
1250 if (board
->can_do_diff_ai
)
1251 s
->subdev_flags
|= SDF_DIFF
;
1252 s
->n_chan
= board
->ai_nchan
;
1253 s
->maxdata
= 0xffff;
1254 s
->len_chanlist
= ME4000_AI_CHANNEL_LIST_COUNT
;
1255 s
->range_table
= &me4000_ai_range
;
1256 s
->insn_read
= me4000_ai_insn_read
;
1259 dev
->read_subdev
= s
;
1260 s
->subdev_flags
|= SDF_CMD_READ
;
1261 s
->cancel
= me4000_ai_cancel
;
1262 s
->do_cmdtest
= me4000_ai_do_cmd_test
;
1263 s
->do_cmd
= me4000_ai_do_cmd
;
1266 /*=========================================================================
1267 Analog output subdevice
1268 ========================================================================*/
1270 s
= &dev
->subdevices
[1];
1272 if (board
->has_ao
) {
1273 s
->type
= COMEDI_SUBD_AO
;
1274 s
->subdev_flags
= SDF_WRITABLE
| SDF_COMMON
| SDF_GROUND
;
1276 s
->maxdata
= 0xFFFF; /* 16 bit DAC */
1277 s
->range_table
= &range_bipolar10
;
1278 s
->insn_write
= me4000_ao_insn_write
;
1280 result
= comedi_alloc_subdev_readback(s
);
1284 s
->type
= COMEDI_SUBD_UNUSED
;
1287 /* Digital I/O subdevice */
1288 s
= &dev
->subdevices
[2];
1289 s
->type
= COMEDI_SUBD_DIO
;
1290 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1293 s
->range_table
= &range_digital
;
1294 s
->insn_bits
= me4000_dio_insn_bits
;
1295 s
->insn_config
= me4000_dio_insn_config
;
1298 * Check for optoisolated ME-4000 version. If one the first
1299 * port is a fixed output port and the second is a fixed input port.
1301 if (!inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1303 outl(ME4000_DIO_CTRL_MODE_0
,
1304 dev
->iobase
+ ME4000_DIO_DIR_REG
);
1307 /* Counter subdevice (8254) */
1308 s
= &dev
->subdevices
[3];
1309 if (board
->has_counter
) {
1310 unsigned long timer_base
= pci_resource_start(pcidev
, 3);
1315 dev
->pacer
= comedi_8254_init(timer_base
, 0, I8254_IO8
, 0);
1319 comedi_8254_subdevice_init(s
, dev
->pacer
);
1321 s
->type
= COMEDI_SUBD_UNUSED
;
1327 static void me4000_detach(struct comedi_device
*dev
)
1331 comedi_pci_detach(dev
);
1334 static struct comedi_driver me4000_driver
= {
1335 .driver_name
= "me4000",
1336 .module
= THIS_MODULE
,
1337 .auto_attach
= me4000_auto_attach
,
1338 .detach
= me4000_detach
,
1341 static int me4000_pci_probe(struct pci_dev
*dev
,
1342 const struct pci_device_id
*id
)
1344 return comedi_pci_auto_config(dev
, &me4000_driver
, id
->driver_data
);
1347 static const struct pci_device_id me4000_pci_table
[] = {
1348 { PCI_VDEVICE(MEILHAUS
, 0x4650), BOARD_ME4650
},
1349 { PCI_VDEVICE(MEILHAUS
, 0x4660), BOARD_ME4660
},
1350 { PCI_VDEVICE(MEILHAUS
, 0x4661), BOARD_ME4660I
},
1351 { PCI_VDEVICE(MEILHAUS
, 0x4662), BOARD_ME4660S
},
1352 { PCI_VDEVICE(MEILHAUS
, 0x4663), BOARD_ME4660IS
},
1353 { PCI_VDEVICE(MEILHAUS
, 0x4670), BOARD_ME4670
},
1354 { PCI_VDEVICE(MEILHAUS
, 0x4671), BOARD_ME4670I
},
1355 { PCI_VDEVICE(MEILHAUS
, 0x4672), BOARD_ME4670S
},
1356 { PCI_VDEVICE(MEILHAUS
, 0x4673), BOARD_ME4670IS
},
1357 { PCI_VDEVICE(MEILHAUS
, 0x4680), BOARD_ME4680
},
1358 { PCI_VDEVICE(MEILHAUS
, 0x4681), BOARD_ME4680I
},
1359 { PCI_VDEVICE(MEILHAUS
, 0x4682), BOARD_ME4680S
},
1360 { PCI_VDEVICE(MEILHAUS
, 0x4683), BOARD_ME4680IS
},
1363 MODULE_DEVICE_TABLE(pci
, me4000_pci_table
);
1365 static struct pci_driver me4000_pci_driver
= {
1367 .id_table
= me4000_pci_table
,
1368 .probe
= me4000_pci_probe
,
1369 .remove
= comedi_pci_auto_unconfig
,
1371 module_comedi_pci_driver(me4000_driver
, me4000_pci_driver
);
1373 MODULE_AUTHOR("Comedi http://www.comedi.org");
1374 MODULE_DESCRIPTION("Comedi low-level driver");
1375 MODULE_LICENSE("GPL");
1376 MODULE_FIRMWARE(ME4000_FIRMWARE
);