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