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