staging: comedi: comedi_test: simplify time since last AI scan
[deliverable/linux.git] / drivers / staging / comedi / drivers / me4000.c
1 /*
2 * me4000.c
3 * Source code for the Meilhaus ME-4000 board family.
4 *
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 *
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.
12 *
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.
17 */
18
19 /*
20 * Driver: me4000
21 * Description: Meilhaus ME-4000 series boards
22 * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i,
23 * ME-4680is
24 * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
25 * Updated: Mon, 18 Mar 2002 15:34:01 -0800
26 * Status: untested
27 *
28 * Supports:
29 * - Analog Input
30 * - Analog Output
31 * - Digital I/O
32 * - Counter
33 *
34 * Configuration Options: not applicable, uses PCI auto config
35 *
36 * The firmware required by these boards is available in the
37 * comedi_nonfree_firmware tarball available from
38 * http://www.comedi.org.
39 */
40
41 #include <linux/module.h>
42 #include <linux/delay.h>
43 #include <linux/interrupt.h>
44
45 #include "../comedi_pci.h"
46
47 #include "comedi_8254.h"
48 #include "plx9052.h"
49
50 #define ME4000_FIRMWARE "me4000_firmware.bin"
51
52 /*
53 * ME4000 Register map and bit defines
54 */
55 #define ME4000_AO_CHAN(x) ((x) * 0x18)
56
57 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
58 #define ME4000_AO_CTRL_MODE_0 BIT(0)
59 #define ME4000_AO_CTRL_MODE_1 BIT(1)
60 #define ME4000_AO_CTRL_STOP BIT(2)
61 #define ME4000_AO_CTRL_ENABLE_FIFO BIT(3)
62 #define ME4000_AO_CTRL_ENABLE_EX_TRIG BIT(4)
63 #define ME4000_AO_CTRL_EX_TRIG_EDGE BIT(5)
64 #define ME4000_AO_CTRL_IMMEDIATE_STOP BIT(7)
65 #define ME4000_AO_CTRL_ENABLE_DO BIT(8)
66 #define ME4000_AO_CTRL_ENABLE_IRQ BIT(9)
67 #define ME4000_AO_CTRL_RESET_IRQ BIT(10)
68 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
69 #define ME4000_AO_STATUS_FSM BIT(0)
70 #define ME4000_AO_STATUS_FF BIT(1)
71 #define ME4000_AO_STATUS_HF BIT(2)
72 #define ME4000_AO_STATUS_EF BIT(3)
73 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
74 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
75 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
76 #define ME4000_AI_CTRL_REG 0x74
77 #define ME4000_AI_STATUS_REG 0x74
78 #define ME4000_AI_CTRL_MODE_0 BIT(0)
79 #define ME4000_AI_CTRL_MODE_1 BIT(1)
80 #define ME4000_AI_CTRL_MODE_2 BIT(2)
81 #define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3)
82 #define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4)
83 #define ME4000_AI_CTRL_STOP BIT(5)
84 #define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6)
85 #define ME4000_AI_CTRL_DATA_FIFO BIT(7)
86 #define ME4000_AI_CTRL_FULLSCALE BIT(8)
87 #define ME4000_AI_CTRL_OFFSET BIT(9)
88 #define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10)
89 #define ME4000_AI_CTRL_EX_TRIG BIT(11)
90 #define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12)
91 #define ME4000_AI_CTRL_EX_IRQ BIT(13)
92 #define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14)
93 #define ME4000_AI_CTRL_LE_IRQ BIT(15)
94 #define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16)
95 #define ME4000_AI_CTRL_HF_IRQ BIT(17)
96 #define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18)
97 #define ME4000_AI_CTRL_SC_IRQ BIT(19)
98 #define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20)
99 #define ME4000_AI_CTRL_SC_RELOAD BIT(21)
100 #define ME4000_AI_STATUS_EF_CHANNEL BIT(22)
101 #define ME4000_AI_STATUS_HF_CHANNEL BIT(23)
102 #define ME4000_AI_STATUS_FF_CHANNEL BIT(24)
103 #define ME4000_AI_STATUS_EF_DATA BIT(25)
104 #define ME4000_AI_STATUS_HF_DATA BIT(26)
105 #define ME4000_AI_STATUS_FF_DATA BIT(27)
106 #define ME4000_AI_STATUS_LE BIT(28)
107 #define ME4000_AI_STATUS_FSM BIT(29)
108 #define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31)
109 #define ME4000_AI_CHANNEL_LIST_REG 0x78
110 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5)
111 #define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6)
112 #define ME4000_AI_LIST_LAST_ENTRY BIT(8)
113 #define ME4000_AI_DATA_REG 0x7c
114 #define ME4000_AI_CHAN_TIMER_REG 0x80
115 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
116 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
117 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
118 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
119 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
120 #define ME4000_AI_START_REG 0x98
121 #define ME4000_IRQ_STATUS_REG 0x9c
122 #define ME4000_IRQ_STATUS_EX BIT(0)
123 #define ME4000_IRQ_STATUS_LE BIT(1)
124 #define ME4000_IRQ_STATUS_AI_HF BIT(2)
125 #define ME4000_IRQ_STATUS_AO_0_HF BIT(3)
126 #define ME4000_IRQ_STATUS_AO_1_HF BIT(4)
127 #define ME4000_IRQ_STATUS_AO_2_HF BIT(5)
128 #define ME4000_IRQ_STATUS_AO_3_HF BIT(6)
129 #define ME4000_IRQ_STATUS_SC BIT(7)
130 #define ME4000_DIO_PORT_0_REG 0xa0
131 #define ME4000_DIO_PORT_1_REG 0xa4
132 #define ME4000_DIO_PORT_2_REG 0xa8
133 #define ME4000_DIO_PORT_3_REG 0xac
134 #define ME4000_DIO_DIR_REG 0xb0
135 #define ME4000_AO_LOADSETREG_XX 0xb4
136 #define ME4000_DIO_CTRL_REG 0xb8
137 #define ME4000_DIO_CTRL_MODE_0 BIT(0)
138 #define ME4000_DIO_CTRL_MODE_1 BIT(1)
139 #define ME4000_DIO_CTRL_MODE_2 BIT(2)
140 #define ME4000_DIO_CTRL_MODE_3 BIT(3)
141 #define ME4000_DIO_CTRL_MODE_4 BIT(4)
142 #define ME4000_DIO_CTRL_MODE_5 BIT(5)
143 #define ME4000_DIO_CTRL_MODE_6 BIT(6)
144 #define ME4000_DIO_CTRL_MODE_7 BIT(7)
145 #define ME4000_DIO_CTRL_FUNCTION_0 BIT(8)
146 #define ME4000_DIO_CTRL_FUNCTION_1 BIT(9)
147 #define ME4000_DIO_CTRL_FIFO_HIGH_0 BIT(10)
148 #define ME4000_DIO_CTRL_FIFO_HIGH_1 BIT(11)
149 #define ME4000_DIO_CTRL_FIFO_HIGH_2 BIT(12)
150 #define ME4000_DIO_CTRL_FIFO_HIGH_3 BIT(13)
151 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
152 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
153 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
154
155 #define ME4000_AI_FIFO_COUNT 2048
156
157 #define ME4000_AI_MIN_TICKS 66
158 #define ME4000_AI_MIN_SAMPLE_TIME 2000
159
160 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
161
162 struct me4000_private {
163 unsigned long plx_regbase;
164 unsigned int ai_ctrl_mode;
165 unsigned int ai_init_ticks;
166 unsigned int ai_scan_ticks;
167 unsigned int ai_chan_ticks;
168 };
169
170 enum me4000_boardid {
171 BOARD_ME4650,
172 BOARD_ME4660,
173 BOARD_ME4660I,
174 BOARD_ME4660S,
175 BOARD_ME4660IS,
176 BOARD_ME4670,
177 BOARD_ME4670I,
178 BOARD_ME4670S,
179 BOARD_ME4670IS,
180 BOARD_ME4680,
181 BOARD_ME4680I,
182 BOARD_ME4680S,
183 BOARD_ME4680IS,
184 };
185
186 struct me4000_board {
187 const char *name;
188 int ai_nchan;
189 unsigned int can_do_diff_ai:1;
190 unsigned int can_do_sh_ai:1; /* sample & hold (8 channels) */
191 unsigned int ex_trig_analog:1;
192 unsigned int has_ao:1;
193 unsigned int has_ao_fifo:1;
194 unsigned int has_counter:1;
195 };
196
197 static const struct me4000_board me4000_boards[] = {
198 [BOARD_ME4650] = {
199 .name = "ME-4650",
200 .ai_nchan = 16,
201 },
202 [BOARD_ME4660] = {
203 .name = "ME-4660",
204 .ai_nchan = 32,
205 .can_do_diff_ai = 1,
206 .has_counter = 1,
207 },
208 [BOARD_ME4660I] = {
209 .name = "ME-4660i",
210 .ai_nchan = 32,
211 .can_do_diff_ai = 1,
212 .has_counter = 1,
213 },
214 [BOARD_ME4660S] = {
215 .name = "ME-4660s",
216 .ai_nchan = 32,
217 .can_do_diff_ai = 1,
218 .can_do_sh_ai = 1,
219 .has_counter = 1,
220 },
221 [BOARD_ME4660IS] = {
222 .name = "ME-4660is",
223 .ai_nchan = 32,
224 .can_do_diff_ai = 1,
225 .can_do_sh_ai = 1,
226 .has_counter = 1,
227 },
228 [BOARD_ME4670] = {
229 .name = "ME-4670",
230 .ai_nchan = 32,
231 .can_do_diff_ai = 1,
232 .ex_trig_analog = 1,
233 .has_ao = 1,
234 .has_counter = 1,
235 },
236 [BOARD_ME4670I] = {
237 .name = "ME-4670i",
238 .ai_nchan = 32,
239 .can_do_diff_ai = 1,
240 .ex_trig_analog = 1,
241 .has_ao = 1,
242 .has_counter = 1,
243 },
244 [BOARD_ME4670S] = {
245 .name = "ME-4670s",
246 .ai_nchan = 32,
247 .can_do_diff_ai = 1,
248 .can_do_sh_ai = 1,
249 .ex_trig_analog = 1,
250 .has_ao = 1,
251 .has_counter = 1,
252 },
253 [BOARD_ME4670IS] = {
254 .name = "ME-4670is",
255 .ai_nchan = 32,
256 .can_do_diff_ai = 1,
257 .can_do_sh_ai = 1,
258 .ex_trig_analog = 1,
259 .has_ao = 1,
260 .has_counter = 1,
261 },
262 [BOARD_ME4680] = {
263 .name = "ME-4680",
264 .ai_nchan = 32,
265 .can_do_diff_ai = 1,
266 .ex_trig_analog = 1,
267 .has_ao = 1,
268 .has_ao_fifo = 1,
269 .has_counter = 1,
270 },
271 [BOARD_ME4680I] = {
272 .name = "ME-4680i",
273 .ai_nchan = 32,
274 .can_do_diff_ai = 1,
275 .ex_trig_analog = 1,
276 .has_ao = 1,
277 .has_ao_fifo = 1,
278 .has_counter = 1,
279 },
280 [BOARD_ME4680S] = {
281 .name = "ME-4680s",
282 .ai_nchan = 32,
283 .can_do_diff_ai = 1,
284 .can_do_sh_ai = 1,
285 .ex_trig_analog = 1,
286 .has_ao = 1,
287 .has_ao_fifo = 1,
288 .has_counter = 1,
289 },
290 [BOARD_ME4680IS] = {
291 .name = "ME-4680is",
292 .ai_nchan = 32,
293 .can_do_diff_ai = 1,
294 .can_do_sh_ai = 1,
295 .ex_trig_analog = 1,
296 .has_ao = 1,
297 .has_ao_fifo = 1,
298 .has_counter = 1,
299 },
300 };
301
302 /*
303 * NOTE: the ranges here are inverted compared to the values
304 * written to the ME4000_AI_CHANNEL_LIST_REG,
305 *
306 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
307 */
308 static const struct comedi_lrange me4000_ai_range = {
309 4, {
310 UNI_RANGE(2.5),
311 UNI_RANGE(10),
312 BIP_RANGE(2.5),
313 BIP_RANGE(10)
314 }
315 };
316
317 static int me4000_xilinx_download(struct comedi_device *dev,
318 const u8 *data, size_t size,
319 unsigned long context)
320 {
321 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
322 struct me4000_private *devpriv = dev->private;
323 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
324 unsigned int file_length;
325 unsigned int val;
326 unsigned int i;
327
328 if (!xilinx_iobase)
329 return -ENODEV;
330
331 /*
332 * Set PLX local interrupt 2 polarity to high.
333 * Interrupt is thrown by init pin of xilinx.
334 */
335 outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR);
336
337 /* Set /CS and /WRITE of the Xilinx */
338 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
339 val |= PLX9052_CNTRL_UIO2_DATA;
340 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
341
342 /* Init Xilinx with CS1 */
343 inb(xilinx_iobase + 0xC8);
344
345 /* Wait until /INIT pin is set */
346 usleep_range(20, 1000);
347 val = inl(devpriv->plx_regbase + PLX9052_INTCSR);
348 if (!(val & PLX9052_INTCSR_LI2STAT)) {
349 dev_err(dev->class_dev, "Can't init Xilinx\n");
350 return -EIO;
351 }
352
353 /* Reset /CS and /WRITE of the Xilinx */
354 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
355 val &= ~PLX9052_CNTRL_UIO2_DATA;
356 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
357
358 /* Download Xilinx firmware */
359 file_length = (((unsigned int)data[0] & 0xff) << 24) +
360 (((unsigned int)data[1] & 0xff) << 16) +
361 (((unsigned int)data[2] & 0xff) << 8) +
362 ((unsigned int)data[3] & 0xff);
363 usleep_range(10, 1000);
364
365 for (i = 0; i < file_length; i++) {
366 outb(data[16 + i], xilinx_iobase);
367 usleep_range(10, 1000);
368
369 /* Check if BUSY flag is low */
370 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
371 if (val & PLX9052_CNTRL_UIO1_DATA) {
372 dev_err(dev->class_dev,
373 "Xilinx is still busy (i = %d)\n", i);
374 return -EIO;
375 }
376 }
377
378 /* If done flag is high download was successful */
379 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
380 if (!(val & PLX9052_CNTRL_UIO0_DATA)) {
381 dev_err(dev->class_dev, "DONE flag is not set\n");
382 dev_err(dev->class_dev, "Download not successful\n");
383 return -EIO;
384 }
385
386 /* Set /CS and /WRITE */
387 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
388 val |= PLX9052_CNTRL_UIO2_DATA;
389 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
390
391 return 0;
392 }
393
394 static void me4000_ai_reset(struct comedi_device *dev)
395 {
396 unsigned int ctrl;
397
398 /* Stop any running conversion */
399 ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG);
400 ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP;
401 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
402
403 /* Clear the control register */
404 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
405 }
406
407 static void me4000_reset(struct comedi_device *dev)
408 {
409 struct me4000_private *devpriv = dev->private;
410 unsigned int val;
411 int chan;
412
413 /* Disable interrupts on the PLX */
414 outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
415
416 /* Software reset the PLX */
417 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
418 val |= PLX9052_CNTRL_PCI_RESET;
419 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
420 val &= ~PLX9052_CNTRL_PCI_RESET;
421 outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
422
423 /* 0x8000 to the DACs means an output voltage of 0V */
424 for (chan = 0; chan < 4; chan++)
425 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
426
427 me4000_ai_reset(dev);
428
429 /* Set both stop bits in the analog output control register */
430 val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP;
431 for (chan = 0; chan < 4; chan++)
432 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
433
434 /* Set the adustment register for AO demux */
435 outl(ME4000_AO_DEMUX_ADJUST_VALUE,
436 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
437
438 /*
439 * Set digital I/O direction for port 0
440 * to output on isolated versions
441 */
442 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
443 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
444 }
445
446 static unsigned int me4000_ai_get_sample(struct comedi_device *dev,
447 struct comedi_subdevice *s)
448 {
449 unsigned int val;
450
451 /* read two's complement value and munge to offset binary */
452 val = inl(dev->iobase + ME4000_AI_DATA_REG);
453 return comedi_offset_munge(s, val);
454 }
455
456 static int me4000_ai_eoc(struct comedi_device *dev,
457 struct comedi_subdevice *s,
458 struct comedi_insn *insn,
459 unsigned long context)
460 {
461 unsigned int status;
462
463 status = inl(dev->iobase + ME4000_AI_STATUS_REG);
464 if (status & ME4000_AI_STATUS_EF_DATA)
465 return 0;
466 return -EBUSY;
467 }
468
469 static int me4000_ai_insn_read(struct comedi_device *dev,
470 struct comedi_subdevice *s,
471 struct comedi_insn *insn,
472 unsigned int *data)
473 {
474 unsigned int chan = CR_CHAN(insn->chanspec);
475 unsigned int range = CR_RANGE(insn->chanspec);
476 unsigned int aref = CR_AREF(insn->chanspec);
477 unsigned int entry;
478 int ret = 0;
479 int i;
480
481 entry = chan | ME4000_AI_LIST_RANGE(range);
482 if (aref == AREF_DIFF) {
483 if (!(s->subdev_flags & SDF_DIFF)) {
484 dev_err(dev->class_dev,
485 "Differential inputs are not available\n");
486 return -EINVAL;
487 }
488
489 if (!comedi_range_is_bipolar(s, range)) {
490 dev_err(dev->class_dev,
491 "Range must be bipolar when aref = diff\n");
492 return -EINVAL;
493 }
494
495 if (chan >= (s->n_chan / 2)) {
496 dev_err(dev->class_dev,
497 "Analog input is not available\n");
498 return -EINVAL;
499 }
500 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
501 }
502
503 entry |= ME4000_AI_LIST_LAST_ENTRY;
504
505 /* Enable channel list and data fifo for single acquisition mode */
506 outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO,
507 dev->iobase + ME4000_AI_CTRL_REG);
508
509 /* Generate channel list entry */
510 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
511
512 /* Set the timer to maximum sample rate */
513 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
514 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
515
516 for (i = 0; i < insn->n; i++) {
517 unsigned int val;
518
519 /* start conversion by dummy read */
520 inl(dev->iobase + ME4000_AI_START_REG);
521
522 ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0);
523 if (ret)
524 break;
525
526 val = me4000_ai_get_sample(dev, s);
527 data[i] = comedi_offset_munge(s, val);
528 }
529
530 me4000_ai_reset(dev);
531
532 return ret ? ret : insn->n;
533 }
534
535 static int me4000_ai_cancel(struct comedi_device *dev,
536 struct comedi_subdevice *s)
537 {
538 me4000_ai_reset(dev);
539
540 return 0;
541 }
542
543 static int me4000_ai_check_chanlist(struct comedi_device *dev,
544 struct comedi_subdevice *s,
545 struct comedi_cmd *cmd)
546 {
547 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
548 int i;
549
550 for (i = 0; i < cmd->chanlist_len; i++) {
551 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
552 unsigned int range = CR_RANGE(cmd->chanlist[i]);
553 unsigned int aref = CR_AREF(cmd->chanlist[i]);
554
555 if (aref != aref0) {
556 dev_dbg(dev->class_dev,
557 "Mode is not equal for all entries\n");
558 return -EINVAL;
559 }
560
561 if (aref == AREF_DIFF) {
562 if (!(s->subdev_flags & SDF_DIFF)) {
563 dev_err(dev->class_dev,
564 "Differential inputs are not available\n");
565 return -EINVAL;
566 }
567
568 if (chan >= (s->n_chan / 2)) {
569 dev_dbg(dev->class_dev,
570 "Channel number to high\n");
571 return -EINVAL;
572 }
573
574 if (!comedi_range_is_bipolar(s, range)) {
575 dev_dbg(dev->class_dev,
576 "Bipolar is not selected in differential mode\n");
577 return -EINVAL;
578 }
579 }
580 }
581
582 return 0;
583 }
584
585 static void me4000_ai_round_cmd_args(struct comedi_device *dev,
586 struct comedi_subdevice *s,
587 struct comedi_cmd *cmd)
588 {
589 struct me4000_private *devpriv = dev->private;
590 int rest;
591
592 devpriv->ai_init_ticks = 0;
593 devpriv->ai_scan_ticks = 0;
594 devpriv->ai_chan_ticks = 0;
595
596 if (cmd->start_arg) {
597 devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000;
598 rest = (cmd->start_arg * 33) % 1000;
599
600 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
601 if (rest > 33)
602 devpriv->ai_init_ticks++;
603 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
604 if (rest)
605 devpriv->ai_init_ticks++;
606 }
607 }
608
609 if (cmd->scan_begin_arg) {
610 devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
611 rest = (cmd->scan_begin_arg * 33) % 1000;
612
613 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
614 if (rest > 33)
615 devpriv->ai_scan_ticks++;
616 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
617 if (rest)
618 devpriv->ai_scan_ticks++;
619 }
620 }
621
622 if (cmd->convert_arg) {
623 devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000;
624 rest = (cmd->convert_arg * 33) % 1000;
625
626 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
627 if (rest > 33)
628 devpriv->ai_chan_ticks++;
629 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
630 if (rest)
631 devpriv->ai_chan_ticks++;
632 }
633 }
634 }
635
636 static void me4000_ai_write_chanlist(struct comedi_device *dev,
637 struct comedi_subdevice *s,
638 struct comedi_cmd *cmd)
639 {
640 int i;
641
642 for (i = 0; i < cmd->chanlist_len; i++) {
643 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
644 unsigned int range = CR_RANGE(cmd->chanlist[i]);
645 unsigned int aref = CR_AREF(cmd->chanlist[i]);
646 unsigned int entry;
647
648 entry = chan | ME4000_AI_LIST_RANGE(range);
649
650 if (aref == AREF_DIFF)
651 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
652
653 if (i == (cmd->chanlist_len - 1))
654 entry |= ME4000_AI_LIST_LAST_ENTRY;
655
656 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
657 }
658 }
659
660 static int me4000_ai_do_cmd(struct comedi_device *dev,
661 struct comedi_subdevice *s)
662 {
663 struct me4000_private *devpriv = dev->private;
664 struct comedi_cmd *cmd = &s->async->cmd;
665 unsigned int ctrl;
666
667 /* Write timer arguments */
668 outl(devpriv->ai_init_ticks - 1,
669 dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
670 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
671
672 if (devpriv->ai_scan_ticks) {
673 outl(devpriv->ai_scan_ticks - 1,
674 dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
675 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
676 }
677
678 outl(devpriv->ai_chan_ticks - 1,
679 dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
680 outl(devpriv->ai_chan_ticks - 1,
681 dev->iobase + ME4000_AI_CHAN_TIMER_REG);
682
683 /* Start sources */
684 ctrl = devpriv->ai_ctrl_mode |
685 ME4000_AI_CTRL_CHANNEL_FIFO |
686 ME4000_AI_CTRL_DATA_FIFO;
687
688 /* Stop triggers */
689 if (cmd->stop_src == TRIG_COUNT) {
690 outl(cmd->chanlist_len * cmd->stop_arg,
691 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
692 ctrl |= ME4000_AI_CTRL_SC_IRQ;
693 } else if (cmd->stop_src == TRIG_NONE &&
694 cmd->scan_end_src == TRIG_COUNT) {
695 outl(cmd->scan_end_arg,
696 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
697 ctrl |= ME4000_AI_CTRL_SC_IRQ;
698 }
699 ctrl |= ME4000_AI_CTRL_HF_IRQ;
700
701 /* Write the setup to the control register */
702 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
703
704 /* Write the channel list */
705 me4000_ai_write_chanlist(dev, s, cmd);
706
707 /* Start acquistion by dummy read */
708 inl(dev->iobase + ME4000_AI_START_REG);
709
710 return 0;
711 }
712
713 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
714 struct comedi_subdevice *s,
715 struct comedi_cmd *cmd)
716 {
717 struct me4000_private *devpriv = dev->private;
718 int err = 0;
719
720 /* Step 1 : check if triggers are trivially valid */
721
722 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
723 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
724 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
725 err |= comedi_check_trigger_src(&cmd->convert_src,
726 TRIG_TIMER | TRIG_EXT);
727 err |= comedi_check_trigger_src(&cmd->scan_end_src,
728 TRIG_NONE | TRIG_COUNT);
729 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
730
731 if (err)
732 return 1;
733
734 /* Step 2a : make sure trigger sources are unique */
735
736 err |= comedi_check_trigger_is_unique(cmd->start_src);
737 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
738 err |= comedi_check_trigger_is_unique(cmd->convert_src);
739 err |= comedi_check_trigger_is_unique(cmd->scan_end_src);
740 err |= comedi_check_trigger_is_unique(cmd->stop_src);
741
742 /* Step 2b : and mutually compatible */
743
744 if (cmd->start_src == TRIG_NOW &&
745 cmd->scan_begin_src == TRIG_TIMER &&
746 cmd->convert_src == TRIG_TIMER) {
747 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
748 } else if (cmd->start_src == TRIG_NOW &&
749 cmd->scan_begin_src == TRIG_FOLLOW &&
750 cmd->convert_src == TRIG_TIMER) {
751 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
752 } else if (cmd->start_src == TRIG_EXT &&
753 cmd->scan_begin_src == TRIG_TIMER &&
754 cmd->convert_src == TRIG_TIMER) {
755 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
756 } else if (cmd->start_src == TRIG_EXT &&
757 cmd->scan_begin_src == TRIG_FOLLOW &&
758 cmd->convert_src == TRIG_TIMER) {
759 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
760 } else if (cmd->start_src == TRIG_EXT &&
761 cmd->scan_begin_src == TRIG_EXT &&
762 cmd->convert_src == TRIG_TIMER) {
763 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2;
764 } else if (cmd->start_src == TRIG_EXT &&
765 cmd->scan_begin_src == TRIG_EXT &&
766 cmd->convert_src == TRIG_EXT) {
767 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 |
768 ME4000_AI_CTRL_MODE_1;
769 } else {
770 err |= -EINVAL;
771 }
772
773 if (err)
774 return 2;
775
776 /* Step 3: check if arguments are trivially valid */
777
778 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
779
780 if (cmd->chanlist_len < 1) {
781 cmd->chanlist_len = 1;
782 err |= -EINVAL;
783 }
784
785 /* Round the timer arguments */
786 me4000_ai_round_cmd_args(dev, s, cmd);
787
788 if (devpriv->ai_init_ticks < 66) {
789 cmd->start_arg = 2000;
790 err |= -EINVAL;
791 }
792 if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) {
793 cmd->scan_begin_arg = 2031;
794 err |= -EINVAL;
795 }
796 if (devpriv->ai_chan_ticks < 66) {
797 cmd->convert_arg = 2000;
798 err |= -EINVAL;
799 }
800
801 if (cmd->stop_src == TRIG_COUNT)
802 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
803 else /* TRIG_NONE */
804 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
805
806 if (err)
807 return 3;
808
809 /*
810 * Stage 4. Check for argument conflicts.
811 */
812 if (cmd->start_src == TRIG_NOW &&
813 cmd->scan_begin_src == TRIG_TIMER &&
814 cmd->convert_src == TRIG_TIMER) {
815 /* Check timer arguments */
816 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
817 dev_err(dev->class_dev, "Invalid start arg\n");
818 cmd->start_arg = 2000; /* 66 ticks at least */
819 err++;
820 }
821 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
822 dev_err(dev->class_dev, "Invalid convert arg\n");
823 cmd->convert_arg = 2000; /* 66 ticks at least */
824 err++;
825 }
826 if (devpriv->ai_scan_ticks <=
827 cmd->chanlist_len * devpriv->ai_chan_ticks) {
828 dev_err(dev->class_dev, "Invalid scan end arg\n");
829
830 /* At least one tick more */
831 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
832 err++;
833 }
834 } else if (cmd->start_src == TRIG_NOW &&
835 cmd->scan_begin_src == TRIG_FOLLOW &&
836 cmd->convert_src == TRIG_TIMER) {
837 /* Check timer arguments */
838 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
839 dev_err(dev->class_dev, "Invalid start arg\n");
840 cmd->start_arg = 2000; /* 66 ticks at least */
841 err++;
842 }
843 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
844 dev_err(dev->class_dev, "Invalid convert arg\n");
845 cmd->convert_arg = 2000; /* 66 ticks at least */
846 err++;
847 }
848 } else if (cmd->start_src == TRIG_EXT &&
849 cmd->scan_begin_src == TRIG_TIMER &&
850 cmd->convert_src == TRIG_TIMER) {
851 /* Check timer arguments */
852 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
853 dev_err(dev->class_dev, "Invalid start arg\n");
854 cmd->start_arg = 2000; /* 66 ticks at least */
855 err++;
856 }
857 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
858 dev_err(dev->class_dev, "Invalid convert arg\n");
859 cmd->convert_arg = 2000; /* 66 ticks at least */
860 err++;
861 }
862 if (devpriv->ai_scan_ticks <=
863 cmd->chanlist_len * devpriv->ai_chan_ticks) {
864 dev_err(dev->class_dev, "Invalid scan end arg\n");
865
866 /* At least one tick more */
867 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
868 err++;
869 }
870 } else if (cmd->start_src == TRIG_EXT &&
871 cmd->scan_begin_src == TRIG_FOLLOW &&
872 cmd->convert_src == TRIG_TIMER) {
873 /* Check timer arguments */
874 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
875 dev_err(dev->class_dev, "Invalid start arg\n");
876 cmd->start_arg = 2000; /* 66 ticks at least */
877 err++;
878 }
879 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
880 dev_err(dev->class_dev, "Invalid convert arg\n");
881 cmd->convert_arg = 2000; /* 66 ticks at least */
882 err++;
883 }
884 } else if (cmd->start_src == TRIG_EXT &&
885 cmd->scan_begin_src == TRIG_EXT &&
886 cmd->convert_src == TRIG_TIMER) {
887 /* Check timer arguments */
888 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
889 dev_err(dev->class_dev, "Invalid start arg\n");
890 cmd->start_arg = 2000; /* 66 ticks at least */
891 err++;
892 }
893 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
894 dev_err(dev->class_dev, "Invalid convert arg\n");
895 cmd->convert_arg = 2000; /* 66 ticks at least */
896 err++;
897 }
898 } else if (cmd->start_src == TRIG_EXT &&
899 cmd->scan_begin_src == TRIG_EXT &&
900 cmd->convert_src == TRIG_EXT) {
901 /* Check timer arguments */
902 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
903 dev_err(dev->class_dev, "Invalid start arg\n");
904 cmd->start_arg = 2000; /* 66 ticks at least */
905 err++;
906 }
907 }
908 if (cmd->scan_end_src == TRIG_COUNT) {
909 if (cmd->scan_end_arg == 0) {
910 dev_err(dev->class_dev, "Invalid scan end arg\n");
911 cmd->scan_end_arg = 1;
912 err++;
913 }
914 }
915
916 if (err)
917 return 4;
918
919 /* Step 5: check channel list if it exists */
920 if (cmd->chanlist && cmd->chanlist_len > 0)
921 err |= me4000_ai_check_chanlist(dev, s, cmd);
922
923 if (err)
924 return 5;
925
926 return 0;
927 }
928
929 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
930 {
931 unsigned int tmp;
932 struct comedi_device *dev = dev_id;
933 struct comedi_subdevice *s = dev->read_subdev;
934 int i;
935 int c = 0;
936 unsigned int lval;
937
938 if (!dev->attached)
939 return IRQ_NONE;
940
941 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
942 ME4000_IRQ_STATUS_AI_HF) {
943 /* Read status register to find out what happened */
944 tmp = inl(dev->iobase + ME4000_AI_STATUS_REG);
945
946 if (!(tmp & ME4000_AI_STATUS_FF_DATA) &&
947 !(tmp & ME4000_AI_STATUS_HF_DATA) &&
948 (tmp & ME4000_AI_STATUS_EF_DATA)) {
949 dev_err(dev->class_dev, "FIFO overflow\n");
950 s->async->events |= COMEDI_CB_ERROR;
951 c = ME4000_AI_FIFO_COUNT;
952 } else if ((tmp & ME4000_AI_STATUS_FF_DATA) &&
953 !(tmp & ME4000_AI_STATUS_HF_DATA) &&
954 (tmp & ME4000_AI_STATUS_EF_DATA)) {
955 c = ME4000_AI_FIFO_COUNT / 2;
956 } else {
957 dev_err(dev->class_dev, "Undefined FIFO state\n");
958 s->async->events |= COMEDI_CB_ERROR;
959 c = 0;
960 }
961
962 for (i = 0; i < c; i++) {
963 lval = me4000_ai_get_sample(dev, s);
964 if (!comedi_buf_write_samples(s, &lval, 1))
965 break;
966 }
967
968 /* Work is done, so reset the interrupt */
969 tmp |= ME4000_AI_CTRL_HF_IRQ_RESET;
970 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
971 tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET;
972 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
973 }
974
975 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
976 ME4000_IRQ_STATUS_SC) {
977 /* Acquisition is complete */
978 s->async->events |= COMEDI_CB_EOA;
979
980 /* Poll data until fifo empty */
981 while (inl(dev->iobase + ME4000_AI_STATUS_REG) &
982 ME4000_AI_STATUS_EF_DATA) {
983 lval = me4000_ai_get_sample(dev, s);
984 if (!comedi_buf_write_samples(s, &lval, 1))
985 break;
986 }
987
988 /* Work is done, so reset the interrupt */
989 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
990 tmp |= ME4000_AI_CTRL_SC_IRQ_RESET;
991 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
992 tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET;
993 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
994 }
995
996 comedi_handle_events(dev, s);
997
998 return IRQ_HANDLED;
999 }
1000
1001 static int me4000_ao_insn_write(struct comedi_device *dev,
1002 struct comedi_subdevice *s,
1003 struct comedi_insn *insn,
1004 unsigned int *data)
1005 {
1006 unsigned int chan = CR_CHAN(insn->chanspec);
1007 unsigned int tmp;
1008
1009 /* Stop any running conversion */
1010 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1011 tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP;
1012 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1013
1014 /* Clear control register and set to single mode */
1015 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1016
1017 /* Write data value */
1018 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1019
1020 /* Store in the mirror */
1021 s->readback[chan] = data[0];
1022
1023 return 1;
1024 }
1025
1026 static int me4000_dio_insn_bits(struct comedi_device *dev,
1027 struct comedi_subdevice *s,
1028 struct comedi_insn *insn,
1029 unsigned int *data)
1030 {
1031 if (comedi_dio_update_state(s, data)) {
1032 outl((s->state >> 0) & 0xFF,
1033 dev->iobase + ME4000_DIO_PORT_0_REG);
1034 outl((s->state >> 8) & 0xFF,
1035 dev->iobase + ME4000_DIO_PORT_1_REG);
1036 outl((s->state >> 16) & 0xFF,
1037 dev->iobase + ME4000_DIO_PORT_2_REG);
1038 outl((s->state >> 24) & 0xFF,
1039 dev->iobase + ME4000_DIO_PORT_3_REG);
1040 }
1041
1042 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1043 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1044 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1045 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1046
1047 return insn->n;
1048 }
1049
1050 static int me4000_dio_insn_config(struct comedi_device *dev,
1051 struct comedi_subdevice *s,
1052 struct comedi_insn *insn,
1053 unsigned int *data)
1054 {
1055 unsigned int chan = CR_CHAN(insn->chanspec);
1056 unsigned int mask;
1057 unsigned int tmp;
1058 int ret;
1059
1060 if (chan < 8)
1061 mask = 0x000000ff;
1062 else if (chan < 16)
1063 mask = 0x0000ff00;
1064 else if (chan < 24)
1065 mask = 0x00ff0000;
1066 else
1067 mask = 0xff000000;
1068
1069 ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1070 if (ret)
1071 return ret;
1072
1073 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1074 tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 |
1075 ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 |
1076 ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 |
1077 ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7);
1078 if (s->io_bits & 0x000000ff)
1079 tmp |= ME4000_DIO_CTRL_MODE_0;
1080 if (s->io_bits & 0x0000ff00)
1081 tmp |= ME4000_DIO_CTRL_MODE_2;
1082 if (s->io_bits & 0x00ff0000)
1083 tmp |= ME4000_DIO_CTRL_MODE_4;
1084 if (s->io_bits & 0xff000000)
1085 tmp |= ME4000_DIO_CTRL_MODE_6;
1086
1087 /*
1088 * Check for optoisolated ME-4000 version.
1089 * If one the first port is a fixed output
1090 * port and the second is a fixed input port.
1091 */
1092 if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1093 s->io_bits |= 0x000000ff;
1094 s->io_bits &= ~0x0000ff00;
1095 tmp |= ME4000_DIO_CTRL_MODE_0;
1096 tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3);
1097 }
1098
1099 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1100
1101 return insn->n;
1102 }
1103
1104 static int me4000_auto_attach(struct comedi_device *dev,
1105 unsigned long context)
1106 {
1107 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1108 const struct me4000_board *board = NULL;
1109 struct me4000_private *devpriv;
1110 struct comedi_subdevice *s;
1111 int result;
1112
1113 if (context < ARRAY_SIZE(me4000_boards))
1114 board = &me4000_boards[context];
1115 if (!board)
1116 return -ENODEV;
1117 dev->board_ptr = board;
1118 dev->board_name = board->name;
1119
1120 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1121 if (!devpriv)
1122 return -ENOMEM;
1123
1124 result = comedi_pci_enable(dev);
1125 if (result)
1126 return result;
1127
1128 devpriv->plx_regbase = pci_resource_start(pcidev, 1);
1129 dev->iobase = pci_resource_start(pcidev, 2);
1130 if (!devpriv->plx_regbase || !dev->iobase)
1131 return -ENODEV;
1132
1133 result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
1134 me4000_xilinx_download, 0);
1135 if (result < 0)
1136 return result;
1137
1138 me4000_reset(dev);
1139
1140 if (pcidev->irq > 0) {
1141 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1142 dev->board_name, dev);
1143 if (result == 0) {
1144 dev->irq = pcidev->irq;
1145
1146 /* Enable interrupts on the PLX */
1147 outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL |
1148 PLX9052_INTCSR_PCIENAB,
1149 devpriv->plx_regbase + PLX9052_INTCSR);
1150 }
1151 }
1152
1153 result = comedi_alloc_subdevices(dev, 4);
1154 if (result)
1155 return result;
1156
1157 /* Analog Input subdevice */
1158 s = &dev->subdevices[0];
1159 s->type = COMEDI_SUBD_AI;
1160 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
1161 if (board->can_do_diff_ai)
1162 s->subdev_flags |= SDF_DIFF;
1163 s->n_chan = board->ai_nchan;
1164 s->maxdata = 0xffff;
1165 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1166 s->range_table = &me4000_ai_range;
1167 s->insn_read = me4000_ai_insn_read;
1168
1169 if (dev->irq) {
1170 dev->read_subdev = s;
1171 s->subdev_flags |= SDF_CMD_READ;
1172 s->cancel = me4000_ai_cancel;
1173 s->do_cmdtest = me4000_ai_do_cmd_test;
1174 s->do_cmd = me4000_ai_do_cmd;
1175 }
1176
1177 /* Analog Output subdevice */
1178 s = &dev->subdevices[1];
1179 if (board->has_ao) {
1180 s->type = COMEDI_SUBD_AO;
1181 s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND;
1182 s->n_chan = 4;
1183 s->maxdata = 0xffff;
1184 s->range_table = &range_bipolar10;
1185 s->insn_write = me4000_ao_insn_write;
1186
1187 result = comedi_alloc_subdev_readback(s);
1188 if (result)
1189 return result;
1190 } else {
1191 s->type = COMEDI_SUBD_UNUSED;
1192 }
1193
1194 /* Digital I/O subdevice */
1195 s = &dev->subdevices[2];
1196 s->type = COMEDI_SUBD_DIO;
1197 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1198 s->n_chan = 32;
1199 s->maxdata = 1;
1200 s->range_table = &range_digital;
1201 s->insn_bits = me4000_dio_insn_bits;
1202 s->insn_config = me4000_dio_insn_config;
1203
1204 /*
1205 * Check for optoisolated ME-4000 version. If one the first
1206 * port is a fixed output port and the second is a fixed input port.
1207 */
1208 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1209 s->io_bits |= 0xFF;
1210 outl(ME4000_DIO_CTRL_MODE_0,
1211 dev->iobase + ME4000_DIO_DIR_REG);
1212 }
1213
1214 /* Counter subdevice (8254) */
1215 s = &dev->subdevices[3];
1216 if (board->has_counter) {
1217 unsigned long timer_base = pci_resource_start(pcidev, 3);
1218
1219 if (!timer_base)
1220 return -ENODEV;
1221
1222 dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0);
1223 if (!dev->pacer)
1224 return -ENOMEM;
1225
1226 comedi_8254_subdevice_init(s, dev->pacer);
1227 } else {
1228 s->type = COMEDI_SUBD_UNUSED;
1229 }
1230
1231 return 0;
1232 }
1233
1234 static void me4000_detach(struct comedi_device *dev)
1235 {
1236 if (dev->irq) {
1237 struct me4000_private *devpriv = dev->private;
1238
1239 /* Disable interrupts on the PLX */
1240 outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
1241 }
1242 comedi_pci_detach(dev);
1243 }
1244
1245 static struct comedi_driver me4000_driver = {
1246 .driver_name = "me4000",
1247 .module = THIS_MODULE,
1248 .auto_attach = me4000_auto_attach,
1249 .detach = me4000_detach,
1250 };
1251
1252 static int me4000_pci_probe(struct pci_dev *dev,
1253 const struct pci_device_id *id)
1254 {
1255 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1256 }
1257
1258 static const struct pci_device_id me4000_pci_table[] = {
1259 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1260 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1261 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1262 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1263 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1264 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1265 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1266 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1267 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1268 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1269 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1270 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1271 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1272 { 0 }
1273 };
1274 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1275
1276 static struct pci_driver me4000_pci_driver = {
1277 .name = "me4000",
1278 .id_table = me4000_pci_table,
1279 .probe = me4000_pci_probe,
1280 .remove = comedi_pci_auto_unconfig,
1281 };
1282 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1283
1284 MODULE_AUTHOR("Comedi http://www.comedi.org");
1285 MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards");
1286 MODULE_LICENSE("GPL");
1287 MODULE_FIRMWARE(ME4000_FIRMWARE);
This page took 0.087236 seconds and 5 git commands to generate.