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/pci.h>
45 #include <linux/delay.h>
46 #include <linux/interrupt.h>
47 #include <linux/list.h>
48 #include <linux/spinlock.h>
50 #include "../comedidev.h"
52 #include "comedi_fc.h"
57 /* file removed due to GPL incompatibility */
58 #include "me4000_fw.h"
62 * ME4000 Register map and bit defines
64 #define ME4000_AO_CHAN(x) ((x) * 0x18)
66 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
67 #define ME4000_AO_CTRL_BIT_MODE_0 (1 << 0)
68 #define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1)
69 #define ME4000_AO_CTRL_MASK_MODE (3 << 0)
70 #define ME4000_AO_CTRL_BIT_STOP (1 << 2)
71 #define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3)
72 #define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4)
73 #define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5)
74 #define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7)
75 #define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8)
76 #define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9)
77 #define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10)
78 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
79 #define ME4000_AO_STATUS_BIT_FSM (1 << 0)
80 #define ME4000_AO_STATUS_BIT_FF (1 << 1)
81 #define ME4000_AO_STATUS_BIT_HF (1 << 2)
82 #define ME4000_AO_STATUS_BIT_EF (1 << 3)
83 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
84 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
85 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
86 #define ME4000_AI_CTRL_REG 0x74
87 #define ME4000_AI_STATUS_REG 0x74
88 #define ME4000_AI_CTRL_BIT_MODE_0 (1 << 0)
89 #define ME4000_AI_CTRL_BIT_MODE_1 (1 << 1)
90 #define ME4000_AI_CTRL_BIT_MODE_2 (1 << 2)
91 #define ME4000_AI_CTRL_BIT_SAMPLE_HOLD (1 << 3)
92 #define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP (1 << 4)
93 #define ME4000_AI_CTRL_BIT_STOP (1 << 5)
94 #define ME4000_AI_CTRL_BIT_CHANNEL_FIFO (1 << 6)
95 #define ME4000_AI_CTRL_BIT_DATA_FIFO (1 << 7)
96 #define ME4000_AI_CTRL_BIT_FULLSCALE (1 << 8)
97 #define ME4000_AI_CTRL_BIT_OFFSET (1 << 9)
98 #define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG (1 << 10)
99 #define ME4000_AI_CTRL_BIT_EX_TRIG (1 << 11)
100 #define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING (1 << 12)
101 #define ME4000_AI_CTRL_BIT_EX_IRQ (1 << 13)
102 #define ME4000_AI_CTRL_BIT_EX_IRQ_RESET (1 << 14)
103 #define ME4000_AI_CTRL_BIT_LE_IRQ (1 << 15)
104 #define ME4000_AI_CTRL_BIT_LE_IRQ_RESET (1 << 16)
105 #define ME4000_AI_CTRL_BIT_HF_IRQ (1 << 17)
106 #define ME4000_AI_CTRL_BIT_HF_IRQ_RESET (1 << 18)
107 #define ME4000_AI_CTRL_BIT_SC_IRQ (1 << 19)
108 #define ME4000_AI_CTRL_BIT_SC_IRQ_RESET (1 << 20)
109 #define ME4000_AI_CTRL_BIT_SC_RELOAD (1 << 21)
110 #define ME4000_AI_STATUS_BIT_EF_CHANNEL (1 << 22)
111 #define ME4000_AI_STATUS_BIT_HF_CHANNEL (1 << 23)
112 #define ME4000_AI_STATUS_BIT_FF_CHANNEL (1 << 24)
113 #define ME4000_AI_STATUS_BIT_EF_DATA (1 << 25)
114 #define ME4000_AI_STATUS_BIT_HF_DATA (1 << 26)
115 #define ME4000_AI_STATUS_BIT_FF_DATA (1 << 27)
116 #define ME4000_AI_STATUS_BIT_LE (1 << 28)
117 #define ME4000_AI_STATUS_BIT_FSM (1 << 29)
118 #define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH (1 << 31)
119 #define ME4000_AI_CHANNEL_LIST_REG 0x78
120 #define ME4000_AI_LIST_INPUT_SINGLE_ENDED (0 << 5)
121 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL (1 << 5)
122 #define ME4000_AI_LIST_RANGE_BIPOLAR_10 (0 << 6)
123 #define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 (1 << 6)
124 #define ME4000_AI_LIST_RANGE_UNIPOLAR_10 (2 << 6)
125 #define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 (3 << 6)
126 #define ME4000_AI_LIST_LAST_ENTRY (1 << 8)
127 #define ME4000_AI_DATA_REG 0x7c
128 #define ME4000_AI_CHAN_TIMER_REG 0x80
129 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
130 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
131 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
132 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
133 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
134 #define ME4000_AI_START_REG 0x98
135 #define ME4000_IRQ_STATUS_REG 0x9c
136 #define ME4000_IRQ_STATUS_BIT_EX (1 << 0)
137 #define ME4000_IRQ_STATUS_BIT_LE (1 << 1)
138 #define ME4000_IRQ_STATUS_BIT_AI_HF (1 << 2)
139 #define ME4000_IRQ_STATUS_BIT_AO_0_HF (1 << 3)
140 #define ME4000_IRQ_STATUS_BIT_AO_1_HF (1 << 4)
141 #define ME4000_IRQ_STATUS_BIT_AO_2_HF (1 << 5)
142 #define ME4000_IRQ_STATUS_BIT_AO_3_HF (1 << 6)
143 #define ME4000_IRQ_STATUS_BIT_SC (1 << 7)
144 #define ME4000_DIO_PORT_0_REG 0xa0
145 #define ME4000_DIO_PORT_1_REG 0xa4
146 #define ME4000_DIO_PORT_2_REG 0xa8
147 #define ME4000_DIO_PORT_3_REG 0xac
148 #define ME4000_DIO_DIR_REG 0xb0
149 #define ME4000_AO_LOADSETREG_XX 0xb4
150 #define ME4000_DIO_CTRL_REG 0xb8
151 #define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0)
152 #define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1)
153 #define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2)
154 #define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3)
155 #define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4)
156 #define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5)
157 #define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6)
158 #define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7)
159 #define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8)
160 #define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9)
161 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10)
162 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11)
163 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12)
164 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13)
165 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
166 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
167 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
169 #define ME4000_AI_FIFO_COUNT 2048
171 #define ME4000_AI_MIN_TICKS 66
172 #define ME4000_AI_MIN_SAMPLE_TIME 2000
174 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
177 unsigned long plx_regbase;
178 unsigned long timer_regbase;
180 unsigned int ao_readback[4];
183 enum me4000_boardid {
199 struct me4000_board {
211 static const struct me4000_board me4000_boards[] = {
329 static const struct comedi_lrange me4000_ai_range = {
338 #define FIRMWARE_NOT_AVAILABLE 1
339 #if FIRMWARE_NOT_AVAILABLE
340 extern unsigned char *xilinx_firm;
343 static int xilinx_download(struct comedi_device *dev)
345 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
346 struct me4000_info *info = dev->private;
347 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
349 wait_queue_head_t queue;
357 init_waitqueue_head(&queue);
360 * Set PLX local interrupt 2 polarity to high.
361 * Interrupt is thrown by init pin of xilinx.
363 outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
365 /* Set /CS and /WRITE of the Xilinx */
366 value = inl(info->plx_regbase + PLX9052_CNTRL);
367 value |= PLX9052_CNTRL_UIO2_DATA;
368 outl(value, info->plx_regbase + PLX9052_CNTRL);
370 /* Init Xilinx with CS1 */
371 inb(xilinx_iobase + 0xC8);
373 /* Wait until /INIT pin is set */
375 intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
376 if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
377 dev_err(dev->class_dev, "Can't init Xilinx\n");
381 /* Reset /CS and /WRITE of the Xilinx */
382 value = inl(info->plx_regbase + PLX9052_CNTRL);
383 value &= ~PLX9052_CNTRL_UIO2_DATA;
384 outl(value, info->plx_regbase + PLX9052_CNTRL);
385 if (FIRMWARE_NOT_AVAILABLE) {
386 dev_err(dev->class_dev,
387 "xilinx firmware unavailable due to licensing, aborting");
390 /* Download Xilinx firmware */
391 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
392 (xilinx_firm[2] << 8) + xilinx_firm[3];
395 for (idx = 0; idx < size; idx++) {
396 outb(xilinx_firm[16 + idx], xilinx_iobase);
399 /* Check if BUSY flag is low */
400 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
401 dev_err(dev->class_dev,
402 "Xilinx is still busy (idx = %d)\n",
409 /* If done flag is high download was successful */
410 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
412 dev_err(dev->class_dev, "DONE flag is not set\n");
413 dev_err(dev->class_dev, "Download not successful\n");
417 /* Set /CS and /WRITE */
418 value = inl(info->plx_regbase + PLX9052_CNTRL);
419 value |= PLX9052_CNTRL_UIO2_DATA;
420 outl(value, info->plx_regbase + PLX9052_CNTRL);
425 static void me4000_reset(struct comedi_device *dev)
427 struct me4000_info *info = dev->private;
431 /* Make a hardware reset */
432 val = inl(info->plx_regbase + PLX9052_CNTRL);
433 val |= PLX9052_CNTRL_PCI_RESET;
434 outl(val, info->plx_regbase + PLX9052_CNTRL);
435 val &= ~PLX9052_CNTRL_PCI_RESET;
436 outl(val , info->plx_regbase + PLX9052_CNTRL);
438 /* 0x8000 to the DACs means an output voltage of 0V */
439 for (chan = 0; chan < 4; chan++)
440 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
442 /* Set both stop bits in the analog input control register */
443 outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
444 dev->iobase + ME4000_AI_CTRL_REG);
446 /* Set both stop bits in the analog output control register */
447 val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
448 for (chan = 0; chan < 4; chan++)
449 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
451 /* Enable interrupts on the PLX */
452 outl(PLX9052_INTCSR_LI1ENAB |
453 PLX9052_INTCSR_LI1POL |
454 PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
456 /* Set the adustment register for AO demux */
457 outl(ME4000_AO_DEMUX_ADJUST_VALUE,
458 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
461 * Set digital I/O direction for port 0
462 * to output on isolated versions
464 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
465 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
468 /*=============================================================================
470 ===========================================================================*/
472 static int me4000_ai_insn_read(struct comedi_device *dev,
473 struct comedi_subdevice *subdevice,
474 struct comedi_insn *insn, unsigned int *data)
476 const struct me4000_board *thisboard = comedi_board(dev);
477 int chan = CR_CHAN(insn->chanspec);
478 int rang = CR_RANGE(insn->chanspec);
479 int aref = CR_AREF(insn->chanspec);
481 unsigned int entry = 0;
487 } else if (insn->n > 1) {
488 dev_err(dev->class_dev, "Invalid instruction length %d\n",
495 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
498 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
501 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
504 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
507 dev_err(dev->class_dev, "Invalid range specified\n");
514 if (chan >= thisboard->ai_nchan) {
515 dev_err(dev->class_dev,
516 "Analog input is not available\n");
519 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
523 if (rang == 0 || rang == 1) {
524 dev_err(dev->class_dev,
525 "Range must be bipolar when aref = diff\n");
529 if (chan >= thisboard->ai_diff_nchan) {
530 dev_err(dev->class_dev,
531 "Analog input is not available\n");
534 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
537 dev_err(dev->class_dev, "Invalid aref specified\n");
541 entry |= ME4000_AI_LIST_LAST_ENTRY;
543 /* Clear channel list, data fifo and both stop bits */
544 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
545 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
546 ME4000_AI_CTRL_BIT_DATA_FIFO |
547 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
548 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
550 /* Set the acquisition mode to single */
551 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
552 ME4000_AI_CTRL_BIT_MODE_2);
553 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
555 /* Enable channel list and data fifo */
556 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
557 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
559 /* Generate channel list entry */
560 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
562 /* Set the timer to maximum sample rate */
563 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
564 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
566 /* Start conversion by dummy read */
567 inl(dev->iobase + ME4000_AI_START_REG);
569 /* Wait until ready */
571 if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
572 ME4000_AI_STATUS_BIT_EF_DATA)) {
573 dev_err(dev->class_dev, "Value not available after wait\n");
577 /* Read value from data fifo */
578 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
579 data[0] = lval ^ 0x8000;
584 static int me4000_ai_cancel(struct comedi_device *dev,
585 struct comedi_subdevice *s)
589 /* Stop any running conversion */
590 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
591 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
592 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
594 /* Clear the control register */
595 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
600 static int me4000_ai_check_chanlist(struct comedi_device *dev,
601 struct comedi_subdevice *s,
602 struct comedi_cmd *cmd)
604 const struct me4000_board *board = comedi_board(dev);
605 unsigned int max_diff_chan = board->ai_diff_nchan;
606 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
609 for (i = 0; i < cmd->chanlist_len; i++) {
610 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
611 unsigned int range = CR_RANGE(cmd->chanlist[i]);
612 unsigned int aref = CR_AREF(cmd->chanlist[i]);
615 dev_dbg(dev->class_dev,
616 "Mode is not equal for all entries\n");
620 if (aref == SDF_DIFF) {
621 if (chan >= max_diff_chan) {
622 dev_dbg(dev->class_dev,
623 "Channel number to high\n");
627 if (!comedi_range_is_bipolar(s, range)) {
628 dev_dbg(dev->class_dev,
629 "Bipolar is not selected in differential mode\n");
638 static int ai_round_cmd_args(struct comedi_device *dev,
639 struct comedi_subdevice *s,
640 struct comedi_cmd *cmd,
641 unsigned int *init_ticks,
642 unsigned int *scan_ticks, unsigned int *chan_ticks)
651 if (cmd->start_arg) {
652 *init_ticks = (cmd->start_arg * 33) / 1000;
653 rest = (cmd->start_arg * 33) % 1000;
655 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
658 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
664 if (cmd->scan_begin_arg) {
665 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
666 rest = (cmd->scan_begin_arg * 33) % 1000;
668 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
671 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
677 if (cmd->convert_arg) {
678 *chan_ticks = (cmd->convert_arg * 33) / 1000;
679 rest = (cmd->convert_arg * 33) % 1000;
681 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
684 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
693 static void ai_write_timer(struct comedi_device *dev,
694 unsigned int init_ticks,
695 unsigned int scan_ticks, unsigned int chan_ticks)
697 outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
698 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
701 outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
702 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
705 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
706 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
709 static int ai_write_chanlist(struct comedi_device *dev,
710 struct comedi_subdevice *s, struct comedi_cmd *cmd)
718 for (i = 0; i < cmd->chanlist_len; i++) {
719 chan = CR_CHAN(cmd->chanlist[i]);
720 rang = CR_RANGE(cmd->chanlist[i]);
721 aref = CR_AREF(cmd->chanlist[i]);
726 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
728 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
730 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
732 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
734 if (aref == SDF_DIFF)
735 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
737 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
739 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
745 static int ai_prepare(struct comedi_device *dev,
746 struct comedi_subdevice *s,
747 struct comedi_cmd *cmd,
748 unsigned int init_ticks,
749 unsigned int scan_ticks, unsigned int chan_ticks)
752 unsigned int tmp = 0;
754 /* Write timer arguments */
755 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
757 /* Reset control register */
758 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
761 if ((cmd->start_src == TRIG_EXT &&
762 cmd->scan_begin_src == TRIG_TIMER &&
763 cmd->convert_src == TRIG_TIMER) ||
764 (cmd->start_src == TRIG_EXT &&
765 cmd->scan_begin_src == TRIG_FOLLOW &&
766 cmd->convert_src == TRIG_TIMER)) {
767 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
768 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
769 ME4000_AI_CTRL_BIT_DATA_FIFO;
770 } else if (cmd->start_src == TRIG_EXT &&
771 cmd->scan_begin_src == TRIG_EXT &&
772 cmd->convert_src == TRIG_TIMER) {
773 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
774 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
775 ME4000_AI_CTRL_BIT_DATA_FIFO;
776 } else if (cmd->start_src == TRIG_EXT &&
777 cmd->scan_begin_src == TRIG_EXT &&
778 cmd->convert_src == TRIG_EXT) {
779 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
780 ME4000_AI_CTRL_BIT_MODE_1 |
781 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
782 ME4000_AI_CTRL_BIT_DATA_FIFO;
784 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
785 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
786 ME4000_AI_CTRL_BIT_DATA_FIFO;
790 if (cmd->stop_src == TRIG_COUNT) {
791 outl(cmd->chanlist_len * cmd->stop_arg,
792 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
793 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
794 } else if (cmd->stop_src == TRIG_NONE &&
795 cmd->scan_end_src == TRIG_COUNT) {
796 outl(cmd->scan_end_arg,
797 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
798 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
800 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
803 /* Write the setup to the control register */
804 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
806 /* Write the channel list */
807 ai_write_chanlist(dev, s, cmd);
812 static int me4000_ai_do_cmd(struct comedi_device *dev,
813 struct comedi_subdevice *s)
816 unsigned int init_ticks = 0;
817 unsigned int scan_ticks = 0;
818 unsigned int chan_ticks = 0;
819 struct comedi_cmd *cmd = &s->async->cmd;
821 /* Reset the analog input */
822 err = me4000_ai_cancel(dev, s);
826 /* Round the timer arguments */
827 err = ai_round_cmd_args(dev,
828 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
832 /* Prepare the AI for acquisition */
833 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
837 /* Start acquistion by dummy read */
838 inl(dev->iobase + ME4000_AI_START_REG);
843 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
844 struct comedi_subdevice *s,
845 struct comedi_cmd *cmd)
848 unsigned int init_ticks;
849 unsigned int chan_ticks;
850 unsigned int scan_ticks;
853 /* Only rounding flags are implemented */
854 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
856 /* Round the timer arguments */
857 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
859 /* Step 1 : check if triggers are trivially valid */
861 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
862 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
863 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
864 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
865 err |= cfc_check_trigger_src(&cmd->scan_end_src,
866 TRIG_NONE | TRIG_COUNT);
867 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
872 /* Step 2a : make sure trigger sources are unique */
874 err |= cfc_check_trigger_is_unique(cmd->start_src);
875 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
876 err |= cfc_check_trigger_is_unique(cmd->convert_src);
877 err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
878 err |= cfc_check_trigger_is_unique(cmd->stop_src);
880 /* Step 2b : and mutually compatible */
882 if (cmd->start_src == TRIG_NOW &&
883 cmd->scan_begin_src == TRIG_TIMER &&
884 cmd->convert_src == TRIG_TIMER) {
885 } else if (cmd->start_src == TRIG_NOW &&
886 cmd->scan_begin_src == TRIG_FOLLOW &&
887 cmd->convert_src == TRIG_TIMER) {
888 } else if (cmd->start_src == TRIG_EXT &&
889 cmd->scan_begin_src == TRIG_TIMER &&
890 cmd->convert_src == TRIG_TIMER) {
891 } else if (cmd->start_src == TRIG_EXT &&
892 cmd->scan_begin_src == TRIG_FOLLOW &&
893 cmd->convert_src == TRIG_TIMER) {
894 } else if (cmd->start_src == TRIG_EXT &&
895 cmd->scan_begin_src == TRIG_EXT &&
896 cmd->convert_src == TRIG_TIMER) {
897 } else if (cmd->start_src == TRIG_EXT &&
898 cmd->scan_begin_src == TRIG_EXT &&
899 cmd->convert_src == TRIG_EXT) {
907 /* Step 3: check if arguments are trivially valid */
909 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
911 if (cmd->chanlist_len < 1) {
912 cmd->chanlist_len = 1;
915 if (init_ticks < 66) {
916 cmd->start_arg = 2000;
919 if (scan_ticks && scan_ticks < 67) {
920 cmd->scan_begin_arg = 2031;
923 if (chan_ticks < 66) {
924 cmd->convert_arg = 2000;
932 * Stage 4. Check for argument conflicts.
934 if (cmd->start_src == TRIG_NOW &&
935 cmd->scan_begin_src == TRIG_TIMER &&
936 cmd->convert_src == TRIG_TIMER) {
938 /* Check timer arguments */
939 if (init_ticks < ME4000_AI_MIN_TICKS) {
940 dev_err(dev->class_dev, "Invalid start arg\n");
941 cmd->start_arg = 2000; /* 66 ticks at least */
944 if (chan_ticks < ME4000_AI_MIN_TICKS) {
945 dev_err(dev->class_dev, "Invalid convert arg\n");
946 cmd->convert_arg = 2000; /* 66 ticks at least */
949 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
950 dev_err(dev->class_dev, "Invalid scan end arg\n");
952 /* At least one tick more */
953 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
956 } else if (cmd->start_src == TRIG_NOW &&
957 cmd->scan_begin_src == TRIG_FOLLOW &&
958 cmd->convert_src == TRIG_TIMER) {
960 /* Check timer arguments */
961 if (init_ticks < ME4000_AI_MIN_TICKS) {
962 dev_err(dev->class_dev, "Invalid start arg\n");
963 cmd->start_arg = 2000; /* 66 ticks at least */
966 if (chan_ticks < ME4000_AI_MIN_TICKS) {
967 dev_err(dev->class_dev, "Invalid convert arg\n");
968 cmd->convert_arg = 2000; /* 66 ticks at least */
971 } else if (cmd->start_src == TRIG_EXT &&
972 cmd->scan_begin_src == TRIG_TIMER &&
973 cmd->convert_src == TRIG_TIMER) {
975 /* Check timer arguments */
976 if (init_ticks < ME4000_AI_MIN_TICKS) {
977 dev_err(dev->class_dev, "Invalid start arg\n");
978 cmd->start_arg = 2000; /* 66 ticks at least */
981 if (chan_ticks < ME4000_AI_MIN_TICKS) {
982 dev_err(dev->class_dev, "Invalid convert arg\n");
983 cmd->convert_arg = 2000; /* 66 ticks at least */
986 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
987 dev_err(dev->class_dev, "Invalid scan end arg\n");
989 /* At least one tick more */
990 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
993 } else if (cmd->start_src == TRIG_EXT &&
994 cmd->scan_begin_src == TRIG_FOLLOW &&
995 cmd->convert_src == TRIG_TIMER) {
997 /* Check timer arguments */
998 if (init_ticks < ME4000_AI_MIN_TICKS) {
999 dev_err(dev->class_dev, "Invalid start arg\n");
1000 cmd->start_arg = 2000; /* 66 ticks at least */
1003 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1004 dev_err(dev->class_dev, "Invalid convert arg\n");
1005 cmd->convert_arg = 2000; /* 66 ticks at least */
1008 } else if (cmd->start_src == TRIG_EXT &&
1009 cmd->scan_begin_src == TRIG_EXT &&
1010 cmd->convert_src == TRIG_TIMER) {
1012 /* Check timer arguments */
1013 if (init_ticks < ME4000_AI_MIN_TICKS) {
1014 dev_err(dev->class_dev, "Invalid start arg\n");
1015 cmd->start_arg = 2000; /* 66 ticks at least */
1018 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1019 dev_err(dev->class_dev, "Invalid convert arg\n");
1020 cmd->convert_arg = 2000; /* 66 ticks at least */
1023 } else if (cmd->start_src == TRIG_EXT &&
1024 cmd->scan_begin_src == TRIG_EXT &&
1025 cmd->convert_src == TRIG_EXT) {
1027 /* Check timer arguments */
1028 if (init_ticks < ME4000_AI_MIN_TICKS) {
1029 dev_err(dev->class_dev, "Invalid start arg\n");
1030 cmd->start_arg = 2000; /* 66 ticks at least */
1034 if (cmd->stop_src == TRIG_COUNT) {
1035 if (cmd->stop_arg == 0) {
1036 dev_err(dev->class_dev, "Invalid stop arg\n");
1041 if (cmd->scan_end_src == TRIG_COUNT) {
1042 if (cmd->scan_end_arg == 0) {
1043 dev_err(dev->class_dev, "Invalid scan end arg\n");
1044 cmd->scan_end_arg = 1;
1052 /* Step 5: check channel list if it exists */
1053 if (cmd->chanlist && cmd->chanlist_len > 0)
1054 err |= me4000_ai_check_chanlist(dev, s, cmd);
1062 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1065 struct comedi_device *dev = dev_id;
1066 struct comedi_subdevice *s = dev->read_subdev;
1074 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1075 ME4000_IRQ_STATUS_BIT_AI_HF) {
1076 /* Read status register to find out what happened */
1077 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1079 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1080 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1081 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1082 c = ME4000_AI_FIFO_COUNT;
1085 * FIFO overflow, so stop conversion
1086 * and disable all interrupts
1088 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1089 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1090 ME4000_AI_CTRL_BIT_SC_IRQ);
1091 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1093 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1095 dev_err(dev->class_dev, "FIFO overflow\n");
1096 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1097 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1098 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1099 s->async->events |= COMEDI_CB_BLOCK;
1101 c = ME4000_AI_FIFO_COUNT / 2;
1103 dev_err(dev->class_dev,
1104 "Can't determine state of fifo\n");
1108 * Undefined state, so stop conversion
1109 * and disable all interrupts
1111 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1112 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1113 ME4000_AI_CTRL_BIT_SC_IRQ);
1114 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1116 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1118 dev_err(dev->class_dev, "Undefined FIFO state\n");
1121 for (i = 0; i < c; i++) {
1122 /* Read value from data fifo */
1123 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1126 if (!comedi_buf_put(s, lval)) {
1128 * Buffer overflow, so stop conversion
1129 * and disable all interrupts
1131 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1132 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1133 ME4000_AI_CTRL_BIT_SC_IRQ);
1134 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1136 s->async->events |= COMEDI_CB_OVERFLOW;
1138 dev_err(dev->class_dev, "Buffer overflow\n");
1144 /* Work is done, so reset the interrupt */
1145 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1146 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1147 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1148 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1151 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1152 ME4000_IRQ_STATUS_BIT_SC) {
1153 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1156 * Acquisition is complete, so stop
1157 * conversion and disable all interrupts
1159 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1160 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1161 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1162 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1164 /* Poll data until fifo empty */
1165 while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1166 ME4000_AI_STATUS_BIT_EF_DATA) {
1167 /* Read value from data fifo */
1168 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1171 if (!comedi_buf_put(s, lval)) {
1172 dev_err(dev->class_dev, "Buffer overflow\n");
1173 s->async->events |= COMEDI_CB_OVERFLOW;
1178 /* Work is done, so reset the interrupt */
1179 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1180 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1181 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1182 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1185 if (s->async->events)
1186 comedi_event(dev, s);
1191 /*=============================================================================
1192 Analog output section
1193 ===========================================================================*/
1195 static int me4000_ao_insn_write(struct comedi_device *dev,
1196 struct comedi_subdevice *s,
1197 struct comedi_insn *insn, unsigned int *data)
1199 const struct me4000_board *thisboard = comedi_board(dev);
1200 struct me4000_info *info = dev->private;
1201 int chan = CR_CHAN(insn->chanspec);
1202 int rang = CR_RANGE(insn->chanspec);
1203 int aref = CR_AREF(insn->chanspec);
1208 } else if (insn->n > 1) {
1209 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1214 if (chan >= thisboard->ao_nchan) {
1215 dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
1220 dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
1224 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1225 dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
1229 /* Stop any running conversion */
1230 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1231 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1232 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1234 /* Clear control register and set to single mode */
1235 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1237 /* Write data value */
1238 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1240 /* Store in the mirror */
1241 info->ao_readback[chan] = data[0];
1246 static int me4000_ao_insn_read(struct comedi_device *dev,
1247 struct comedi_subdevice *s,
1248 struct comedi_insn *insn, unsigned int *data)
1250 struct me4000_info *info = dev->private;
1251 int chan = CR_CHAN(insn->chanspec);
1255 } else if (insn->n > 1) {
1256 dev_err(dev->class_dev, "Invalid instruction length\n");
1260 data[0] = info->ao_readback[chan];
1265 static int me4000_dio_insn_bits(struct comedi_device *dev,
1266 struct comedi_subdevice *s,
1267 struct comedi_insn *insn,
1270 if (comedi_dio_update_state(s, data)) {
1271 outl((s->state >> 0) & 0xFF,
1272 dev->iobase + ME4000_DIO_PORT_0_REG);
1273 outl((s->state >> 8) & 0xFF,
1274 dev->iobase + ME4000_DIO_PORT_1_REG);
1275 outl((s->state >> 16) & 0xFF,
1276 dev->iobase + ME4000_DIO_PORT_2_REG);
1277 outl((s->state >> 24) & 0xFF,
1278 dev->iobase + ME4000_DIO_PORT_3_REG);
1281 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1282 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1283 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1284 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1289 static int me4000_dio_insn_config(struct comedi_device *dev,
1290 struct comedi_subdevice *s,
1291 struct comedi_insn *insn,
1294 unsigned int chan = CR_CHAN(insn->chanspec);
1308 ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1312 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1313 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
1314 ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 |
1315 ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 |
1316 ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
1317 if (s->io_bits & 0x000000ff)
1318 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1319 if (s->io_bits & 0x0000ff00)
1320 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1321 if (s->io_bits & 0x00ff0000)
1322 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1323 if (s->io_bits & 0xff000000)
1324 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1327 * Check for optoisolated ME-4000 version.
1328 * If one the first port is a fixed output
1329 * port and the second is a fixed input port.
1331 if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1332 s->io_bits |= 0x000000ff;
1333 s->io_bits &= ~0x0000ff00;
1334 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1335 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1336 ME4000_DIO_CTRL_BIT_MODE_3);
1339 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1344 /*=============================================================================
1346 ===========================================================================*/
1348 static int me4000_cnt_insn_config(struct comedi_device *dev,
1349 struct comedi_subdevice *s,
1350 struct comedi_insn *insn,
1353 struct me4000_info *info = dev->private;
1354 unsigned int chan = CR_CHAN(insn->chanspec);
1362 err = i8254_set_mode(info->timer_regbase, 0, chan,
1363 I8254_MODE0 | I8254_BINARY);
1366 i8254_write(info->timer_regbase, 0, chan, 0);
1368 case GPCT_SET_OPERATION:
1372 err = i8254_set_mode(info->timer_regbase, 0, chan,
1373 (data[1] << 1) | I8254_BINARY);
1384 static int me4000_cnt_insn_read(struct comedi_device *dev,
1385 struct comedi_subdevice *s,
1386 struct comedi_insn *insn, unsigned int *data)
1388 struct me4000_info *info = dev->private;
1394 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1399 data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
1404 static int me4000_cnt_insn_write(struct comedi_device *dev,
1405 struct comedi_subdevice *s,
1406 struct comedi_insn *insn, unsigned int *data)
1408 struct me4000_info *info = dev->private;
1412 } else if (insn->n > 1) {
1413 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1418 i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
1423 static int me4000_auto_attach(struct comedi_device *dev,
1424 unsigned long context)
1426 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1427 const struct me4000_board *thisboard = NULL;
1428 struct me4000_info *info;
1429 struct comedi_subdevice *s;
1432 if (context < ARRAY_SIZE(me4000_boards))
1433 thisboard = &me4000_boards[context];
1436 dev->board_ptr = thisboard;
1437 dev->board_name = thisboard->name;
1439 info = comedi_alloc_devpriv(dev, sizeof(*info));
1443 result = comedi_pci_enable(dev);
1447 info->plx_regbase = pci_resource_start(pcidev, 1);
1448 dev->iobase = pci_resource_start(pcidev, 2);
1449 info->timer_regbase = pci_resource_start(pcidev, 3);
1450 if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1453 result = xilinx_download(dev);
1459 if (pcidev->irq > 0) {
1460 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1461 dev->board_name, dev);
1463 dev->irq = pcidev->irq;
1466 result = comedi_alloc_subdevices(dev, 4);
1470 /*=========================================================================
1471 Analog input subdevice
1472 ========================================================================*/
1474 s = &dev->subdevices[0];
1476 if (thisboard->ai_nchan) {
1477 s->type = COMEDI_SUBD_AI;
1479 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1480 s->n_chan = thisboard->ai_nchan;
1481 s->maxdata = 0xFFFF; /* 16 bit ADC */
1482 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1483 s->range_table = &me4000_ai_range;
1484 s->insn_read = me4000_ai_insn_read;
1487 dev->read_subdev = s;
1488 s->subdev_flags |= SDF_CMD_READ;
1489 s->cancel = me4000_ai_cancel;
1490 s->do_cmdtest = me4000_ai_do_cmd_test;
1491 s->do_cmd = me4000_ai_do_cmd;
1494 s->type = COMEDI_SUBD_UNUSED;
1497 /*=========================================================================
1498 Analog output subdevice
1499 ========================================================================*/
1501 s = &dev->subdevices[1];
1503 if (thisboard->ao_nchan) {
1504 s->type = COMEDI_SUBD_AO;
1505 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1506 s->n_chan = thisboard->ao_nchan;
1507 s->maxdata = 0xFFFF; /* 16 bit DAC */
1508 s->range_table = &range_bipolar10;
1509 s->insn_write = me4000_ao_insn_write;
1510 s->insn_read = me4000_ao_insn_read;
1512 s->type = COMEDI_SUBD_UNUSED;
1515 /*=========================================================================
1516 Digital I/O subdevice
1517 ========================================================================*/
1519 s = &dev->subdevices[2];
1521 if (thisboard->dio_nchan) {
1522 s->type = COMEDI_SUBD_DIO;
1523 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1524 s->n_chan = thisboard->dio_nchan;
1526 s->range_table = &range_digital;
1527 s->insn_bits = me4000_dio_insn_bits;
1528 s->insn_config = me4000_dio_insn_config;
1530 s->type = COMEDI_SUBD_UNUSED;
1534 * Check for optoisolated ME-4000 version. If one the first
1535 * port is a fixed output port and the second is a fixed input port.
1537 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1539 outl(ME4000_DIO_CTRL_BIT_MODE_0,
1540 dev->iobase + ME4000_DIO_DIR_REG);
1543 /*=========================================================================
1545 ========================================================================*/
1547 s = &dev->subdevices[3];
1549 if (thisboard->has_counter) {
1550 s->type = COMEDI_SUBD_COUNTER;
1551 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1553 s->maxdata = 0xFFFF; /* 16 bit counters */
1554 s->insn_read = me4000_cnt_insn_read;
1555 s->insn_write = me4000_cnt_insn_write;
1556 s->insn_config = me4000_cnt_insn_config;
1558 s->type = COMEDI_SUBD_UNUSED;
1564 static void me4000_detach(struct comedi_device *dev)
1567 free_irq(dev->irq, dev);
1570 comedi_pci_disable(dev);
1573 static struct comedi_driver me4000_driver = {
1574 .driver_name = "me4000",
1575 .module = THIS_MODULE,
1576 .auto_attach = me4000_auto_attach,
1577 .detach = me4000_detach,
1580 static int me4000_pci_probe(struct pci_dev *dev,
1581 const struct pci_device_id *id)
1583 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1586 static const struct pci_device_id me4000_pci_table[] = {
1587 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1588 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1589 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1590 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1591 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1592 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1593 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1594 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1595 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1596 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1597 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1598 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1599 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1602 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1604 static struct pci_driver me4000_pci_driver = {
1606 .id_table = me4000_pci_table,
1607 .probe = me4000_pci_probe,
1608 .remove = comedi_pci_auto_unconfig,
1610 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1612 MODULE_AUTHOR("Comedi http://www.comedi.org");
1613 MODULE_DESCRIPTION("Comedi low-level driver");
1614 MODULE_LICENSE("GPL");