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