1 // SPDX-License-Identifier: GPL-2.0+
4 * Source code for the Meilhaus ME-4000 board family.
6 * COMEDI - Linux Control and Measurement Device Interface
7 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
12 * Description: Meilhaus ME-4000 series boards
13 * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i,
15 * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
16 * Updated: Mon, 18 Mar 2002 15:34:01 -0800
25 * Configuration Options: not applicable, uses PCI auto config
27 * The firmware required by these boards is available in the
28 * comedi_nonfree_firmware tarball available from
29 * https://www.comedi.org.
32 #include <linux/module.h>
33 #include <linux/delay.h>
34 #include <linux/interrupt.h>
36 #include "../comedi_pci.h"
38 #include "comedi_8254.h"
41 #define ME4000_FIRMWARE "/*(DEBLOBBED)*/"
44 * ME4000 Register map and bit defines
46 #define ME4000_AO_CHAN(x) ((x) * 0x18)
48 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
49 #define ME4000_AO_CTRL_MODE_0 BIT(0)
50 #define ME4000_AO_CTRL_MODE_1 BIT(1)
51 #define ME4000_AO_CTRL_STOP BIT(2)
52 #define ME4000_AO_CTRL_ENABLE_FIFO BIT(3)
53 #define ME4000_AO_CTRL_ENABLE_EX_TRIG BIT(4)
54 #define ME4000_AO_CTRL_EX_TRIG_EDGE BIT(5)
55 #define ME4000_AO_CTRL_IMMEDIATE_STOP BIT(7)
56 #define ME4000_AO_CTRL_ENABLE_DO BIT(8)
57 #define ME4000_AO_CTRL_ENABLE_IRQ BIT(9)
58 #define ME4000_AO_CTRL_RESET_IRQ BIT(10)
59 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
60 #define ME4000_AO_STATUS_FSM BIT(0)
61 #define ME4000_AO_STATUS_FF BIT(1)
62 #define ME4000_AO_STATUS_HF BIT(2)
63 #define ME4000_AO_STATUS_EF BIT(3)
64 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
65 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
66 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
67 #define ME4000_AI_CTRL_REG 0x74
68 #define ME4000_AI_STATUS_REG 0x74
69 #define ME4000_AI_CTRL_MODE_0 BIT(0)
70 #define ME4000_AI_CTRL_MODE_1 BIT(1)
71 #define ME4000_AI_CTRL_MODE_2 BIT(2)
72 #define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3)
73 #define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4)
74 #define ME4000_AI_CTRL_STOP BIT(5)
75 #define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6)
76 #define ME4000_AI_CTRL_DATA_FIFO BIT(7)
77 #define ME4000_AI_CTRL_FULLSCALE BIT(8)
78 #define ME4000_AI_CTRL_OFFSET BIT(9)
79 #define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10)
80 #define ME4000_AI_CTRL_EX_TRIG BIT(11)
81 #define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12)
82 #define ME4000_AI_CTRL_EX_IRQ BIT(13)
83 #define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14)
84 #define ME4000_AI_CTRL_LE_IRQ BIT(15)
85 #define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16)
86 #define ME4000_AI_CTRL_HF_IRQ BIT(17)
87 #define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18)
88 #define ME4000_AI_CTRL_SC_IRQ BIT(19)
89 #define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20)
90 #define ME4000_AI_CTRL_SC_RELOAD BIT(21)
91 #define ME4000_AI_STATUS_EF_CHANNEL BIT(22)
92 #define ME4000_AI_STATUS_HF_CHANNEL BIT(23)
93 #define ME4000_AI_STATUS_FF_CHANNEL BIT(24)
94 #define ME4000_AI_STATUS_EF_DATA BIT(25)
95 #define ME4000_AI_STATUS_HF_DATA BIT(26)
96 #define ME4000_AI_STATUS_FF_DATA BIT(27)
97 #define ME4000_AI_STATUS_LE BIT(28)
98 #define ME4000_AI_STATUS_FSM BIT(29)
99 #define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31)
100 #define ME4000_AI_CHANNEL_LIST_REG 0x78
101 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5)
102 #define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6)
103 #define ME4000_AI_LIST_LAST_ENTRY BIT(8)
104 #define ME4000_AI_DATA_REG 0x7c
105 #define ME4000_AI_CHAN_TIMER_REG 0x80
106 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
107 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
108 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
109 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
110 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
111 #define ME4000_AI_START_REG 0x98
112 #define ME4000_IRQ_STATUS_REG 0x9c
113 #define ME4000_IRQ_STATUS_EX BIT(0)
114 #define ME4000_IRQ_STATUS_LE BIT(1)
115 #define ME4000_IRQ_STATUS_AI_HF BIT(2)
116 #define ME4000_IRQ_STATUS_AO_0_HF BIT(3)
117 #define ME4000_IRQ_STATUS_AO_1_HF BIT(4)
118 #define ME4000_IRQ_STATUS_AO_2_HF BIT(5)
119 #define ME4000_IRQ_STATUS_AO_3_HF BIT(6)
120 #define ME4000_IRQ_STATUS_SC BIT(7)
121 #define ME4000_DIO_PORT_0_REG 0xa0
122 #define ME4000_DIO_PORT_1_REG 0xa4
123 #define ME4000_DIO_PORT_2_REG 0xa8
124 #define ME4000_DIO_PORT_3_REG 0xac
125 #define ME4000_DIO_DIR_REG 0xb0
126 #define ME4000_AO_LOADSETREG_XX 0xb4
127 #define ME4000_DIO_CTRL_REG 0xb8
128 #define ME4000_DIO_CTRL_MODE_0 BIT(0)
129 #define ME4000_DIO_CTRL_MODE_1 BIT(1)
130 #define ME4000_DIO_CTRL_MODE_2 BIT(2)
131 #define ME4000_DIO_CTRL_MODE_3 BIT(3)
132 #define ME4000_DIO_CTRL_MODE_4 BIT(4)
133 #define ME4000_DIO_CTRL_MODE_5 BIT(5)
134 #define ME4000_DIO_CTRL_MODE_6 BIT(6)
135 #define ME4000_DIO_CTRL_MODE_7 BIT(7)
136 #define ME4000_DIO_CTRL_FUNCTION_0 BIT(8)
137 #define ME4000_DIO_CTRL_FUNCTION_1 BIT(9)
138 #define ME4000_DIO_CTRL_FIFO_HIGH_0 BIT(10)
139 #define ME4000_DIO_CTRL_FIFO_HIGH_1 BIT(11)
140 #define ME4000_DIO_CTRL_FIFO_HIGH_2 BIT(12)
141 #define ME4000_DIO_CTRL_FIFO_HIGH_3 BIT(13)
142 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
143 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
144 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
146 #define ME4000_AI_FIFO_COUNT 2048
148 #define ME4000_AI_MIN_TICKS 66
149 #define ME4000_AI_MIN_SAMPLE_TIME 2000
151 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
153 struct me4000_private {
154 unsigned long plx_regbase;
155 unsigned int ai_ctrl_mode;
156 unsigned int ai_init_ticks;
157 unsigned int ai_scan_ticks;
158 unsigned int ai_chan_ticks;
161 enum me4000_boardid {
177 struct me4000_board {
180 unsigned int can_do_diff_ai:1;
181 unsigned int can_do_sh_ai:1; /* sample & hold (8 channels) */
182 unsigned int ex_trig_analog:1;
183 unsigned int has_ao:1;
184 unsigned int has_ao_fifo:1;
185 unsigned int has_counter:1;
188 static const struct me4000_board me4000_boards[] = {
294 * NOTE: the ranges here are inverted compared to the values
295 * written to the ME4000_AI_CHANNEL_LIST_REG,
297 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
299 static const struct comedi_lrange me4000_ai_range = {
308 static int me4000_xilinx_download(struct comedi_device *dev,
309 const u8 *data, size_t size,
310 unsigned long context)
312 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
313 struct me4000_private *devpriv = dev->private;
314 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
315 unsigned int file_length;
323 * Set PLX local interrupt 2 polarity to high.
324 * Interrupt is thrown by init pin of xilinx.
326 outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR);
328 /* Set /CS and /WRITE of the Xilinx */
329 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
330 val |= PLX9052_CNTRL_UIO2_DATA;
331 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
333 /* Init Xilinx with CS1 */
334 inb(xilinx_iobase + 0xC8);
336 /* Wait until /INIT pin is set */
337 usleep_range(20, 1000);
338 val = inl(devpriv->plx_regbase + PLX9052_INTCSR);
339 if (!(val & PLX9052_INTCSR_LI2STAT)) {
340 dev_err(dev->class_dev, "Can't init Xilinx\n");
344 /* Reset /CS and /WRITE of the Xilinx */
345 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
346 val &= ~PLX9052_CNTRL_UIO2_DATA;
347 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
349 /* Download Xilinx firmware */
350 file_length = (((unsigned int)data[0] & 0xff) << 24) +
351 (((unsigned int)data[1] & 0xff) << 16) +
352 (((unsigned int)data[2] & 0xff) << 8) +
353 ((unsigned int)data[3] & 0xff);
354 usleep_range(10, 1000);
356 for (i = 0; i < file_length; i++) {
357 outb(data[16 + i], xilinx_iobase);
358 usleep_range(10, 1000);
360 /* Check if BUSY flag is low */
361 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
362 if (val & PLX9052_CNTRL_UIO1_DATA) {
363 dev_err(dev->class_dev,
364 "Xilinx is still busy (i = %d)\n", i);
369 /* If done flag is high download was successful */
370 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
371 if (!(val & PLX9052_CNTRL_UIO0_DATA)) {
372 dev_err(dev->class_dev, "DONE flag is not set\n");
373 dev_err(dev->class_dev, "Download not successful\n");
377 /* Set /CS and /WRITE */
378 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
379 val |= PLX9052_CNTRL_UIO2_DATA;
380 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
385 static void me4000_ai_reset(struct comedi_device *dev)
389 /* Stop any running conversion */
390 ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG);
391 ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP;
392 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
394 /* Clear the control register */
395 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
398 static void me4000_reset(struct comedi_device *dev)
400 struct me4000_private *devpriv = dev->private;
404 /* Disable interrupts on the PLX */
405 outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
407 /* Software reset the PLX */
408 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
409 val |= PLX9052_CNTRL_PCI_RESET;
410 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
411 val &= ~PLX9052_CNTRL_PCI_RESET;
412 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
414 /* 0x8000 to the DACs means an output voltage of 0V */
415 for (chan = 0; chan < 4; chan++)
416 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
418 me4000_ai_reset(dev);
420 /* Set both stop bits in the analog output control register */
421 val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP;
422 for (chan = 0; chan < 4; chan++)
423 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
425 /* Set the adustment register for AO demux */
426 outl(ME4000_AO_DEMUX_ADJUST_VALUE,
427 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
430 * Set digital I/O direction for port 0
431 * to output on isolated versions
433 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
434 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
437 static unsigned int me4000_ai_get_sample(struct comedi_device *dev,
438 struct comedi_subdevice *s)
442 /* read two's complement value and munge to offset binary */
443 val = inl(dev->iobase + ME4000_AI_DATA_REG);
444 return comedi_offset_munge(s, val);
447 static int me4000_ai_eoc(struct comedi_device *dev,
448 struct comedi_subdevice *s,
449 struct comedi_insn *insn,
450 unsigned long context)
454 status = inl(dev->iobase + ME4000_AI_STATUS_REG);
455 if (status & ME4000_AI_STATUS_EF_DATA)
460 static int me4000_ai_insn_read(struct comedi_device *dev,
461 struct comedi_subdevice *s,
462 struct comedi_insn *insn,
465 unsigned int chan = CR_CHAN(insn->chanspec);
466 unsigned int range = CR_RANGE(insn->chanspec);
467 unsigned int aref = CR_AREF(insn->chanspec);
472 entry = chan | ME4000_AI_LIST_RANGE(range);
473 if (aref == AREF_DIFF) {
474 if (!(s->subdev_flags & SDF_DIFF)) {
475 dev_err(dev->class_dev,
476 "Differential inputs are not available\n");
480 if (!comedi_range_is_bipolar(s, range)) {
481 dev_err(dev->class_dev,
482 "Range must be bipolar when aref = diff\n");
486 if (chan >= (s->n_chan / 2)) {
487 dev_err(dev->class_dev,
488 "Analog input is not available\n");
491 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
494 entry |= ME4000_AI_LIST_LAST_ENTRY;
496 /* Enable channel list and data fifo for single acquisition mode */
497 outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO,
498 dev->iobase + ME4000_AI_CTRL_REG);
500 /* Generate channel list entry */
501 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
503 /* Set the timer to maximum sample rate */
504 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
505 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
507 for (i = 0; i < insn->n; i++) {
510 /* start conversion by dummy read */
511 inl(dev->iobase + ME4000_AI_START_REG);
513 ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0);
517 val = me4000_ai_get_sample(dev, s);
518 data[i] = comedi_offset_munge(s, val);
521 me4000_ai_reset(dev);
523 return ret ? ret : insn->n;
526 static int me4000_ai_cancel(struct comedi_device *dev,
527 struct comedi_subdevice *s)
529 me4000_ai_reset(dev);
534 static int me4000_ai_check_chanlist(struct comedi_device *dev,
535 struct comedi_subdevice *s,
536 struct comedi_cmd *cmd)
538 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
541 for (i = 0; i < cmd->chanlist_len; i++) {
542 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
543 unsigned int range = CR_RANGE(cmd->chanlist[i]);
544 unsigned int aref = CR_AREF(cmd->chanlist[i]);
547 dev_dbg(dev->class_dev,
548 "Mode is not equal for all entries\n");
552 if (aref == AREF_DIFF) {
553 if (!(s->subdev_flags & SDF_DIFF)) {
554 dev_err(dev->class_dev,
555 "Differential inputs are not available\n");
559 if (chan >= (s->n_chan / 2)) {
560 dev_dbg(dev->class_dev,
561 "Channel number to high\n");
565 if (!comedi_range_is_bipolar(s, range)) {
566 dev_dbg(dev->class_dev,
567 "Bipolar is not selected in differential mode\n");
576 static void me4000_ai_round_cmd_args(struct comedi_device *dev,
577 struct comedi_subdevice *s,
578 struct comedi_cmd *cmd)
580 struct me4000_private *devpriv = dev->private;
583 devpriv->ai_init_ticks = 0;
584 devpriv->ai_scan_ticks = 0;
585 devpriv->ai_chan_ticks = 0;
587 if (cmd->start_arg) {
588 devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000;
589 rest = (cmd->start_arg * 33) % 1000;
591 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
593 devpriv->ai_init_ticks++;
594 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
596 devpriv->ai_init_ticks++;
600 if (cmd->scan_begin_arg) {
601 devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
602 rest = (cmd->scan_begin_arg * 33) % 1000;
604 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
606 devpriv->ai_scan_ticks++;
607 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
609 devpriv->ai_scan_ticks++;
613 if (cmd->convert_arg) {
614 devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000;
615 rest = (cmd->convert_arg * 33) % 1000;
617 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
619 devpriv->ai_chan_ticks++;
620 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
622 devpriv->ai_chan_ticks++;
627 static void me4000_ai_write_chanlist(struct comedi_device *dev,
628 struct comedi_subdevice *s,
629 struct comedi_cmd *cmd)
633 for (i = 0; i < cmd->chanlist_len; i++) {
634 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
635 unsigned int range = CR_RANGE(cmd->chanlist[i]);
636 unsigned int aref = CR_AREF(cmd->chanlist[i]);
639 entry = chan | ME4000_AI_LIST_RANGE(range);
641 if (aref == AREF_DIFF)
642 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
644 if (i == (cmd->chanlist_len - 1))
645 entry |= ME4000_AI_LIST_LAST_ENTRY;
647 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
651 static int me4000_ai_do_cmd(struct comedi_device *dev,
652 struct comedi_subdevice *s)
654 struct me4000_private *devpriv = dev->private;
655 struct comedi_cmd *cmd = &s->async->cmd;
658 /* Write timer arguments */
659 outl(devpriv->ai_init_ticks - 1,
660 dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
661 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
663 if (devpriv->ai_scan_ticks) {
664 outl(devpriv->ai_scan_ticks - 1,
665 dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
666 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
669 outl(devpriv->ai_chan_ticks - 1,
670 dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
671 outl(devpriv->ai_chan_ticks - 1,
672 dev->iobase + ME4000_AI_CHAN_TIMER_REG);
675 ctrl = devpriv->ai_ctrl_mode |
676 ME4000_AI_CTRL_CHANNEL_FIFO |
677 ME4000_AI_CTRL_DATA_FIFO;
680 if (cmd->stop_src == TRIG_COUNT) {
681 outl(cmd->chanlist_len * cmd->stop_arg,
682 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
683 ctrl |= ME4000_AI_CTRL_SC_IRQ;
684 } else if (cmd->stop_src == TRIG_NONE &&
685 cmd->scan_end_src == TRIG_COUNT) {
686 outl(cmd->scan_end_arg,
687 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
688 ctrl |= ME4000_AI_CTRL_SC_IRQ;
690 ctrl |= ME4000_AI_CTRL_HF_IRQ;
692 /* Write the setup to the control register */
693 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
695 /* Write the channel list */
696 me4000_ai_write_chanlist(dev, s, cmd);
698 /* Start acquistion by dummy read */
699 inl(dev->iobase + ME4000_AI_START_REG);
704 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
705 struct comedi_subdevice *s,
706 struct comedi_cmd *cmd)
708 struct me4000_private *devpriv = dev->private;
711 /* Step 1 : check if triggers are trivially valid */
713 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
714 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
715 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
716 err |= comedi_check_trigger_src(&cmd->convert_src,
717 TRIG_TIMER | TRIG_EXT);
718 err |= comedi_check_trigger_src(&cmd->scan_end_src,
719 TRIG_NONE | TRIG_COUNT);
720 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
725 /* Step 2a : make sure trigger sources are unique */
727 err |= comedi_check_trigger_is_unique(cmd->start_src);
728 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
729 err |= comedi_check_trigger_is_unique(cmd->convert_src);
730 err |= comedi_check_trigger_is_unique(cmd->scan_end_src);
731 err |= comedi_check_trigger_is_unique(cmd->stop_src);
733 /* Step 2b : and mutually compatible */
735 if (cmd->start_src == TRIG_NOW &&
736 cmd->scan_begin_src == TRIG_TIMER &&
737 cmd->convert_src == TRIG_TIMER) {
738 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
739 } else if (cmd->start_src == TRIG_NOW &&
740 cmd->scan_begin_src == TRIG_FOLLOW &&
741 cmd->convert_src == TRIG_TIMER) {
742 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
743 } else if (cmd->start_src == TRIG_EXT &&
744 cmd->scan_begin_src == TRIG_TIMER &&
745 cmd->convert_src == TRIG_TIMER) {
746 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
747 } else if (cmd->start_src == TRIG_EXT &&
748 cmd->scan_begin_src == TRIG_FOLLOW &&
749 cmd->convert_src == TRIG_TIMER) {
750 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
751 } else if (cmd->start_src == TRIG_EXT &&
752 cmd->scan_begin_src == TRIG_EXT &&
753 cmd->convert_src == TRIG_TIMER) {
754 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2;
755 } else if (cmd->start_src == TRIG_EXT &&
756 cmd->scan_begin_src == TRIG_EXT &&
757 cmd->convert_src == TRIG_EXT) {
758 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 |
759 ME4000_AI_CTRL_MODE_1;
767 /* Step 3: check if arguments are trivially valid */
769 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
771 if (cmd->chanlist_len < 1) {
772 cmd->chanlist_len = 1;
776 /* Round the timer arguments */
777 me4000_ai_round_cmd_args(dev, s, cmd);
779 if (devpriv->ai_init_ticks < 66) {
780 cmd->start_arg = 2000;
783 if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) {
784 cmd->scan_begin_arg = 2031;
787 if (devpriv->ai_chan_ticks < 66) {
788 cmd->convert_arg = 2000;
792 if (cmd->stop_src == TRIG_COUNT)
793 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
795 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
801 * Stage 4. Check for argument conflicts.
803 if (cmd->start_src == TRIG_NOW &&
804 cmd->scan_begin_src == TRIG_TIMER &&
805 cmd->convert_src == TRIG_TIMER) {
806 /* Check timer arguments */
807 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
808 dev_err(dev->class_dev, "Invalid start arg\n");
809 cmd->start_arg = 2000; /* 66 ticks at least */
812 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
813 dev_err(dev->class_dev, "Invalid convert arg\n");
814 cmd->convert_arg = 2000; /* 66 ticks at least */
817 if (devpriv->ai_scan_ticks <=
818 cmd->chanlist_len * devpriv->ai_chan_ticks) {
819 dev_err(dev->class_dev, "Invalid scan end arg\n");
821 /* At least one tick more */
822 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
825 } else if (cmd->start_src == TRIG_NOW &&
826 cmd->scan_begin_src == TRIG_FOLLOW &&
827 cmd->convert_src == TRIG_TIMER) {
828 /* Check timer arguments */
829 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
830 dev_err(dev->class_dev, "Invalid start arg\n");
831 cmd->start_arg = 2000; /* 66 ticks at least */
834 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
835 dev_err(dev->class_dev, "Invalid convert arg\n");
836 cmd->convert_arg = 2000; /* 66 ticks at least */
839 } else if (cmd->start_src == TRIG_EXT &&
840 cmd->scan_begin_src == TRIG_TIMER &&
841 cmd->convert_src == TRIG_TIMER) {
842 /* Check timer arguments */
843 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
844 dev_err(dev->class_dev, "Invalid start arg\n");
845 cmd->start_arg = 2000; /* 66 ticks at least */
848 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
849 dev_err(dev->class_dev, "Invalid convert arg\n");
850 cmd->convert_arg = 2000; /* 66 ticks at least */
853 if (devpriv->ai_scan_ticks <=
854 cmd->chanlist_len * devpriv->ai_chan_ticks) {
855 dev_err(dev->class_dev, "Invalid scan end arg\n");
857 /* At least one tick more */
858 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
861 } else if (cmd->start_src == TRIG_EXT &&
862 cmd->scan_begin_src == TRIG_FOLLOW &&
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 } else if (cmd->start_src == TRIG_EXT &&
876 cmd->scan_begin_src == TRIG_EXT &&
877 cmd->convert_src == TRIG_TIMER) {
878 /* Check timer arguments */
879 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
880 dev_err(dev->class_dev, "Invalid start arg\n");
881 cmd->start_arg = 2000; /* 66 ticks at least */
884 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
885 dev_err(dev->class_dev, "Invalid convert arg\n");
886 cmd->convert_arg = 2000; /* 66 ticks at least */
889 } else if (cmd->start_src == TRIG_EXT &&
890 cmd->scan_begin_src == TRIG_EXT &&
891 cmd->convert_src == TRIG_EXT) {
892 /* Check timer arguments */
893 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
894 dev_err(dev->class_dev, "Invalid start arg\n");
895 cmd->start_arg = 2000; /* 66 ticks at least */
899 if (cmd->scan_end_src == TRIG_COUNT) {
900 if (cmd->scan_end_arg == 0) {
901 dev_err(dev->class_dev, "Invalid scan end arg\n");
902 cmd->scan_end_arg = 1;
910 /* Step 5: check channel list if it exists */
911 if (cmd->chanlist && cmd->chanlist_len > 0)
912 err |= me4000_ai_check_chanlist(dev, s, cmd);
920 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
923 struct comedi_device *dev = dev_id;
924 struct comedi_subdevice *s = dev->read_subdev;
932 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
933 ME4000_IRQ_STATUS_AI_HF) {
934 /* Read status register to find out what happened */
935 tmp = inl(dev->iobase + ME4000_AI_STATUS_REG);
937 if (!(tmp & ME4000_AI_STATUS_FF_DATA) &&
938 !(tmp & ME4000_AI_STATUS_HF_DATA) &&
939 (tmp & ME4000_AI_STATUS_EF_DATA)) {
940 dev_err(dev->class_dev, "FIFO overflow\n");
941 s->async->events |= COMEDI_CB_ERROR;
942 c = ME4000_AI_FIFO_COUNT;
943 } else if ((tmp & ME4000_AI_STATUS_FF_DATA) &&
944 !(tmp & ME4000_AI_STATUS_HF_DATA) &&
945 (tmp & ME4000_AI_STATUS_EF_DATA)) {
946 c = ME4000_AI_FIFO_COUNT / 2;
948 dev_err(dev->class_dev, "Undefined FIFO state\n");
949 s->async->events |= COMEDI_CB_ERROR;
953 for (i = 0; i < c; i++) {
954 lval = me4000_ai_get_sample(dev, s);
955 if (!comedi_buf_write_samples(s, &lval, 1))
959 /* Work is done, so reset the interrupt */
960 tmp |= ME4000_AI_CTRL_HF_IRQ_RESET;
961 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
962 tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET;
963 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
966 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
967 ME4000_IRQ_STATUS_SC) {
968 /* Acquisition is complete */
969 s->async->events |= COMEDI_CB_EOA;
971 /* Poll data until fifo empty */
972 while (inl(dev->iobase + ME4000_AI_STATUS_REG) &
973 ME4000_AI_STATUS_EF_DATA) {
974 lval = me4000_ai_get_sample(dev, s);
975 if (!comedi_buf_write_samples(s, &lval, 1))
979 /* Work is done, so reset the interrupt */
980 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
981 tmp |= ME4000_AI_CTRL_SC_IRQ_RESET;
982 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
983 tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET;
984 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
987 comedi_handle_events(dev, s);
992 static int me4000_ao_insn_write(struct comedi_device *dev,
993 struct comedi_subdevice *s,
994 struct comedi_insn *insn,
997 unsigned int chan = CR_CHAN(insn->chanspec);
1000 /* Stop any running conversion */
1001 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1002 tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP;
1003 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1005 /* Clear control register and set to single mode */
1006 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1008 /* Write data value */
1009 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1011 /* Store in the mirror */
1012 s->readback[chan] = data[0];
1017 static int me4000_dio_insn_bits(struct comedi_device *dev,
1018 struct comedi_subdevice *s,
1019 struct comedi_insn *insn,
1022 if (comedi_dio_update_state(s, data)) {
1023 outl((s->state >> 0) & 0xFF,
1024 dev->iobase + ME4000_DIO_PORT_0_REG);
1025 outl((s->state >> 8) & 0xFF,
1026 dev->iobase + ME4000_DIO_PORT_1_REG);
1027 outl((s->state >> 16) & 0xFF,
1028 dev->iobase + ME4000_DIO_PORT_2_REG);
1029 outl((s->state >> 24) & 0xFF,
1030 dev->iobase + ME4000_DIO_PORT_3_REG);
1033 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1034 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1035 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1036 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1041 static int me4000_dio_insn_config(struct comedi_device *dev,
1042 struct comedi_subdevice *s,
1043 struct comedi_insn *insn,
1046 unsigned int chan = CR_CHAN(insn->chanspec);
1060 ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1064 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1065 tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 |
1066 ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 |
1067 ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 |
1068 ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7);
1069 if (s->io_bits & 0x000000ff)
1070 tmp |= ME4000_DIO_CTRL_MODE_0;
1071 if (s->io_bits & 0x0000ff00)
1072 tmp |= ME4000_DIO_CTRL_MODE_2;
1073 if (s->io_bits & 0x00ff0000)
1074 tmp |= ME4000_DIO_CTRL_MODE_4;
1075 if (s->io_bits & 0xff000000)
1076 tmp |= ME4000_DIO_CTRL_MODE_6;
1079 * Check for optoisolated ME-4000 version.
1080 * If one the first port is a fixed output
1081 * port and the second is a fixed input port.
1083 if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1084 s->io_bits |= 0x000000ff;
1085 s->io_bits &= ~0x0000ff00;
1086 tmp |= ME4000_DIO_CTRL_MODE_0;
1087 tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3);
1090 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1095 static int me4000_auto_attach(struct comedi_device *dev,
1096 unsigned long context)
1098 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1099 const struct me4000_board *board = NULL;
1100 struct me4000_private *devpriv;
1101 struct comedi_subdevice *s;
1104 if (context < ARRAY_SIZE(me4000_boards))
1105 board = &me4000_boards[context];
1108 dev->board_ptr = board;
1109 dev->board_name = board->name;
1111 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1115 result = comedi_pci_enable(dev);
1119 devpriv->plx_regbase = pci_resource_start(pcidev, 1);
1120 dev->iobase = pci_resource_start(pcidev, 2);
1121 if (!devpriv->plx_regbase || !dev->iobase)
1124 result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
1125 me4000_xilinx_download, 0);
1131 if (pcidev->irq > 0) {
1132 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1133 dev->board_name, dev);
1135 dev->irq = pcidev->irq;
1137 /* Enable interrupts on the PLX */
1138 outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL |
1139 PLX9052_INTCSR_PCIENAB,
1140 devpriv->plx_regbase + PLX9052_INTCSR);
1144 result = comedi_alloc_subdevices(dev, 4);
1148 /* Analog Input subdevice */
1149 s = &dev->subdevices[0];
1150 s->type = COMEDI_SUBD_AI;
1151 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
1152 if (board->can_do_diff_ai)
1153 s->subdev_flags |= SDF_DIFF;
1154 s->n_chan = board->ai_nchan;
1155 s->maxdata = 0xffff;
1156 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1157 s->range_table = &me4000_ai_range;
1158 s->insn_read = me4000_ai_insn_read;
1161 dev->read_subdev = s;
1162 s->subdev_flags |= SDF_CMD_READ;
1163 s->cancel = me4000_ai_cancel;
1164 s->do_cmdtest = me4000_ai_do_cmd_test;
1165 s->do_cmd = me4000_ai_do_cmd;
1168 /* Analog Output subdevice */
1169 s = &dev->subdevices[1];
1170 if (board->has_ao) {
1171 s->type = COMEDI_SUBD_AO;
1172 s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND;
1174 s->maxdata = 0xffff;
1175 s->range_table = &range_bipolar10;
1176 s->insn_write = me4000_ao_insn_write;
1178 result = comedi_alloc_subdev_readback(s);
1182 s->type = COMEDI_SUBD_UNUSED;
1185 /* Digital I/O subdevice */
1186 s = &dev->subdevices[2];
1187 s->type = COMEDI_SUBD_DIO;
1188 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1191 s->range_table = &range_digital;
1192 s->insn_bits = me4000_dio_insn_bits;
1193 s->insn_config = me4000_dio_insn_config;
1196 * Check for optoisolated ME-4000 version. If one the first
1197 * port is a fixed output port and the second is a fixed input port.
1199 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1201 outl(ME4000_DIO_CTRL_MODE_0,
1202 dev->iobase + ME4000_DIO_DIR_REG);
1205 /* Counter subdevice (8254) */
1206 s = &dev->subdevices[3];
1207 if (board->has_counter) {
1208 unsigned long timer_base = pci_resource_start(pcidev, 3);
1213 dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0);
1217 comedi_8254_subdevice_init(s, dev->pacer);
1219 s->type = COMEDI_SUBD_UNUSED;
1225 static void me4000_detach(struct comedi_device *dev)
1228 struct me4000_private *devpriv = dev->private;
1230 /* Disable interrupts on the PLX */
1231 outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
1233 comedi_pci_detach(dev);
1236 static struct comedi_driver me4000_driver = {
1237 .driver_name = "me4000",
1238 .module = THIS_MODULE,
1239 .auto_attach = me4000_auto_attach,
1240 .detach = me4000_detach,
1243 static int me4000_pci_probe(struct pci_dev *dev,
1244 const struct pci_device_id *id)
1246 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1249 static const struct pci_device_id me4000_pci_table[] = {
1250 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1251 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1252 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1253 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1254 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1255 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1256 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1257 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1258 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1259 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1260 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1261 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1262 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1265 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1267 static struct pci_driver me4000_pci_driver = {
1269 .id_table = me4000_pci_table,
1270 .probe = me4000_pci_probe,
1271 .remove = comedi_pci_auto_unconfig,
1273 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1275 MODULE_AUTHOR("Comedi https://www.comedi.org");
1276 MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards");
1277 MODULE_LICENSE("GPL");