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_BIT_MODE_0 (1 << 0)
61 #define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1)
62 #define ME4000_AO_CTRL_MASK_MODE (3 << 0)
63 #define ME4000_AO_CTRL_BIT_STOP (1 << 2)
64 #define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3)
65 #define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4)
66 #define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5)
67 #define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7)
68 #define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8)
69 #define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9)
70 #define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10)
71 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
72 #define ME4000_AO_STATUS_BIT_FSM (1 << 0)
73 #define ME4000_AO_STATUS_BIT_FF (1 << 1)
74 #define ME4000_AO_STATUS_BIT_HF (1 << 2)
75 #define ME4000_AO_STATUS_BIT_EF (1 << 3)
76 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
77 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
78 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
79 #define ME4000_AI_CTRL_REG 0x74
80 #define ME4000_AI_STATUS_REG 0x74
81 #define ME4000_AI_CTRL_MODE_0 BIT(0)
82 #define ME4000_AI_CTRL_MODE_1 BIT(1)
83 #define ME4000_AI_CTRL_MODE_2 BIT(2)
84 #define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3)
85 #define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4)
86 #define ME4000_AI_CTRL_STOP BIT(5)
87 #define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6)
88 #define ME4000_AI_CTRL_DATA_FIFO BIT(7)
89 #define ME4000_AI_CTRL_FULLSCALE BIT(8)
90 #define ME4000_AI_CTRL_OFFSET BIT(9)
91 #define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10)
92 #define ME4000_AI_CTRL_EX_TRIG BIT(11)
93 #define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12)
94 #define ME4000_AI_CTRL_EX_IRQ BIT(13)
95 #define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14)
96 #define ME4000_AI_CTRL_LE_IRQ BIT(15)
97 #define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16)
98 #define ME4000_AI_CTRL_HF_IRQ BIT(17)
99 #define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18)
100 #define ME4000_AI_CTRL_SC_IRQ BIT(19)
101 #define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20)
102 #define ME4000_AI_CTRL_SC_RELOAD BIT(21)
103 #define ME4000_AI_STATUS_EF_CHANNEL BIT(22)
104 #define ME4000_AI_STATUS_HF_CHANNEL BIT(23)
105 #define ME4000_AI_STATUS_FF_CHANNEL BIT(24)
106 #define ME4000_AI_STATUS_EF_DATA BIT(25)
107 #define ME4000_AI_STATUS_HF_DATA BIT(26)
108 #define ME4000_AI_STATUS_FF_DATA BIT(27)
109 #define ME4000_AI_STATUS_LE BIT(28)
110 #define ME4000_AI_STATUS_FSM BIT(29)
111 #define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31)
112 #define ME4000_AI_CHANNEL_LIST_REG 0x78
113 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5)
114 #define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6)
115 #define ME4000_AI_LIST_LAST_ENTRY BIT(8)
116 #define ME4000_AI_DATA_REG 0x7c
117 #define ME4000_AI_CHAN_TIMER_REG 0x80
118 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
119 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
120 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
121 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
122 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
123 #define ME4000_AI_START_REG 0x98
124 #define ME4000_IRQ_STATUS_REG 0x9c
125 #define ME4000_IRQ_STATUS_EX BIT(0)
126 #define ME4000_IRQ_STATUS_LE BIT(1)
127 #define ME4000_IRQ_STATUS_AI_HF BIT(2)
128 #define ME4000_IRQ_STATUS_AO_0_HF BIT(3)
129 #define ME4000_IRQ_STATUS_AO_1_HF BIT(4)
130 #define ME4000_IRQ_STATUS_AO_2_HF BIT(5)
131 #define ME4000_IRQ_STATUS_AO_3_HF BIT(6)
132 #define ME4000_IRQ_STATUS_SC BIT(7)
133 #define ME4000_DIO_PORT_0_REG 0xa0
134 #define ME4000_DIO_PORT_1_REG 0xa4
135 #define ME4000_DIO_PORT_2_REG 0xa8
136 #define ME4000_DIO_PORT_3_REG 0xac
137 #define ME4000_DIO_DIR_REG 0xb0
138 #define ME4000_AO_LOADSETREG_XX 0xb4
139 #define ME4000_DIO_CTRL_REG 0xb8
140 #define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0)
141 #define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1)
142 #define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2)
143 #define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3)
144 #define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4)
145 #define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5)
146 #define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6)
147 #define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7)
148 #define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8)
149 #define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9)
150 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10)
151 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11)
152 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12)
153 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13)
154 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
155 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
156 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
158 #define ME4000_AI_FIFO_COUNT 2048
160 #define ME4000_AI_MIN_TICKS 66
161 #define ME4000_AI_MIN_SAMPLE_TIME 2000
163 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
165 struct me4000_private
{
166 unsigned long plx_regbase
;
169 enum me4000_boardid
{
185 struct me4000_board
{
188 unsigned int can_do_diff_ai
:1;
189 unsigned int can_do_sh_ai
:1; /* sample & hold (8 channels) */
190 unsigned int ex_trig_analog
:1;
191 unsigned int has_ao
:1;
192 unsigned int has_ao_fifo
:1;
193 unsigned int has_counter
:1;
196 static const struct me4000_board me4000_boards
[] = {
302 * NOTE: the ranges here are inverted compared to the values
303 * written to the ME4000_AI_CHANNEL_LIST_REG,
305 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
307 static const struct comedi_lrange me4000_ai_range
= {
316 static int me4000_xilinx_download(struct comedi_device
*dev
,
317 const u8
*data
, size_t size
,
318 unsigned long context
)
320 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
321 struct me4000_private
*devpriv
= dev
->private;
322 unsigned long xilinx_iobase
= pci_resource_start(pcidev
, 5);
323 unsigned int file_length
;
331 * Set PLX local interrupt 2 polarity to high.
332 * Interrupt is thrown by init pin of xilinx.
334 outl(PLX9052_INTCSR_LI2POL
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
336 /* Set /CS and /WRITE of the Xilinx */
337 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
338 val
|= PLX9052_CNTRL_UIO2_DATA
;
339 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
341 /* Init Xilinx with CS1 */
342 inb(xilinx_iobase
+ 0xC8);
344 /* Wait until /INIT pin is set */
346 val
= inl(devpriv
->plx_regbase
+ PLX9052_INTCSR
);
347 if (!(val
& PLX9052_INTCSR_LI2STAT
)) {
348 dev_err(dev
->class_dev
, "Can't init Xilinx\n");
352 /* Reset /CS and /WRITE of the Xilinx */
353 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
354 val
&= ~PLX9052_CNTRL_UIO2_DATA
;
355 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
357 /* Download Xilinx firmware */
358 file_length
= (((unsigned int)data
[0] & 0xff) << 24) +
359 (((unsigned int)data
[1] & 0xff) << 16) +
360 (((unsigned int)data
[2] & 0xff) << 8) +
361 ((unsigned int)data
[3] & 0xff);
364 for (i
= 0; i
< file_length
; i
++) {
365 outb(data
[16 + i
], xilinx_iobase
);
368 /* Check if BUSY flag is low */
369 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
370 if (val
& PLX9052_CNTRL_UIO1_DATA
) {
371 dev_err(dev
->class_dev
,
372 "Xilinx is still busy (i = %d)\n", i
);
377 /* If done flag is high download was successful */
378 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
379 if (!(val
& PLX9052_CNTRL_UIO0_DATA
)) {
380 dev_err(dev
->class_dev
, "DONE flag is not set\n");
381 dev_err(dev
->class_dev
, "Download not successful\n");
385 /* Set /CS and /WRITE */
386 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
387 val
|= PLX9052_CNTRL_UIO2_DATA
;
388 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
393 static void me4000_reset(struct comedi_device
*dev
)
395 struct me4000_private
*devpriv
= dev
->private;
399 /* Make a hardware reset */
400 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
401 val
|= PLX9052_CNTRL_PCI_RESET
;
402 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
403 val
&= ~PLX9052_CNTRL_PCI_RESET
;
404 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
406 /* 0x8000 to the DACs means an output voltage of 0V */
407 for (chan
= 0; chan
< 4; chan
++)
408 outl(0x8000, dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
410 /* Set both stop bits in the analog input control register */
411 outl(ME4000_AI_CTRL_IMMEDIATE_STOP
| ME4000_AI_CTRL_STOP
,
412 dev
->iobase
+ ME4000_AI_CTRL_REG
);
414 /* Set both stop bits in the analog output control register */
415 val
= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AO_CTRL_BIT_STOP
;
416 for (chan
= 0; chan
< 4; chan
++)
417 outl(val
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
419 /* Enable interrupts on the PLX */
420 outl(PLX9052_INTCSR_LI1ENAB
|
421 PLX9052_INTCSR_LI1POL
|
422 PLX9052_INTCSR_PCIENAB
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
424 /* Set the adustment register for AO demux */
425 outl(ME4000_AO_DEMUX_ADJUST_VALUE
,
426 dev
->iobase
+ ME4000_AO_DEMUX_ADJUST_REG
);
429 * Set digital I/O direction for port 0
430 * to output on isolated versions
432 if (!(inl(dev
->iobase
+ ME4000_DIO_DIR_REG
) & 0x1))
433 outl(0x1, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
436 static int me4000_ai_eoc(struct comedi_device
*dev
,
437 struct comedi_subdevice
*s
,
438 struct comedi_insn
*insn
,
439 unsigned long context
)
443 status
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
444 if (status
& ME4000_AI_STATUS_EF_DATA
)
449 static int me4000_ai_insn_read(struct comedi_device
*dev
,
450 struct comedi_subdevice
*s
,
451 struct comedi_insn
*insn
,
454 unsigned int chan
= CR_CHAN(insn
->chanspec
);
455 unsigned int range
= CR_RANGE(insn
->chanspec
);
456 unsigned int aref
= CR_AREF(insn
->chanspec
);
462 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
463 if (aref
== AREF_DIFF
) {
464 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
465 dev_err(dev
->class_dev
,
466 "Differential inputs are not available\n");
470 if (!comedi_range_is_bipolar(s
, range
)) {
471 dev_err(dev
->class_dev
,
472 "Range must be bipolar when aref = diff\n");
476 if (chan
>= (s
->n_chan
/ 2)) {
477 dev_err(dev
->class_dev
,
478 "Analog input is not available\n");
481 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
484 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
486 /* Clear channel list, data fifo and both stop bits */
487 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
488 tmp
&= ~(ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
|
489 ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
);
490 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
492 /* Set the acquisition mode to single */
493 tmp
&= ~(ME4000_AI_CTRL_MODE_0
| ME4000_AI_CTRL_MODE_1
|
494 ME4000_AI_CTRL_MODE_2
);
495 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
497 /* Enable channel list and data fifo */
498 tmp
|= ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
;
499 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
501 /* Generate channel list entry */
502 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
504 /* Set the timer to maximum sample rate */
505 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
506 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
508 for (i
= 0; i
< insn
->n
; i
++) {
511 /* start conversion by dummy read */
512 inl(dev
->iobase
+ ME4000_AI_START_REG
);
514 ret
= comedi_timeout(dev
, s
, insn
, me4000_ai_eoc
, 0);
518 /* read two's complement value and munge to offset binary */
519 val
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
);
520 data
[i
] = comedi_offset_munge(s
, val
);
526 static int me4000_ai_cancel(struct comedi_device
*dev
,
527 struct comedi_subdevice
*s
)
531 /* Stop any running conversion */
532 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
533 tmp
&= ~(ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
);
534 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
536 /* Clear the control register */
537 outl(0x0, dev
->iobase
+ ME4000_AI_CTRL_REG
);
542 static int me4000_ai_check_chanlist(struct comedi_device
*dev
,
543 struct comedi_subdevice
*s
,
544 struct comedi_cmd
*cmd
)
546 unsigned int aref0
= CR_AREF(cmd
->chanlist
[0]);
549 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
550 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
551 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
552 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
555 dev_dbg(dev
->class_dev
,
556 "Mode is not equal for all entries\n");
560 if (aref
== AREF_DIFF
) {
561 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
562 dev_err(dev
->class_dev
,
563 "Differential inputs are not available\n");
567 if (chan
>= (s
->n_chan
/ 2)) {
568 dev_dbg(dev
->class_dev
,
569 "Channel number to high\n");
573 if (!comedi_range_is_bipolar(s
, range
)) {
574 dev_dbg(dev
->class_dev
,
575 "Bipolar is not selected in differential mode\n");
584 static int ai_round_cmd_args(struct comedi_device
*dev
,
585 struct comedi_subdevice
*s
,
586 struct comedi_cmd
*cmd
,
587 unsigned int *init_ticks
,
588 unsigned int *scan_ticks
, unsigned int *chan_ticks
)
596 if (cmd
->start_arg
) {
597 *init_ticks
= (cmd
->start_arg
* 33) / 1000;
598 rest
= (cmd
->start_arg
* 33) % 1000;
600 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
603 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
609 if (cmd
->scan_begin_arg
) {
610 *scan_ticks
= (cmd
->scan_begin_arg
* 33) / 1000;
611 rest
= (cmd
->scan_begin_arg
* 33) % 1000;
613 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
616 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
622 if (cmd
->convert_arg
) {
623 *chan_ticks
= (cmd
->convert_arg
* 33) / 1000;
624 rest
= (cmd
->convert_arg
* 33) % 1000;
626 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
629 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
638 static void ai_write_timer(struct comedi_device
*dev
,
639 unsigned int init_ticks
,
640 unsigned int scan_ticks
, unsigned int chan_ticks
)
642 outl(init_ticks
- 1, dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_LOW_REG
);
643 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_HIGH_REG
);
646 outl(scan_ticks
- 1, dev
->iobase
+ ME4000_AI_SCAN_TIMER_LOW_REG
);
647 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_TIMER_HIGH_REG
);
650 outl(chan_ticks
- 1, dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
651 outl(chan_ticks
- 1, dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
654 static int me4000_ai_write_chanlist(struct comedi_device
*dev
,
655 struct comedi_subdevice
*s
,
656 struct comedi_cmd
*cmd
)
660 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
661 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
662 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
663 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
666 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
668 if (aref
== AREF_DIFF
)
669 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
671 if (i
== (cmd
->chanlist_len
- 1))
672 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
674 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
680 static int ai_prepare(struct comedi_device
*dev
,
681 struct comedi_subdevice
*s
,
682 struct comedi_cmd
*cmd
,
683 unsigned int init_ticks
,
684 unsigned int scan_ticks
, unsigned int chan_ticks
)
686 unsigned int tmp
= 0;
688 /* Write timer arguments */
689 ai_write_timer(dev
, init_ticks
, scan_ticks
, chan_ticks
);
691 /* Reset control register */
692 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
695 if ((cmd
->start_src
== TRIG_EXT
&&
696 cmd
->scan_begin_src
== TRIG_TIMER
&&
697 cmd
->convert_src
== TRIG_TIMER
) ||
698 (cmd
->start_src
== TRIG_EXT
&&
699 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
700 cmd
->convert_src
== TRIG_TIMER
)) {
701 tmp
= ME4000_AI_CTRL_MODE_1
|
702 ME4000_AI_CTRL_CHANNEL_FIFO
|
703 ME4000_AI_CTRL_DATA_FIFO
;
704 } else if (cmd
->start_src
== TRIG_EXT
&&
705 cmd
->scan_begin_src
== TRIG_EXT
&&
706 cmd
->convert_src
== TRIG_TIMER
) {
707 tmp
= ME4000_AI_CTRL_MODE_2
|
708 ME4000_AI_CTRL_CHANNEL_FIFO
|
709 ME4000_AI_CTRL_DATA_FIFO
;
710 } else if (cmd
->start_src
== TRIG_EXT
&&
711 cmd
->scan_begin_src
== TRIG_EXT
&&
712 cmd
->convert_src
== TRIG_EXT
) {
713 tmp
= ME4000_AI_CTRL_MODE_0
|
714 ME4000_AI_CTRL_MODE_1
|
715 ME4000_AI_CTRL_CHANNEL_FIFO
|
716 ME4000_AI_CTRL_DATA_FIFO
;
718 tmp
= ME4000_AI_CTRL_MODE_0
|
719 ME4000_AI_CTRL_CHANNEL_FIFO
|
720 ME4000_AI_CTRL_DATA_FIFO
;
724 if (cmd
->stop_src
== TRIG_COUNT
) {
725 outl(cmd
->chanlist_len
* cmd
->stop_arg
,
726 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
727 tmp
|= ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
;
728 } else if (cmd
->stop_src
== TRIG_NONE
&&
729 cmd
->scan_end_src
== TRIG_COUNT
) {
730 outl(cmd
->scan_end_arg
,
731 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
732 tmp
|= ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
;
734 tmp
|= ME4000_AI_CTRL_HF_IRQ
;
737 /* Write the setup to the control register */
738 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
740 /* Write the channel list */
741 me4000_ai_write_chanlist(dev
, s
, cmd
);
746 static int me4000_ai_do_cmd(struct comedi_device
*dev
,
747 struct comedi_subdevice
*s
)
750 unsigned int init_ticks
= 0;
751 unsigned int scan_ticks
= 0;
752 unsigned int chan_ticks
= 0;
753 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
755 /* Reset the analog input */
756 err
= me4000_ai_cancel(dev
, s
);
760 /* Round the timer arguments */
761 err
= ai_round_cmd_args(dev
,
762 s
, cmd
, &init_ticks
, &scan_ticks
, &chan_ticks
);
766 /* Prepare the AI for acquisition */
767 err
= ai_prepare(dev
, s
, cmd
, init_ticks
, scan_ticks
, chan_ticks
);
771 /* Start acquistion by dummy read */
772 inl(dev
->iobase
+ ME4000_AI_START_REG
);
777 static int me4000_ai_do_cmd_test(struct comedi_device
*dev
,
778 struct comedi_subdevice
*s
,
779 struct comedi_cmd
*cmd
)
781 unsigned int init_ticks
;
782 unsigned int chan_ticks
;
783 unsigned int scan_ticks
;
786 /* Round the timer arguments */
787 ai_round_cmd_args(dev
, s
, cmd
, &init_ticks
, &scan_ticks
, &chan_ticks
);
789 /* Step 1 : check if triggers are trivially valid */
791 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
792 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
793 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
794 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
795 TRIG_TIMER
| TRIG_EXT
);
796 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
,
797 TRIG_NONE
| TRIG_COUNT
);
798 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_NONE
| TRIG_COUNT
);
803 /* Step 2a : make sure trigger sources are unique */
805 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
806 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
807 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
808 err
|= comedi_check_trigger_is_unique(cmd
->scan_end_src
);
809 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
811 /* Step 2b : and mutually compatible */
813 if (cmd
->start_src
== TRIG_NOW
&&
814 cmd
->scan_begin_src
== TRIG_TIMER
&&
815 cmd
->convert_src
== TRIG_TIMER
) {
816 } else if (cmd
->start_src
== TRIG_NOW
&&
817 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
818 cmd
->convert_src
== TRIG_TIMER
) {
819 } else if (cmd
->start_src
== TRIG_EXT
&&
820 cmd
->scan_begin_src
== TRIG_TIMER
&&
821 cmd
->convert_src
== TRIG_TIMER
) {
822 } else if (cmd
->start_src
== TRIG_EXT
&&
823 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
824 cmd
->convert_src
== TRIG_TIMER
) {
825 } else if (cmd
->start_src
== TRIG_EXT
&&
826 cmd
->scan_begin_src
== TRIG_EXT
&&
827 cmd
->convert_src
== TRIG_TIMER
) {
828 } else if (cmd
->start_src
== TRIG_EXT
&&
829 cmd
->scan_begin_src
== TRIG_EXT
&&
830 cmd
->convert_src
== TRIG_EXT
) {
838 /* Step 3: check if arguments are trivially valid */
840 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
842 if (cmd
->chanlist_len
< 1) {
843 cmd
->chanlist_len
= 1;
846 if (init_ticks
< 66) {
847 cmd
->start_arg
= 2000;
850 if (scan_ticks
&& scan_ticks
< 67) {
851 cmd
->scan_begin_arg
= 2031;
854 if (chan_ticks
< 66) {
855 cmd
->convert_arg
= 2000;
859 if (cmd
->stop_src
== TRIG_COUNT
)
860 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
862 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
868 * Stage 4. Check for argument conflicts.
870 if (cmd
->start_src
== TRIG_NOW
&&
871 cmd
->scan_begin_src
== TRIG_TIMER
&&
872 cmd
->convert_src
== TRIG_TIMER
) {
873 /* Check timer arguments */
874 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
875 dev_err(dev
->class_dev
, "Invalid start arg\n");
876 cmd
->start_arg
= 2000; /* 66 ticks at least */
879 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
880 dev_err(dev
->class_dev
, "Invalid convert arg\n");
881 cmd
->convert_arg
= 2000; /* 66 ticks at least */
884 if (scan_ticks
<= cmd
->chanlist_len
* chan_ticks
) {
885 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
887 /* At least one tick more */
888 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
891 } else if (cmd
->start_src
== TRIG_NOW
&&
892 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
893 cmd
->convert_src
== TRIG_TIMER
) {
894 /* Check timer arguments */
895 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
896 dev_err(dev
->class_dev
, "Invalid start arg\n");
897 cmd
->start_arg
= 2000; /* 66 ticks at least */
900 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
901 dev_err(dev
->class_dev
, "Invalid convert arg\n");
902 cmd
->convert_arg
= 2000; /* 66 ticks at least */
905 } else if (cmd
->start_src
== TRIG_EXT
&&
906 cmd
->scan_begin_src
== TRIG_TIMER
&&
907 cmd
->convert_src
== TRIG_TIMER
) {
908 /* Check timer arguments */
909 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
910 dev_err(dev
->class_dev
, "Invalid start arg\n");
911 cmd
->start_arg
= 2000; /* 66 ticks at least */
914 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
915 dev_err(dev
->class_dev
, "Invalid convert arg\n");
916 cmd
->convert_arg
= 2000; /* 66 ticks at least */
919 if (scan_ticks
<= cmd
->chanlist_len
* chan_ticks
) {
920 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
922 /* At least one tick more */
923 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
926 } else if (cmd
->start_src
== TRIG_EXT
&&
927 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
928 cmd
->convert_src
== TRIG_TIMER
) {
929 /* Check timer arguments */
930 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
931 dev_err(dev
->class_dev
, "Invalid start arg\n");
932 cmd
->start_arg
= 2000; /* 66 ticks at least */
935 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
936 dev_err(dev
->class_dev
, "Invalid convert arg\n");
937 cmd
->convert_arg
= 2000; /* 66 ticks at least */
940 } else if (cmd
->start_src
== TRIG_EXT
&&
941 cmd
->scan_begin_src
== TRIG_EXT
&&
942 cmd
->convert_src
== TRIG_TIMER
) {
943 /* Check timer arguments */
944 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
945 dev_err(dev
->class_dev
, "Invalid start arg\n");
946 cmd
->start_arg
= 2000; /* 66 ticks at least */
949 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
950 dev_err(dev
->class_dev
, "Invalid convert arg\n");
951 cmd
->convert_arg
= 2000; /* 66 ticks at least */
954 } else if (cmd
->start_src
== TRIG_EXT
&&
955 cmd
->scan_begin_src
== TRIG_EXT
&&
956 cmd
->convert_src
== TRIG_EXT
) {
957 /* Check timer arguments */
958 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
959 dev_err(dev
->class_dev
, "Invalid start arg\n");
960 cmd
->start_arg
= 2000; /* 66 ticks at least */
964 if (cmd
->scan_end_src
== TRIG_COUNT
) {
965 if (cmd
->scan_end_arg
== 0) {
966 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
967 cmd
->scan_end_arg
= 1;
975 /* Step 5: check channel list if it exists */
976 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
977 err
|= me4000_ai_check_chanlist(dev
, s
, cmd
);
985 static irqreturn_t
me4000_ai_isr(int irq
, void *dev_id
)
988 struct comedi_device
*dev
= dev_id
;
989 struct comedi_subdevice
*s
= dev
->read_subdev
;
997 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
998 ME4000_IRQ_STATUS_AI_HF
) {
999 /* Read status register to find out what happened */
1000 tmp
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
1002 if (!(tmp
& ME4000_AI_STATUS_FF_DATA
) &&
1003 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
1004 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
1005 c
= ME4000_AI_FIFO_COUNT
;
1008 * FIFO overflow, so stop conversion
1009 * and disable all interrupts
1011 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1012 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1013 ME4000_AI_CTRL_SC_IRQ
);
1014 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1016 s
->async
->events
|= COMEDI_CB_ERROR
;
1018 dev_err(dev
->class_dev
, "FIFO overflow\n");
1019 } else if ((tmp
& ME4000_AI_STATUS_FF_DATA
) &&
1020 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
1021 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
1022 c
= ME4000_AI_FIFO_COUNT
/ 2;
1024 dev_err(dev
->class_dev
,
1025 "Can't determine state of fifo\n");
1029 * Undefined state, so stop conversion
1030 * and disable all interrupts
1032 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1033 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1034 ME4000_AI_CTRL_SC_IRQ
);
1035 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1037 s
->async
->events
|= COMEDI_CB_ERROR
;
1039 dev_err(dev
->class_dev
, "Undefined FIFO state\n");
1042 for (i
= 0; i
< c
; i
++) {
1043 /* Read value from data fifo */
1044 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
1047 if (!comedi_buf_write_samples(s
, &lval
, 1)) {
1049 * Buffer overflow, so stop conversion
1050 * and disable all interrupts
1052 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1053 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1054 ME4000_AI_CTRL_SC_IRQ
);
1055 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1060 /* Work is done, so reset the interrupt */
1061 tmp
|= ME4000_AI_CTRL_HF_IRQ_RESET
;
1062 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1063 tmp
&= ~ME4000_AI_CTRL_HF_IRQ_RESET
;
1064 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1067 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
1068 ME4000_IRQ_STATUS_SC
) {
1069 s
->async
->events
|= COMEDI_CB_EOA
;
1072 * Acquisition is complete, so stop
1073 * conversion and disable all interrupts
1075 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
1076 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1077 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
);
1078 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1080 /* Poll data until fifo empty */
1081 while (inl(dev
->iobase
+ ME4000_AI_STATUS_REG
) &
1082 ME4000_AI_STATUS_EF_DATA
) {
1083 /* Read value from data fifo */
1084 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
1087 if (!comedi_buf_write_samples(s
, &lval
, 1))
1091 /* Work is done, so reset the interrupt */
1092 tmp
|= ME4000_AI_CTRL_SC_IRQ_RESET
;
1093 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1094 tmp
&= ~ME4000_AI_CTRL_SC_IRQ_RESET
;
1095 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1098 comedi_handle_events(dev
, s
);
1103 static int me4000_ao_insn_write(struct comedi_device
*dev
,
1104 struct comedi_subdevice
*s
,
1105 struct comedi_insn
*insn
,
1108 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1111 /* Stop any running conversion */
1112 tmp
= inl(dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1113 tmp
|= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
;
1114 outl(tmp
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1116 /* Clear control register and set to single mode */
1117 outl(0x0, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1119 /* Write data value */
1120 outl(data
[0], dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
1122 /* Store in the mirror */
1123 s
->readback
[chan
] = data
[0];
1128 static int me4000_dio_insn_bits(struct comedi_device
*dev
,
1129 struct comedi_subdevice
*s
,
1130 struct comedi_insn
*insn
,
1133 if (comedi_dio_update_state(s
, data
)) {
1134 outl((s
->state
>> 0) & 0xFF,
1135 dev
->iobase
+ ME4000_DIO_PORT_0_REG
);
1136 outl((s
->state
>> 8) & 0xFF,
1137 dev
->iobase
+ ME4000_DIO_PORT_1_REG
);
1138 outl((s
->state
>> 16) & 0xFF,
1139 dev
->iobase
+ ME4000_DIO_PORT_2_REG
);
1140 outl((s
->state
>> 24) & 0xFF,
1141 dev
->iobase
+ ME4000_DIO_PORT_3_REG
);
1144 data
[1] = ((inl(dev
->iobase
+ ME4000_DIO_PORT_0_REG
) & 0xFF) << 0) |
1145 ((inl(dev
->iobase
+ ME4000_DIO_PORT_1_REG
) & 0xFF) << 8) |
1146 ((inl(dev
->iobase
+ ME4000_DIO_PORT_2_REG
) & 0xFF) << 16) |
1147 ((inl(dev
->iobase
+ ME4000_DIO_PORT_3_REG
) & 0xFF) << 24);
1152 static int me4000_dio_insn_config(struct comedi_device
*dev
,
1153 struct comedi_subdevice
*s
,
1154 struct comedi_insn
*insn
,
1157 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1171 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, mask
);
1175 tmp
= inl(dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1176 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_0
| ME4000_DIO_CTRL_BIT_MODE_1
|
1177 ME4000_DIO_CTRL_BIT_MODE_2
| ME4000_DIO_CTRL_BIT_MODE_3
|
1178 ME4000_DIO_CTRL_BIT_MODE_4
| ME4000_DIO_CTRL_BIT_MODE_5
|
1179 ME4000_DIO_CTRL_BIT_MODE_6
| ME4000_DIO_CTRL_BIT_MODE_7
);
1180 if (s
->io_bits
& 0x000000ff)
1181 tmp
|= ME4000_DIO_CTRL_BIT_MODE_0
;
1182 if (s
->io_bits
& 0x0000ff00)
1183 tmp
|= ME4000_DIO_CTRL_BIT_MODE_2
;
1184 if (s
->io_bits
& 0x00ff0000)
1185 tmp
|= ME4000_DIO_CTRL_BIT_MODE_4
;
1186 if (s
->io_bits
& 0xff000000)
1187 tmp
|= ME4000_DIO_CTRL_BIT_MODE_6
;
1190 * Check for optoisolated ME-4000 version.
1191 * If one the first port is a fixed output
1192 * port and the second is a fixed input port.
1194 if (inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1195 s
->io_bits
|= 0x000000ff;
1196 s
->io_bits
&= ~0x0000ff00;
1197 tmp
|= ME4000_DIO_CTRL_BIT_MODE_0
;
1198 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_2
|
1199 ME4000_DIO_CTRL_BIT_MODE_3
);
1202 outl(tmp
, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1207 static int me4000_auto_attach(struct comedi_device
*dev
,
1208 unsigned long context
)
1210 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1211 const struct me4000_board
*board
= NULL
;
1212 struct me4000_private
*devpriv
;
1213 struct comedi_subdevice
*s
;
1216 if (context
< ARRAY_SIZE(me4000_boards
))
1217 board
= &me4000_boards
[context
];
1220 dev
->board_ptr
= board
;
1221 dev
->board_name
= board
->name
;
1223 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1227 result
= comedi_pci_enable(dev
);
1231 devpriv
->plx_regbase
= pci_resource_start(pcidev
, 1);
1232 dev
->iobase
= pci_resource_start(pcidev
, 2);
1233 if (!devpriv
->plx_regbase
|| !dev
->iobase
)
1236 result
= comedi_load_firmware(dev
, &pcidev
->dev
, ME4000_FIRMWARE
,
1237 me4000_xilinx_download
, 0);
1243 if (pcidev
->irq
> 0) {
1244 result
= request_irq(pcidev
->irq
, me4000_ai_isr
, IRQF_SHARED
,
1245 dev
->board_name
, dev
);
1247 dev
->irq
= pcidev
->irq
;
1250 result
= comedi_alloc_subdevices(dev
, 4);
1254 /* Analog Input subdevice */
1255 s
= &dev
->subdevices
[0];
1256 s
->type
= COMEDI_SUBD_AI
;
1257 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
;
1258 if (board
->can_do_diff_ai
)
1259 s
->subdev_flags
|= SDF_DIFF
;
1260 s
->n_chan
= board
->ai_nchan
;
1261 s
->maxdata
= 0xffff;
1262 s
->len_chanlist
= ME4000_AI_CHANNEL_LIST_COUNT
;
1263 s
->range_table
= &me4000_ai_range
;
1264 s
->insn_read
= me4000_ai_insn_read
;
1267 dev
->read_subdev
= s
;
1268 s
->subdev_flags
|= SDF_CMD_READ
;
1269 s
->cancel
= me4000_ai_cancel
;
1270 s
->do_cmdtest
= me4000_ai_do_cmd_test
;
1271 s
->do_cmd
= me4000_ai_do_cmd
;
1274 /*=========================================================================
1275 Analog output subdevice
1276 ========================================================================*/
1278 s
= &dev
->subdevices
[1];
1280 if (board
->has_ao
) {
1281 s
->type
= COMEDI_SUBD_AO
;
1282 s
->subdev_flags
= SDF_WRITABLE
| SDF_COMMON
| SDF_GROUND
;
1284 s
->maxdata
= 0xFFFF; /* 16 bit DAC */
1285 s
->range_table
= &range_bipolar10
;
1286 s
->insn_write
= me4000_ao_insn_write
;
1288 result
= comedi_alloc_subdev_readback(s
);
1292 s
->type
= COMEDI_SUBD_UNUSED
;
1295 /* Digital I/O subdevice */
1296 s
= &dev
->subdevices
[2];
1297 s
->type
= COMEDI_SUBD_DIO
;
1298 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1301 s
->range_table
= &range_digital
;
1302 s
->insn_bits
= me4000_dio_insn_bits
;
1303 s
->insn_config
= me4000_dio_insn_config
;
1306 * Check for optoisolated ME-4000 version. If one the first
1307 * port is a fixed output port and the second is a fixed input port.
1309 if (!inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1311 outl(ME4000_DIO_CTRL_BIT_MODE_0
,
1312 dev
->iobase
+ ME4000_DIO_DIR_REG
);
1315 /* Counter subdevice (8254) */
1316 s
= &dev
->subdevices
[3];
1317 if (board
->has_counter
) {
1318 unsigned long timer_base
= pci_resource_start(pcidev
, 3);
1323 dev
->pacer
= comedi_8254_init(timer_base
, 0, I8254_IO8
, 0);
1327 comedi_8254_subdevice_init(s
, dev
->pacer
);
1329 s
->type
= COMEDI_SUBD_UNUSED
;
1335 static void me4000_detach(struct comedi_device
*dev
)
1339 comedi_pci_detach(dev
);
1342 static struct comedi_driver me4000_driver
= {
1343 .driver_name
= "me4000",
1344 .module
= THIS_MODULE
,
1345 .auto_attach
= me4000_auto_attach
,
1346 .detach
= me4000_detach
,
1349 static int me4000_pci_probe(struct pci_dev
*dev
,
1350 const struct pci_device_id
*id
)
1352 return comedi_pci_auto_config(dev
, &me4000_driver
, id
->driver_data
);
1355 static const struct pci_device_id me4000_pci_table
[] = {
1356 { PCI_VDEVICE(MEILHAUS
, 0x4650), BOARD_ME4650
},
1357 { PCI_VDEVICE(MEILHAUS
, 0x4660), BOARD_ME4660
},
1358 { PCI_VDEVICE(MEILHAUS
, 0x4661), BOARD_ME4660I
},
1359 { PCI_VDEVICE(MEILHAUS
, 0x4662), BOARD_ME4660S
},
1360 { PCI_VDEVICE(MEILHAUS
, 0x4663), BOARD_ME4660IS
},
1361 { PCI_VDEVICE(MEILHAUS
, 0x4670), BOARD_ME4670
},
1362 { PCI_VDEVICE(MEILHAUS
, 0x4671), BOARD_ME4670I
},
1363 { PCI_VDEVICE(MEILHAUS
, 0x4672), BOARD_ME4670S
},
1364 { PCI_VDEVICE(MEILHAUS
, 0x4673), BOARD_ME4670IS
},
1365 { PCI_VDEVICE(MEILHAUS
, 0x4680), BOARD_ME4680
},
1366 { PCI_VDEVICE(MEILHAUS
, 0x4681), BOARD_ME4680I
},
1367 { PCI_VDEVICE(MEILHAUS
, 0x4682), BOARD_ME4680S
},
1368 { PCI_VDEVICE(MEILHAUS
, 0x4683), BOARD_ME4680IS
},
1371 MODULE_DEVICE_TABLE(pci
, me4000_pci_table
);
1373 static struct pci_driver me4000_pci_driver
= {
1375 .id_table
= me4000_pci_table
,
1376 .probe
= me4000_pci_probe
,
1377 .remove
= comedi_pci_auto_unconfig
,
1379 module_comedi_pci_driver(me4000_driver
, me4000_pci_driver
);
1381 MODULE_AUTHOR("Comedi http://www.comedi.org");
1382 MODULE_DESCRIPTION("Comedi low-level driver");
1383 MODULE_LICENSE("GPL");
1384 MODULE_FIRMWARE(ME4000_FIRMWARE
);