Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[linux-2.6.git] / drivers / staging / comedi / drivers / me4000.c
blobc2308fd24d6a26445012b5bd5b1ae77738832dbb
1 /*
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.
19 Driver: me4000
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)
26 Supports:
28 - Analog Input
29 - Analog Output
30 - Digital I/O
31 - Counter
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
39 broken.
43 #include <linux/pci.h>
44 #include <linux/delay.h>
45 #include <linux/interrupt.h>
46 #include <linux/list.h>
47 #include <linux/spinlock.h>
49 #include "../comedidev.h"
51 #include "comedi_fc.h"
52 #include "8253.h"
53 #include "plx9052.h"
55 #if 0
56 /* file removed due to GPL incompatibility */
57 #include "me4000_fw.h"
58 #endif
61 * ME4000 Register map and bit defines
63 #define ME4000_AO_CHAN(x) ((x) * 0x18)
65 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
66 #define ME4000_AO_CTRL_BIT_MODE_0 (1 << 0)
67 #define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1)
68 #define ME4000_AO_CTRL_MASK_MODE (3 << 0)
69 #define ME4000_AO_CTRL_BIT_STOP (1 << 2)
70 #define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3)
71 #define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4)
72 #define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5)
73 #define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7)
74 #define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8)
75 #define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9)
76 #define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10)
77 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
78 #define ME4000_AO_STATUS_BIT_FSM (1 << 0)
79 #define ME4000_AO_STATUS_BIT_FF (1 << 1)
80 #define ME4000_AO_STATUS_BIT_HF (1 << 2)
81 #define ME4000_AO_STATUS_BIT_EF (1 << 3)
82 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
83 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
84 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
85 #define ME4000_AI_CTRL_REG 0x74
86 #define ME4000_AI_STATUS_REG 0x74
87 #define ME4000_AI_CTRL_BIT_MODE_0 (1 << 0)
88 #define ME4000_AI_CTRL_BIT_MODE_1 (1 << 1)
89 #define ME4000_AI_CTRL_BIT_MODE_2 (1 << 2)
90 #define ME4000_AI_CTRL_BIT_SAMPLE_HOLD (1 << 3)
91 #define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP (1 << 4)
92 #define ME4000_AI_CTRL_BIT_STOP (1 << 5)
93 #define ME4000_AI_CTRL_BIT_CHANNEL_FIFO (1 << 6)
94 #define ME4000_AI_CTRL_BIT_DATA_FIFO (1 << 7)
95 #define ME4000_AI_CTRL_BIT_FULLSCALE (1 << 8)
96 #define ME4000_AI_CTRL_BIT_OFFSET (1 << 9)
97 #define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG (1 << 10)
98 #define ME4000_AI_CTRL_BIT_EX_TRIG (1 << 11)
99 #define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING (1 << 12)
100 #define ME4000_AI_CTRL_BIT_EX_IRQ (1 << 13)
101 #define ME4000_AI_CTRL_BIT_EX_IRQ_RESET (1 << 14)
102 #define ME4000_AI_CTRL_BIT_LE_IRQ (1 << 15)
103 #define ME4000_AI_CTRL_BIT_LE_IRQ_RESET (1 << 16)
104 #define ME4000_AI_CTRL_BIT_HF_IRQ (1 << 17)
105 #define ME4000_AI_CTRL_BIT_HF_IRQ_RESET (1 << 18)
106 #define ME4000_AI_CTRL_BIT_SC_IRQ (1 << 19)
107 #define ME4000_AI_CTRL_BIT_SC_IRQ_RESET (1 << 20)
108 #define ME4000_AI_CTRL_BIT_SC_RELOAD (1 << 21)
109 #define ME4000_AI_STATUS_BIT_EF_CHANNEL (1 << 22)
110 #define ME4000_AI_STATUS_BIT_HF_CHANNEL (1 << 23)
111 #define ME4000_AI_STATUS_BIT_FF_CHANNEL (1 << 24)
112 #define ME4000_AI_STATUS_BIT_EF_DATA (1 << 25)
113 #define ME4000_AI_STATUS_BIT_HF_DATA (1 << 26)
114 #define ME4000_AI_STATUS_BIT_FF_DATA (1 << 27)
115 #define ME4000_AI_STATUS_BIT_LE (1 << 28)
116 #define ME4000_AI_STATUS_BIT_FSM (1 << 29)
117 #define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH (1 << 31)
118 #define ME4000_AI_CHANNEL_LIST_REG 0x78
119 #define ME4000_AI_LIST_INPUT_SINGLE_ENDED (0 << 5)
120 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL (1 << 5)
121 #define ME4000_AI_LIST_RANGE_BIPOLAR_10 (0 << 6)
122 #define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 (1 << 6)
123 #define ME4000_AI_LIST_RANGE_UNIPOLAR_10 (2 << 6)
124 #define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 (3 << 6)
125 #define ME4000_AI_LIST_LAST_ENTRY (1 << 8)
126 #define ME4000_AI_DATA_REG 0x7c
127 #define ME4000_AI_CHAN_TIMER_REG 0x80
128 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
129 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
130 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
131 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
132 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
133 #define ME4000_AI_START_REG 0x98
134 #define ME4000_IRQ_STATUS_REG 0x9c
135 #define ME4000_IRQ_STATUS_BIT_EX (1 << 0)
136 #define ME4000_IRQ_STATUS_BIT_LE (1 << 1)
137 #define ME4000_IRQ_STATUS_BIT_AI_HF (1 << 2)
138 #define ME4000_IRQ_STATUS_BIT_AO_0_HF (1 << 3)
139 #define ME4000_IRQ_STATUS_BIT_AO_1_HF (1 << 4)
140 #define ME4000_IRQ_STATUS_BIT_AO_2_HF (1 << 5)
141 #define ME4000_IRQ_STATUS_BIT_AO_3_HF (1 << 6)
142 #define ME4000_IRQ_STATUS_BIT_SC (1 << 7)
143 #define ME4000_DIO_PORT_0_REG 0xa0
144 #define ME4000_DIO_PORT_1_REG 0xa4
145 #define ME4000_DIO_PORT_2_REG 0xa8
146 #define ME4000_DIO_PORT_3_REG 0xac
147 #define ME4000_DIO_DIR_REG 0xb0
148 #define ME4000_AO_LOADSETREG_XX 0xb4
149 #define ME4000_DIO_CTRL_REG 0xb8
150 #define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0)
151 #define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1)
152 #define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2)
153 #define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3)
154 #define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4)
155 #define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5)
156 #define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6)
157 #define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7)
158 #define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8)
159 #define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9)
160 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10)
161 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11)
162 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12)
163 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13)
164 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
165 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
166 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
168 #define ME4000_AI_FIFO_COUNT 2048
170 #define ME4000_AI_MIN_TICKS 66
171 #define ME4000_AI_MIN_SAMPLE_TIME 2000
172 #define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
174 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
176 struct me4000_info {
177 unsigned long plx_regbase;
178 unsigned long timer_regbase;
180 unsigned int ao_readback[4];
183 enum me4000_boardid {
184 BOARD_ME4650,
185 BOARD_ME4660,
186 BOARD_ME4660I,
187 BOARD_ME4660S,
188 BOARD_ME4660IS,
189 BOARD_ME4670,
190 BOARD_ME4670I,
191 BOARD_ME4670S,
192 BOARD_ME4670IS,
193 BOARD_ME4680,
194 BOARD_ME4680I,
195 BOARD_ME4680S,
196 BOARD_ME4680IS,
199 struct me4000_board {
200 const char *name;
201 int ao_nchan;
202 int ao_fifo;
203 int ai_nchan;
204 int ai_diff_nchan;
205 int ai_sh_nchan;
206 int ex_trig_analog;
207 int dio_nchan;
208 int has_counter;
211 static const struct me4000_board me4000_boards[] = {
212 [BOARD_ME4650] = {
213 .name = "ME-4650",
214 .ai_nchan = 16,
215 .dio_nchan = 32,
217 [BOARD_ME4660] = {
218 .name = "ME-4660",
219 .ai_nchan = 32,
220 .ai_diff_nchan = 16,
221 .dio_nchan = 32,
222 .has_counter = 1,
224 [BOARD_ME4660I] = {
225 .name = "ME-4660i",
226 .ai_nchan = 32,
227 .ai_diff_nchan = 16,
228 .dio_nchan = 32,
229 .has_counter = 1,
231 [BOARD_ME4660S] = {
232 .name = "ME-4660s",
233 .ai_nchan = 32,
234 .ai_diff_nchan = 16,
235 .ai_sh_nchan = 8,
236 .dio_nchan = 32,
237 .has_counter = 1,
239 [BOARD_ME4660IS] = {
240 .name = "ME-4660is",
241 .ai_nchan = 32,
242 .ai_diff_nchan = 16,
243 .ai_sh_nchan = 8,
244 .dio_nchan = 32,
245 .has_counter = 1,
247 [BOARD_ME4670] = {
248 .name = "ME-4670",
249 .ao_nchan = 4,
250 .ai_nchan = 32,
251 .ai_diff_nchan = 16,
252 .ex_trig_analog = 1,
253 .dio_nchan = 32,
254 .has_counter = 1,
256 [BOARD_ME4670I] = {
257 .name = "ME-4670i",
258 .ao_nchan = 4,
259 .ai_nchan = 32,
260 .ai_diff_nchan = 16,
261 .ex_trig_analog = 1,
262 .dio_nchan = 32,
263 .has_counter = 1,
265 [BOARD_ME4670S] = {
266 .name = "ME-4670s",
267 .ao_nchan = 4,
268 .ai_nchan = 32,
269 .ai_diff_nchan = 16,
270 .ai_sh_nchan = 8,
271 .ex_trig_analog = 1,
272 .dio_nchan = 32,
273 .has_counter = 1,
275 [BOARD_ME4670IS] = {
276 .name = "ME-4670is",
277 .ao_nchan = 4,
278 .ai_nchan = 32,
279 .ai_diff_nchan = 16,
280 .ai_sh_nchan = 8,
281 .ex_trig_analog = 1,
282 .dio_nchan = 32,
283 .has_counter = 1,
285 [BOARD_ME4680] = {
286 .name = "ME-4680",
287 .ao_nchan = 4,
288 .ao_fifo = 4,
289 .ai_nchan = 32,
290 .ai_diff_nchan = 16,
291 .ex_trig_analog = 1,
292 .dio_nchan = 32,
293 .has_counter = 1,
295 [BOARD_ME4680I] = {
296 .name = "ME-4680i",
297 .ao_nchan = 4,
298 .ao_fifo = 4,
299 .ai_nchan = 32,
300 .ai_diff_nchan = 16,
301 .ex_trig_analog = 1,
302 .dio_nchan = 32,
303 .has_counter = 1,
305 [BOARD_ME4680S] = {
306 .name = "ME-4680s",
307 .ao_nchan = 4,
308 .ao_fifo = 4,
309 .ai_nchan = 32,
310 .ai_diff_nchan = 16,
311 .ai_sh_nchan = 8,
312 .ex_trig_analog = 1,
313 .dio_nchan = 32,
314 .has_counter = 1,
316 [BOARD_ME4680IS] = {
317 .name = "ME-4680is",
318 .ao_nchan = 4,
319 .ao_fifo = 4,
320 .ai_nchan = 32,
321 .ai_diff_nchan = 16,
322 .ai_sh_nchan = 8,
323 .ex_trig_analog = 1,
324 .dio_nchan = 32,
325 .has_counter = 1,
329 static const struct comedi_lrange me4000_ai_range = {
332 UNI_RANGE(2.5),
333 UNI_RANGE(10),
334 BIP_RANGE(2.5),
335 BIP_RANGE(10),
339 #define FIRMWARE_NOT_AVAILABLE 1
340 #if FIRMWARE_NOT_AVAILABLE
341 extern unsigned char *xilinx_firm;
342 #endif
344 static int xilinx_download(struct comedi_device *dev)
346 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
347 struct me4000_info *info = dev->private;
348 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
349 u32 value = 0;
350 wait_queue_head_t queue;
351 int idx = 0;
352 int size = 0;
353 unsigned int intcsr;
355 if (!xilinx_iobase)
356 return -ENODEV;
358 init_waitqueue_head(&queue);
361 * Set PLX local interrupt 2 polarity to high.
362 * Interrupt is thrown by init pin of xilinx.
364 outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
366 /* Set /CS and /WRITE of the Xilinx */
367 value = inl(info->plx_regbase + PLX9052_CNTRL);
368 value |= PLX9052_CNTRL_UIO2_DATA;
369 outl(value, info->plx_regbase + PLX9052_CNTRL);
371 /* Init Xilinx with CS1 */
372 inb(xilinx_iobase + 0xC8);
374 /* Wait until /INIT pin is set */
375 udelay(20);
376 intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
377 if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
378 dev_err(dev->class_dev, "Can't init Xilinx\n");
379 return -EIO;
382 /* Reset /CS and /WRITE of the Xilinx */
383 value = inl(info->plx_regbase + PLX9052_CNTRL);
384 value &= ~PLX9052_CNTRL_UIO2_DATA;
385 outl(value, info->plx_regbase + PLX9052_CNTRL);
386 if (FIRMWARE_NOT_AVAILABLE) {
387 dev_err(dev->class_dev,
388 "xilinx firmware unavailable due to licensing, aborting");
389 return -EIO;
390 } else {
391 /* Download Xilinx firmware */
392 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
393 (xilinx_firm[2] << 8) + xilinx_firm[3];
394 udelay(10);
396 for (idx = 0; idx < size; idx++) {
397 outb(xilinx_firm[16 + idx], xilinx_iobase);
398 udelay(10);
400 /* Check if BUSY flag is low */
401 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
402 dev_err(dev->class_dev,
403 "Xilinx is still busy (idx = %d)\n",
404 idx);
405 return -EIO;
410 /* If done flag is high download was successful */
411 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
412 } else {
413 dev_err(dev->class_dev, "DONE flag is not set\n");
414 dev_err(dev->class_dev, "Download not successful\n");
415 return -EIO;
418 /* Set /CS and /WRITE */
419 value = inl(info->plx_regbase + PLX9052_CNTRL);
420 value |= PLX9052_CNTRL_UIO2_DATA;
421 outl(value, info->plx_regbase + PLX9052_CNTRL);
423 return 0;
426 static void me4000_reset(struct comedi_device *dev)
428 struct me4000_info *info = dev->private;
429 unsigned long val;
430 int chan;
432 /* Make a hardware reset */
433 val = inl(info->plx_regbase + PLX9052_CNTRL);
434 val |= PLX9052_CNTRL_PCI_RESET;
435 outl(val, info->plx_regbase + PLX9052_CNTRL);
436 val &= ~PLX9052_CNTRL_PCI_RESET;
437 outl(val , info->plx_regbase + PLX9052_CNTRL);
439 /* 0x8000 to the DACs means an output voltage of 0V */
440 for (chan = 0; chan < 4; chan++)
441 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
443 /* Set both stop bits in the analog input control register */
444 outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
445 dev->iobase + ME4000_AI_CTRL_REG);
447 /* Set both stop bits in the analog output control register */
448 val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
449 for (chan = 0; chan < 4; chan++)
450 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
452 /* Enable interrupts on the PLX */
453 outl(PLX9052_INTCSR_LI1ENAB |
454 PLX9052_INTCSR_LI1POL |
455 PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
457 /* Set the adustment register for AO demux */
458 outl(ME4000_AO_DEMUX_ADJUST_VALUE,
459 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
462 * Set digital I/O direction for port 0
463 * to output on isolated versions
465 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
466 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
469 /*=============================================================================
470 Analog input section
471 ===========================================================================*/
473 static int me4000_ai_insn_read(struct comedi_device *dev,
474 struct comedi_subdevice *subdevice,
475 struct comedi_insn *insn, unsigned int *data)
477 const struct me4000_board *thisboard = comedi_board(dev);
478 int chan = CR_CHAN(insn->chanspec);
479 int rang = CR_RANGE(insn->chanspec);
480 int aref = CR_AREF(insn->chanspec);
482 unsigned long entry = 0;
483 unsigned long tmp;
484 long lval;
486 if (insn->n == 0) {
487 return 0;
488 } else if (insn->n > 1) {
489 dev_err(dev->class_dev, "Invalid instruction length %d\n",
490 insn->n);
491 return -EINVAL;
494 switch (rang) {
495 case 0:
496 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
497 break;
498 case 1:
499 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
500 break;
501 case 2:
502 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
503 break;
504 case 3:
505 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
506 break;
507 default:
508 dev_err(dev->class_dev, "Invalid range specified\n");
509 return -EINVAL;
512 switch (aref) {
513 case AREF_GROUND:
514 case AREF_COMMON:
515 if (chan >= thisboard->ai_nchan) {
516 dev_err(dev->class_dev,
517 "Analog input is not available\n");
518 return -EINVAL;
520 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
521 break;
523 case AREF_DIFF:
524 if (rang == 0 || rang == 1) {
525 dev_err(dev->class_dev,
526 "Range must be bipolar when aref = diff\n");
527 return -EINVAL;
530 if (chan >= thisboard->ai_diff_nchan) {
531 dev_err(dev->class_dev,
532 "Analog input is not available\n");
533 return -EINVAL;
535 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
536 break;
537 default:
538 dev_err(dev->class_dev, "Invalid aref specified\n");
539 return -EINVAL;
542 entry |= ME4000_AI_LIST_LAST_ENTRY;
544 /* Clear channel list, data fifo and both stop bits */
545 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
546 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
547 ME4000_AI_CTRL_BIT_DATA_FIFO |
548 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
549 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
551 /* Set the acquisition mode to single */
552 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
553 ME4000_AI_CTRL_BIT_MODE_2);
554 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
556 /* Enable channel list and data fifo */
557 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
558 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
560 /* Generate channel list entry */
561 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
563 /* Set the timer to maximum sample rate */
564 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
565 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
567 /* Start conversion by dummy read */
568 inl(dev->iobase + ME4000_AI_START_REG);
570 /* Wait until ready */
571 udelay(10);
572 if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
573 ME4000_AI_STATUS_BIT_EF_DATA)) {
574 dev_err(dev->class_dev, "Value not available after wait\n");
575 return -EIO;
578 /* Read value from data fifo */
579 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
580 data[0] = lval ^ 0x8000;
582 return 1;
585 static int me4000_ai_cancel(struct comedi_device *dev,
586 struct comedi_subdevice *s)
588 unsigned long tmp;
590 /* Stop any running conversion */
591 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
592 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
593 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
595 /* Clear the control register */
596 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
598 return 0;
601 static int ai_check_chanlist(struct comedi_device *dev,
602 struct comedi_subdevice *s, struct comedi_cmd *cmd)
604 const struct me4000_board *thisboard = comedi_board(dev);
605 int aref;
606 int i;
608 /* Check whether a channel list is available */
609 if (!cmd->chanlist_len) {
610 dev_err(dev->class_dev, "No channel list available\n");
611 return -EINVAL;
614 /* Check the channel list size */
615 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
616 dev_err(dev->class_dev, "Channel list is to large\n");
617 return -EINVAL;
620 /* Check the pointer */
621 if (!cmd->chanlist) {
622 dev_err(dev->class_dev, "NULL pointer to channel list\n");
623 return -EFAULT;
626 /* Check whether aref is equal for all entries */
627 aref = CR_AREF(cmd->chanlist[0]);
628 for (i = 0; i < cmd->chanlist_len; i++) {
629 if (CR_AREF(cmd->chanlist[i]) != aref) {
630 dev_err(dev->class_dev,
631 "Mode is not equal for all entries\n");
632 return -EINVAL;
636 /* Check whether channels are available for this ending */
637 if (aref == SDF_DIFF) {
638 for (i = 0; i < cmd->chanlist_len; i++) {
639 if (CR_CHAN(cmd->chanlist[i]) >=
640 thisboard->ai_diff_nchan) {
641 dev_err(dev->class_dev,
642 "Channel number to high\n");
643 return -EINVAL;
646 } else {
647 for (i = 0; i < cmd->chanlist_len; i++) {
648 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
649 dev_err(dev->class_dev,
650 "Channel number to high\n");
651 return -EINVAL;
656 /* Check if bipolar is set for all entries when in differential mode */
657 if (aref == SDF_DIFF) {
658 for (i = 0; i < cmd->chanlist_len; i++) {
659 if (CR_RANGE(cmd->chanlist[i]) != 1 &&
660 CR_RANGE(cmd->chanlist[i]) != 2) {
661 dev_err(dev->class_dev,
662 "Bipolar is not selected in differential mode\n");
663 return -EINVAL;
668 return 0;
671 static int ai_round_cmd_args(struct comedi_device *dev,
672 struct comedi_subdevice *s,
673 struct comedi_cmd *cmd,
674 unsigned int *init_ticks,
675 unsigned int *scan_ticks, unsigned int *chan_ticks)
678 int rest;
680 *init_ticks = 0;
681 *scan_ticks = 0;
682 *chan_ticks = 0;
684 if (cmd->start_arg) {
685 *init_ticks = (cmd->start_arg * 33) / 1000;
686 rest = (cmd->start_arg * 33) % 1000;
688 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
689 if (rest > 33)
690 (*init_ticks)++;
691 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
692 if (rest)
693 (*init_ticks)++;
697 if (cmd->scan_begin_arg) {
698 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
699 rest = (cmd->scan_begin_arg * 33) % 1000;
701 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
702 if (rest > 33)
703 (*scan_ticks)++;
704 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
705 if (rest)
706 (*scan_ticks)++;
710 if (cmd->convert_arg) {
711 *chan_ticks = (cmd->convert_arg * 33) / 1000;
712 rest = (cmd->convert_arg * 33) % 1000;
714 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
715 if (rest > 33)
716 (*chan_ticks)++;
717 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
718 if (rest)
719 (*chan_ticks)++;
723 return 0;
726 static void ai_write_timer(struct comedi_device *dev,
727 unsigned int init_ticks,
728 unsigned int scan_ticks, unsigned int chan_ticks)
730 outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
731 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
733 if (scan_ticks) {
734 outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
735 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
738 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
739 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
742 static int ai_write_chanlist(struct comedi_device *dev,
743 struct comedi_subdevice *s, struct comedi_cmd *cmd)
745 unsigned int entry;
746 unsigned int chan;
747 unsigned int rang;
748 unsigned int aref;
749 int i;
751 for (i = 0; i < cmd->chanlist_len; i++) {
752 chan = CR_CHAN(cmd->chanlist[i]);
753 rang = CR_RANGE(cmd->chanlist[i]);
754 aref = CR_AREF(cmd->chanlist[i]);
756 entry = chan;
758 if (rang == 0)
759 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
760 else if (rang == 1)
761 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
762 else if (rang == 2)
763 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
764 else
765 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
767 if (aref == SDF_DIFF)
768 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
769 else
770 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
772 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
775 return 0;
778 static int ai_prepare(struct comedi_device *dev,
779 struct comedi_subdevice *s,
780 struct comedi_cmd *cmd,
781 unsigned int init_ticks,
782 unsigned int scan_ticks, unsigned int chan_ticks)
785 unsigned long tmp = 0;
787 /* Write timer arguments */
788 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
790 /* Reset control register */
791 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
793 /* Start sources */
794 if ((cmd->start_src == TRIG_EXT &&
795 cmd->scan_begin_src == TRIG_TIMER &&
796 cmd->convert_src == TRIG_TIMER) ||
797 (cmd->start_src == TRIG_EXT &&
798 cmd->scan_begin_src == TRIG_FOLLOW &&
799 cmd->convert_src == TRIG_TIMER)) {
800 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
801 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
802 ME4000_AI_CTRL_BIT_DATA_FIFO;
803 } else if (cmd->start_src == TRIG_EXT &&
804 cmd->scan_begin_src == TRIG_EXT &&
805 cmd->convert_src == TRIG_TIMER) {
806 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
807 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
808 ME4000_AI_CTRL_BIT_DATA_FIFO;
809 } else if (cmd->start_src == TRIG_EXT &&
810 cmd->scan_begin_src == TRIG_EXT &&
811 cmd->convert_src == TRIG_EXT) {
812 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
813 ME4000_AI_CTRL_BIT_MODE_1 |
814 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
815 ME4000_AI_CTRL_BIT_DATA_FIFO;
816 } else {
817 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
818 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
819 ME4000_AI_CTRL_BIT_DATA_FIFO;
822 /* Stop triggers */
823 if (cmd->stop_src == TRIG_COUNT) {
824 outl(cmd->chanlist_len * cmd->stop_arg,
825 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
826 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
827 } else if (cmd->stop_src == TRIG_NONE &&
828 cmd->scan_end_src == TRIG_COUNT) {
829 outl(cmd->scan_end_arg,
830 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
831 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
832 } else {
833 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
836 /* Write the setup to the control register */
837 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
839 /* Write the channel list */
840 ai_write_chanlist(dev, s, cmd);
842 return 0;
845 static int me4000_ai_do_cmd(struct comedi_device *dev,
846 struct comedi_subdevice *s)
848 int err;
849 unsigned int init_ticks = 0;
850 unsigned int scan_ticks = 0;
851 unsigned int chan_ticks = 0;
852 struct comedi_cmd *cmd = &s->async->cmd;
854 /* Reset the analog input */
855 err = me4000_ai_cancel(dev, s);
856 if (err)
857 return err;
859 /* Round the timer arguments */
860 err = ai_round_cmd_args(dev,
861 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
862 if (err)
863 return err;
865 /* Prepare the AI for acquisition */
866 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
867 if (err)
868 return err;
870 /* Start acquistion by dummy read */
871 inl(dev->iobase + ME4000_AI_START_REG);
873 return 0;
876 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
877 struct comedi_subdevice *s,
878 struct comedi_cmd *cmd)
881 unsigned int init_ticks;
882 unsigned int chan_ticks;
883 unsigned int scan_ticks;
884 int err = 0;
886 /* Only rounding flags are implemented */
887 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
889 /* Round the timer arguments */
890 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
892 /* Step 1 : check if triggers are trivially valid */
894 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
895 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
896 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
897 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
898 err |= cfc_check_trigger_src(&cmd->scan_end_src,
899 TRIG_NONE | TRIG_COUNT);
900 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
902 if (err)
903 return 1;
905 /* Step 2a : make sure trigger sources are unique */
907 err |= cfc_check_trigger_is_unique(cmd->start_src);
908 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
909 err |= cfc_check_trigger_is_unique(cmd->convert_src);
910 err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
911 err |= cfc_check_trigger_is_unique(cmd->stop_src);
913 /* Step 2b : and mutually compatible */
915 if (cmd->start_src == TRIG_NOW &&
916 cmd->scan_begin_src == TRIG_TIMER &&
917 cmd->convert_src == TRIG_TIMER) {
918 } else if (cmd->start_src == TRIG_NOW &&
919 cmd->scan_begin_src == TRIG_FOLLOW &&
920 cmd->convert_src == TRIG_TIMER) {
921 } else if (cmd->start_src == TRIG_EXT &&
922 cmd->scan_begin_src == TRIG_TIMER &&
923 cmd->convert_src == TRIG_TIMER) {
924 } else if (cmd->start_src == TRIG_EXT &&
925 cmd->scan_begin_src == TRIG_FOLLOW &&
926 cmd->convert_src == TRIG_TIMER) {
927 } else if (cmd->start_src == TRIG_EXT &&
928 cmd->scan_begin_src == TRIG_EXT &&
929 cmd->convert_src == TRIG_TIMER) {
930 } else if (cmd->start_src == TRIG_EXT &&
931 cmd->scan_begin_src == TRIG_EXT &&
932 cmd->convert_src == TRIG_EXT) {
933 } else {
934 err |= -EINVAL;
937 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
938 } else if (cmd->stop_src == TRIG_COUNT &&
939 cmd->scan_end_src == TRIG_NONE) {
940 } else if (cmd->stop_src == TRIG_NONE &&
941 cmd->scan_end_src == TRIG_COUNT) {
942 } else if (cmd->stop_src == TRIG_COUNT &&
943 cmd->scan_end_src == TRIG_COUNT) {
944 } else {
945 err |= -EINVAL;
948 if (err)
949 return 2;
951 /* Step 3: check if arguments are trivially valid */
953 if (cmd->chanlist_len < 1) {
954 cmd->chanlist_len = 1;
955 err |= -EINVAL;
957 if (init_ticks < 66) {
958 cmd->start_arg = 2000;
959 err |= -EINVAL;
961 if (scan_ticks && scan_ticks < 67) {
962 cmd->scan_begin_arg = 2031;
963 err |= -EINVAL;
965 if (chan_ticks < 66) {
966 cmd->convert_arg = 2000;
967 err |= -EINVAL;
970 if (err)
971 return 3;
974 * Stage 4. Check for argument conflicts.
976 if (cmd->start_src == TRIG_NOW &&
977 cmd->scan_begin_src == TRIG_TIMER &&
978 cmd->convert_src == TRIG_TIMER) {
980 /* Check timer arguments */
981 if (init_ticks < ME4000_AI_MIN_TICKS) {
982 dev_err(dev->class_dev, "Invalid start arg\n");
983 cmd->start_arg = 2000; /* 66 ticks at least */
984 err++;
986 if (chan_ticks < ME4000_AI_MIN_TICKS) {
987 dev_err(dev->class_dev, "Invalid convert arg\n");
988 cmd->convert_arg = 2000; /* 66 ticks at least */
989 err++;
991 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
992 dev_err(dev->class_dev, "Invalid scan end arg\n");
994 /* At least one tick more */
995 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
996 err++;
998 } else if (cmd->start_src == TRIG_NOW &&
999 cmd->scan_begin_src == TRIG_FOLLOW &&
1000 cmd->convert_src == TRIG_TIMER) {
1002 /* Check timer arguments */
1003 if (init_ticks < ME4000_AI_MIN_TICKS) {
1004 dev_err(dev->class_dev, "Invalid start arg\n");
1005 cmd->start_arg = 2000; /* 66 ticks at least */
1006 err++;
1008 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1009 dev_err(dev->class_dev, "Invalid convert arg\n");
1010 cmd->convert_arg = 2000; /* 66 ticks at least */
1011 err++;
1013 } else if (cmd->start_src == TRIG_EXT &&
1014 cmd->scan_begin_src == TRIG_TIMER &&
1015 cmd->convert_src == TRIG_TIMER) {
1017 /* Check timer arguments */
1018 if (init_ticks < ME4000_AI_MIN_TICKS) {
1019 dev_err(dev->class_dev, "Invalid start arg\n");
1020 cmd->start_arg = 2000; /* 66 ticks at least */
1021 err++;
1023 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1024 dev_err(dev->class_dev, "Invalid convert arg\n");
1025 cmd->convert_arg = 2000; /* 66 ticks at least */
1026 err++;
1028 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1029 dev_err(dev->class_dev, "Invalid scan end arg\n");
1031 /* At least one tick more */
1032 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1033 err++;
1035 } else if (cmd->start_src == TRIG_EXT &&
1036 cmd->scan_begin_src == TRIG_FOLLOW &&
1037 cmd->convert_src == TRIG_TIMER) {
1039 /* Check timer arguments */
1040 if (init_ticks < ME4000_AI_MIN_TICKS) {
1041 dev_err(dev->class_dev, "Invalid start arg\n");
1042 cmd->start_arg = 2000; /* 66 ticks at least */
1043 err++;
1045 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1046 dev_err(dev->class_dev, "Invalid convert arg\n");
1047 cmd->convert_arg = 2000; /* 66 ticks at least */
1048 err++;
1050 } else if (cmd->start_src == TRIG_EXT &&
1051 cmd->scan_begin_src == TRIG_EXT &&
1052 cmd->convert_src == TRIG_TIMER) {
1054 /* Check timer arguments */
1055 if (init_ticks < ME4000_AI_MIN_TICKS) {
1056 dev_err(dev->class_dev, "Invalid start arg\n");
1057 cmd->start_arg = 2000; /* 66 ticks at least */
1058 err++;
1060 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1061 dev_err(dev->class_dev, "Invalid convert arg\n");
1062 cmd->convert_arg = 2000; /* 66 ticks at least */
1063 err++;
1065 } else if (cmd->start_src == TRIG_EXT &&
1066 cmd->scan_begin_src == TRIG_EXT &&
1067 cmd->convert_src == TRIG_EXT) {
1069 /* Check timer arguments */
1070 if (init_ticks < ME4000_AI_MIN_TICKS) {
1071 dev_err(dev->class_dev, "Invalid start arg\n");
1072 cmd->start_arg = 2000; /* 66 ticks at least */
1073 err++;
1076 if (cmd->stop_src == TRIG_COUNT) {
1077 if (cmd->stop_arg == 0) {
1078 dev_err(dev->class_dev, "Invalid stop arg\n");
1079 cmd->stop_arg = 1;
1080 err++;
1083 if (cmd->scan_end_src == TRIG_COUNT) {
1084 if (cmd->scan_end_arg == 0) {
1085 dev_err(dev->class_dev, "Invalid scan end arg\n");
1086 cmd->scan_end_arg = 1;
1087 err++;
1091 if (err)
1092 return 4;
1095 * Stage 5. Check the channel list.
1097 if (ai_check_chanlist(dev, s, cmd))
1098 return 5;
1100 return 0;
1103 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1105 unsigned int tmp;
1106 struct comedi_device *dev = dev_id;
1107 struct comedi_subdevice *s = &dev->subdevices[0];
1108 int i;
1109 int c = 0;
1110 long lval;
1112 if (!dev->attached)
1113 return IRQ_NONE;
1115 /* Reset all events */
1116 s->async->events = 0;
1118 /* Check if irq number is right */
1119 if (irq != dev->irq) {
1120 dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq);
1121 return IRQ_HANDLED;
1124 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1125 ME4000_IRQ_STATUS_BIT_AI_HF) {
1126 /* Read status register to find out what happened */
1127 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1129 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1130 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1131 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1132 c = ME4000_AI_FIFO_COUNT;
1135 * FIFO overflow, so stop conversion
1136 * and disable all interrupts
1138 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1139 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1140 ME4000_AI_CTRL_BIT_SC_IRQ);
1141 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1143 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1145 dev_err(dev->class_dev, "FIFO overflow\n");
1146 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1147 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1148 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1149 s->async->events |= COMEDI_CB_BLOCK;
1151 c = ME4000_AI_FIFO_COUNT / 2;
1152 } else {
1153 dev_err(dev->class_dev,
1154 "Can't determine state of fifo\n");
1155 c = 0;
1158 * Undefined state, so stop conversion
1159 * and disable all interrupts
1161 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1162 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1163 ME4000_AI_CTRL_BIT_SC_IRQ);
1164 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1166 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1168 dev_err(dev->class_dev, "Undefined FIFO state\n");
1171 for (i = 0; i < c; i++) {
1172 /* Read value from data fifo */
1173 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1174 lval ^= 0x8000;
1176 if (!comedi_buf_put(s->async, lval)) {
1178 * Buffer overflow, so stop conversion
1179 * and disable all interrupts
1181 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1182 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1183 ME4000_AI_CTRL_BIT_SC_IRQ);
1184 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1186 s->async->events |= COMEDI_CB_OVERFLOW;
1188 dev_err(dev->class_dev, "Buffer overflow\n");
1190 break;
1194 /* Work is done, so reset the interrupt */
1195 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1196 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1197 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1198 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1201 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1202 ME4000_IRQ_STATUS_BIT_SC) {
1203 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1206 * Acquisition is complete, so stop
1207 * conversion and disable all interrupts
1209 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1210 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1211 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1212 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1214 /* Poll data until fifo empty */
1215 while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1216 ME4000_AI_STATUS_BIT_EF_DATA) {
1217 /* Read value from data fifo */
1218 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1219 lval ^= 0x8000;
1221 if (!comedi_buf_put(s->async, lval)) {
1222 dev_err(dev->class_dev, "Buffer overflow\n");
1223 s->async->events |= COMEDI_CB_OVERFLOW;
1224 break;
1228 /* Work is done, so reset the interrupt */
1229 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1230 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1231 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1232 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1235 if (s->async->events)
1236 comedi_event(dev, s);
1238 return IRQ_HANDLED;
1241 /*=============================================================================
1242 Analog output section
1243 ===========================================================================*/
1245 static int me4000_ao_insn_write(struct comedi_device *dev,
1246 struct comedi_subdevice *s,
1247 struct comedi_insn *insn, unsigned int *data)
1249 const struct me4000_board *thisboard = comedi_board(dev);
1250 struct me4000_info *info = dev->private;
1251 int chan = CR_CHAN(insn->chanspec);
1252 int rang = CR_RANGE(insn->chanspec);
1253 int aref = CR_AREF(insn->chanspec);
1254 unsigned long tmp;
1256 if (insn->n == 0) {
1257 return 0;
1258 } else if (insn->n > 1) {
1259 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1260 insn->n);
1261 return -EINVAL;
1264 if (chan >= thisboard->ao_nchan) {
1265 dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
1266 return -EINVAL;
1269 if (rang != 0) {
1270 dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
1271 return -EINVAL;
1274 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1275 dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
1276 return -EINVAL;
1279 /* Stop any running conversion */
1280 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1281 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1282 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1284 /* Clear control register and set to single mode */
1285 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1287 /* Write data value */
1288 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1290 /* Store in the mirror */
1291 info->ao_readback[chan] = data[0];
1293 return 1;
1296 static int me4000_ao_insn_read(struct comedi_device *dev,
1297 struct comedi_subdevice *s,
1298 struct comedi_insn *insn, unsigned int *data)
1300 struct me4000_info *info = dev->private;
1301 int chan = CR_CHAN(insn->chanspec);
1303 if (insn->n == 0) {
1304 return 0;
1305 } else if (insn->n > 1) {
1306 dev_err(dev->class_dev, "Invalid instruction length\n");
1307 return -EINVAL;
1310 data[0] = info->ao_readback[chan];
1312 return 1;
1315 /*=============================================================================
1316 Digital I/O section
1317 ===========================================================================*/
1319 static int me4000_dio_insn_bits(struct comedi_device *dev,
1320 struct comedi_subdevice *s,
1321 struct comedi_insn *insn, unsigned int *data)
1324 * The insn data consists of a mask in data[0] and the new data
1325 * in data[1]. The mask defines which bits we are concerning about.
1326 * The new data must be anded with the mask.
1327 * Each channel corresponds to a bit.
1329 if (data[0]) {
1330 /* Check if requested ports are configured for output */
1331 if ((s->io_bits & data[0]) != data[0])
1332 return -EIO;
1334 s->state &= ~data[0];
1335 s->state |= data[0] & data[1];
1337 /* Write out the new digital output lines */
1338 outl((s->state >> 0) & 0xFF,
1339 dev->iobase + ME4000_DIO_PORT_0_REG);
1340 outl((s->state >> 8) & 0xFF,
1341 dev->iobase + ME4000_DIO_PORT_1_REG);
1342 outl((s->state >> 16) & 0xFF,
1343 dev->iobase + ME4000_DIO_PORT_2_REG);
1344 outl((s->state >> 24) & 0xFF,
1345 dev->iobase + ME4000_DIO_PORT_3_REG);
1348 /* On return, data[1] contains the value of
1349 the digital input and output lines. */
1350 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1351 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1352 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1353 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1355 return insn->n;
1358 static int me4000_dio_insn_config(struct comedi_device *dev,
1359 struct comedi_subdevice *s,
1360 struct comedi_insn *insn, unsigned int *data)
1362 unsigned long tmp;
1363 int chan = CR_CHAN(insn->chanspec);
1365 switch (data[0]) {
1366 default:
1367 return -EINVAL;
1368 case INSN_CONFIG_DIO_QUERY:
1369 data[1] =
1370 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1371 return insn->n;
1372 case INSN_CONFIG_DIO_INPUT:
1373 case INSN_CONFIG_DIO_OUTPUT:
1374 break;
1378 * The input or output configuration of each digital line is
1379 * configured by a special insn_config instruction. chanspec
1380 * contains the channel to be changed, and data[0] contains the
1381 * value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
1382 * On the ME-4000 it is only possible to switch port wise (8 bit)
1385 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1387 if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
1388 if (chan < 8) {
1389 s->io_bits |= 0xFF;
1390 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1391 ME4000_DIO_CTRL_BIT_MODE_1);
1392 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1393 } else if (chan < 16) {
1395 * Chech for optoisolated ME-4000 version.
1396 * If one the first port is a fixed output
1397 * port and the second is a fixed input port.
1399 if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1400 return -ENODEV;
1402 s->io_bits |= 0xFF00;
1403 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1404 ME4000_DIO_CTRL_BIT_MODE_3);
1405 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1406 } else if (chan < 24) {
1407 s->io_bits |= 0xFF0000;
1408 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1409 ME4000_DIO_CTRL_BIT_MODE_5);
1410 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1411 } else if (chan < 32) {
1412 s->io_bits |= 0xFF000000;
1413 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1414 ME4000_DIO_CTRL_BIT_MODE_7);
1415 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1416 } else {
1417 return -EINVAL;
1419 } else {
1420 if (chan < 8) {
1422 * Chech for optoisolated ME-4000 version.
1423 * If one the first port is a fixed output
1424 * port and the second is a fixed input port.
1426 if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1427 return -ENODEV;
1429 s->io_bits &= ~0xFF;
1430 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1431 ME4000_DIO_CTRL_BIT_MODE_1);
1432 } else if (chan < 16) {
1433 s->io_bits &= ~0xFF00;
1434 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1435 ME4000_DIO_CTRL_BIT_MODE_3);
1436 } else if (chan < 24) {
1437 s->io_bits &= ~0xFF0000;
1438 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1439 ME4000_DIO_CTRL_BIT_MODE_5);
1440 } else if (chan < 32) {
1441 s->io_bits &= ~0xFF000000;
1442 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1443 ME4000_DIO_CTRL_BIT_MODE_7);
1444 } else {
1445 return -EINVAL;
1449 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1451 return 1;
1454 /*=============================================================================
1455 Counter section
1456 ===========================================================================*/
1458 static int me4000_cnt_insn_config(struct comedi_device *dev,
1459 struct comedi_subdevice *s,
1460 struct comedi_insn *insn,
1461 unsigned int *data)
1463 struct me4000_info *info = dev->private;
1464 int err;
1466 switch (data[0]) {
1467 case GPCT_RESET:
1468 if (insn->n != 1)
1469 return -EINVAL;
1471 err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0,
1472 I8254_MODE0 | I8254_BINARY);
1473 if (err)
1474 return err;
1475 break;
1476 case GPCT_SET_OPERATION:
1477 if (insn->n != 2)
1478 return -EINVAL;
1480 err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec,
1481 (data[1] << 1) | I8254_BINARY);
1482 if (err)
1483 return err;
1484 break;
1485 default:
1486 return -EINVAL;
1489 return insn->n;
1492 static int me4000_cnt_insn_read(struct comedi_device *dev,
1493 struct comedi_subdevice *s,
1494 struct comedi_insn *insn, unsigned int *data)
1496 struct me4000_info *info = dev->private;
1498 if (insn->n == 0)
1499 return 0;
1501 if (insn->n > 1) {
1502 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1503 insn->n);
1504 return -EINVAL;
1507 data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
1509 return 1;
1512 static int me4000_cnt_insn_write(struct comedi_device *dev,
1513 struct comedi_subdevice *s,
1514 struct comedi_insn *insn, unsigned int *data)
1516 struct me4000_info *info = dev->private;
1518 if (insn->n == 0) {
1519 return 0;
1520 } else if (insn->n > 1) {
1521 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1522 insn->n);
1523 return -EINVAL;
1526 i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
1528 return 1;
1531 static int me4000_auto_attach(struct comedi_device *dev,
1532 unsigned long context)
1534 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1535 const struct me4000_board *thisboard = NULL;
1536 struct me4000_info *info;
1537 struct comedi_subdevice *s;
1538 int result;
1540 if (context < ARRAY_SIZE(me4000_boards))
1541 thisboard = &me4000_boards[context];
1542 if (!thisboard)
1543 return -ENODEV;
1544 dev->board_ptr = thisboard;
1545 dev->board_name = thisboard->name;
1547 info = kzalloc(sizeof(*info), GFP_KERNEL);
1548 if (!info)
1549 return -ENOMEM;
1550 dev->private = info;
1552 result = comedi_pci_enable(dev);
1553 if (result)
1554 return result;
1556 info->plx_regbase = pci_resource_start(pcidev, 1);
1557 dev->iobase = pci_resource_start(pcidev, 2);
1558 info->timer_regbase = pci_resource_start(pcidev, 3);
1559 if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1560 return -ENODEV;
1562 result = xilinx_download(dev);
1563 if (result)
1564 return result;
1566 me4000_reset(dev);
1568 result = comedi_alloc_subdevices(dev, 4);
1569 if (result)
1570 return result;
1572 /*=========================================================================
1573 Analog input subdevice
1574 ========================================================================*/
1576 s = &dev->subdevices[0];
1578 if (thisboard->ai_nchan) {
1579 s->type = COMEDI_SUBD_AI;
1580 s->subdev_flags =
1581 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1582 s->n_chan = thisboard->ai_nchan;
1583 s->maxdata = 0xFFFF; /* 16 bit ADC */
1584 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1585 s->range_table = &me4000_ai_range;
1586 s->insn_read = me4000_ai_insn_read;
1588 if (pcidev->irq > 0) {
1589 if (request_irq(pcidev->irq, me4000_ai_isr,
1590 IRQF_SHARED, dev->board_name, dev)) {
1591 dev_warn(dev->class_dev,
1592 "request_irq failed\n");
1593 } else {
1594 dev->read_subdev = s;
1595 s->subdev_flags |= SDF_CMD_READ;
1596 s->cancel = me4000_ai_cancel;
1597 s->do_cmdtest = me4000_ai_do_cmd_test;
1598 s->do_cmd = me4000_ai_do_cmd;
1600 dev->irq = pcidev->irq;
1602 } else {
1603 dev_warn(dev->class_dev, "No interrupt available\n");
1605 } else {
1606 s->type = COMEDI_SUBD_UNUSED;
1609 /*=========================================================================
1610 Analog output subdevice
1611 ========================================================================*/
1613 s = &dev->subdevices[1];
1615 if (thisboard->ao_nchan) {
1616 s->type = COMEDI_SUBD_AO;
1617 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1618 s->n_chan = thisboard->ao_nchan;
1619 s->maxdata = 0xFFFF; /* 16 bit DAC */
1620 s->range_table = &range_bipolar10;
1621 s->insn_write = me4000_ao_insn_write;
1622 s->insn_read = me4000_ao_insn_read;
1623 } else {
1624 s->type = COMEDI_SUBD_UNUSED;
1627 /*=========================================================================
1628 Digital I/O subdevice
1629 ========================================================================*/
1631 s = &dev->subdevices[2];
1633 if (thisboard->dio_nchan) {
1634 s->type = COMEDI_SUBD_DIO;
1635 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1636 s->n_chan = thisboard->dio_nchan;
1637 s->maxdata = 1;
1638 s->range_table = &range_digital;
1639 s->insn_bits = me4000_dio_insn_bits;
1640 s->insn_config = me4000_dio_insn_config;
1641 } else {
1642 s->type = COMEDI_SUBD_UNUSED;
1646 * Check for optoisolated ME-4000 version. If one the first
1647 * port is a fixed output port and the second is a fixed input port.
1649 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1650 s->io_bits |= 0xFF;
1651 outl(ME4000_DIO_CTRL_BIT_MODE_0,
1652 dev->iobase + ME4000_DIO_DIR_REG);
1655 /*=========================================================================
1656 Counter subdevice
1657 ========================================================================*/
1659 s = &dev->subdevices[3];
1661 if (thisboard->has_counter) {
1662 s->type = COMEDI_SUBD_COUNTER;
1663 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1664 s->n_chan = 3;
1665 s->maxdata = 0xFFFF; /* 16 bit counters */
1666 s->insn_read = me4000_cnt_insn_read;
1667 s->insn_write = me4000_cnt_insn_write;
1668 s->insn_config = me4000_cnt_insn_config;
1669 } else {
1670 s->type = COMEDI_SUBD_UNUSED;
1673 return 0;
1676 static void me4000_detach(struct comedi_device *dev)
1678 if (dev->irq)
1679 free_irq(dev->irq, dev);
1680 if (dev->iobase)
1681 me4000_reset(dev);
1682 comedi_pci_disable(dev);
1685 static struct comedi_driver me4000_driver = {
1686 .driver_name = "me4000",
1687 .module = THIS_MODULE,
1688 .auto_attach = me4000_auto_attach,
1689 .detach = me4000_detach,
1692 static int me4000_pci_probe(struct pci_dev *dev,
1693 const struct pci_device_id *id)
1695 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1698 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
1699 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1700 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1701 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1702 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1703 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1704 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1705 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1706 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1707 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1708 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1709 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1710 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1711 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1712 { 0 }
1714 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1716 static struct pci_driver me4000_pci_driver = {
1717 .name = "me4000",
1718 .id_table = me4000_pci_table,
1719 .probe = me4000_pci_probe,
1720 .remove = comedi_pci_auto_unconfig,
1722 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1724 MODULE_AUTHOR("Comedi http://www.comedi.org");
1725 MODULE_DESCRIPTION("Comedi low-level driver");
1726 MODULE_LICENSE("GPL");