a08bc6ffad306ebb57f10e63fa152b7502ddd04e
[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/pci.h>
45 #include <linux/delay.h>
46 #include <linux/interrupt.h>
47 #include <linux/list.h>
48 #include <linux/spinlock.h>
49
50 #include "../comedidev.h"
51
52 #include "comedi_fc.h"
53 #include "8253.h"
54 #include "plx9052.h"
55
56 #if 0
57 /* file removed due to GPL incompatibility */
58 #include "me4000_fw.h"
59 #endif
60
61 /*
62 * ME4000 Register map and bit defines
63 */
64 #define ME4000_AO_CHAN(x) ((x) * 0x18)
65
66 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
67 #define ME4000_AO_CTRL_BIT_MODE_0 (1 << 0)
68 #define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1)
69 #define ME4000_AO_CTRL_MASK_MODE (3 << 0)
70 #define ME4000_AO_CTRL_BIT_STOP (1 << 2)
71 #define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3)
72 #define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4)
73 #define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5)
74 #define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7)
75 #define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8)
76 #define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9)
77 #define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10)
78 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
79 #define ME4000_AO_STATUS_BIT_FSM (1 << 0)
80 #define ME4000_AO_STATUS_BIT_FF (1 << 1)
81 #define ME4000_AO_STATUS_BIT_HF (1 << 2)
82 #define ME4000_AO_STATUS_BIT_EF (1 << 3)
83 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
84 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
85 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
86 #define ME4000_AI_CTRL_REG 0x74
87 #define ME4000_AI_STATUS_REG 0x74
88 #define ME4000_AI_CTRL_BIT_MODE_0 (1 << 0)
89 #define ME4000_AI_CTRL_BIT_MODE_1 (1 << 1)
90 #define ME4000_AI_CTRL_BIT_MODE_2 (1 << 2)
91 #define ME4000_AI_CTRL_BIT_SAMPLE_HOLD (1 << 3)
92 #define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP (1 << 4)
93 #define ME4000_AI_CTRL_BIT_STOP (1 << 5)
94 #define ME4000_AI_CTRL_BIT_CHANNEL_FIFO (1 << 6)
95 #define ME4000_AI_CTRL_BIT_DATA_FIFO (1 << 7)
96 #define ME4000_AI_CTRL_BIT_FULLSCALE (1 << 8)
97 #define ME4000_AI_CTRL_BIT_OFFSET (1 << 9)
98 #define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG (1 << 10)
99 #define ME4000_AI_CTRL_BIT_EX_TRIG (1 << 11)
100 #define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING (1 << 12)
101 #define ME4000_AI_CTRL_BIT_EX_IRQ (1 << 13)
102 #define ME4000_AI_CTRL_BIT_EX_IRQ_RESET (1 << 14)
103 #define ME4000_AI_CTRL_BIT_LE_IRQ (1 << 15)
104 #define ME4000_AI_CTRL_BIT_LE_IRQ_RESET (1 << 16)
105 #define ME4000_AI_CTRL_BIT_HF_IRQ (1 << 17)
106 #define ME4000_AI_CTRL_BIT_HF_IRQ_RESET (1 << 18)
107 #define ME4000_AI_CTRL_BIT_SC_IRQ (1 << 19)
108 #define ME4000_AI_CTRL_BIT_SC_IRQ_RESET (1 << 20)
109 #define ME4000_AI_CTRL_BIT_SC_RELOAD (1 << 21)
110 #define ME4000_AI_STATUS_BIT_EF_CHANNEL (1 << 22)
111 #define ME4000_AI_STATUS_BIT_HF_CHANNEL (1 << 23)
112 #define ME4000_AI_STATUS_BIT_FF_CHANNEL (1 << 24)
113 #define ME4000_AI_STATUS_BIT_EF_DATA (1 << 25)
114 #define ME4000_AI_STATUS_BIT_HF_DATA (1 << 26)
115 #define ME4000_AI_STATUS_BIT_FF_DATA (1 << 27)
116 #define ME4000_AI_STATUS_BIT_LE (1 << 28)
117 #define ME4000_AI_STATUS_BIT_FSM (1 << 29)
118 #define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH (1 << 31)
119 #define ME4000_AI_CHANNEL_LIST_REG 0x78
120 #define ME4000_AI_LIST_INPUT_SINGLE_ENDED (0 << 5)
121 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL (1 << 5)
122 #define ME4000_AI_LIST_RANGE_BIPOLAR_10 (0 << 6)
123 #define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 (1 << 6)
124 #define ME4000_AI_LIST_RANGE_UNIPOLAR_10 (2 << 6)
125 #define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 (3 << 6)
126 #define ME4000_AI_LIST_LAST_ENTRY (1 << 8)
127 #define ME4000_AI_DATA_REG 0x7c
128 #define ME4000_AI_CHAN_TIMER_REG 0x80
129 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
130 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
131 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
132 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
133 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
134 #define ME4000_AI_START_REG 0x98
135 #define ME4000_IRQ_STATUS_REG 0x9c
136 #define ME4000_IRQ_STATUS_BIT_EX (1 << 0)
137 #define ME4000_IRQ_STATUS_BIT_LE (1 << 1)
138 #define ME4000_IRQ_STATUS_BIT_AI_HF (1 << 2)
139 #define ME4000_IRQ_STATUS_BIT_AO_0_HF (1 << 3)
140 #define ME4000_IRQ_STATUS_BIT_AO_1_HF (1 << 4)
141 #define ME4000_IRQ_STATUS_BIT_AO_2_HF (1 << 5)
142 #define ME4000_IRQ_STATUS_BIT_AO_3_HF (1 << 6)
143 #define ME4000_IRQ_STATUS_BIT_SC (1 << 7)
144 #define ME4000_DIO_PORT_0_REG 0xa0
145 #define ME4000_DIO_PORT_1_REG 0xa4
146 #define ME4000_DIO_PORT_2_REG 0xa8
147 #define ME4000_DIO_PORT_3_REG 0xac
148 #define ME4000_DIO_DIR_REG 0xb0
149 #define ME4000_AO_LOADSETREG_XX 0xb4
150 #define ME4000_DIO_CTRL_REG 0xb8
151 #define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0)
152 #define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1)
153 #define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2)
154 #define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3)
155 #define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4)
156 #define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5)
157 #define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6)
158 #define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7)
159 #define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8)
160 #define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9)
161 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10)
162 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11)
163 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12)
164 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13)
165 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
166 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
167 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
168
169 #define ME4000_AI_FIFO_COUNT 2048
170
171 #define ME4000_AI_MIN_TICKS 66
172 #define ME4000_AI_MIN_SAMPLE_TIME 2000
173 #define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
174
175 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
176
177 struct me4000_info {
178 unsigned long plx_regbase;
179 unsigned long timer_regbase;
180
181 unsigned int ao_readback[4];
182 };
183
184 enum me4000_boardid {
185 BOARD_ME4650,
186 BOARD_ME4660,
187 BOARD_ME4660I,
188 BOARD_ME4660S,
189 BOARD_ME4660IS,
190 BOARD_ME4670,
191 BOARD_ME4670I,
192 BOARD_ME4670S,
193 BOARD_ME4670IS,
194 BOARD_ME4680,
195 BOARD_ME4680I,
196 BOARD_ME4680S,
197 BOARD_ME4680IS,
198 };
199
200 struct me4000_board {
201 const char *name;
202 int ao_nchan;
203 int ao_fifo;
204 int ai_nchan;
205 int ai_diff_nchan;
206 int ai_sh_nchan;
207 int ex_trig_analog;
208 int dio_nchan;
209 int has_counter;
210 };
211
212 static const struct me4000_board me4000_boards[] = {
213 [BOARD_ME4650] = {
214 .name = "ME-4650",
215 .ai_nchan = 16,
216 .dio_nchan = 32,
217 },
218 [BOARD_ME4660] = {
219 .name = "ME-4660",
220 .ai_nchan = 32,
221 .ai_diff_nchan = 16,
222 .dio_nchan = 32,
223 .has_counter = 1,
224 },
225 [BOARD_ME4660I] = {
226 .name = "ME-4660i",
227 .ai_nchan = 32,
228 .ai_diff_nchan = 16,
229 .dio_nchan = 32,
230 .has_counter = 1,
231 },
232 [BOARD_ME4660S] = {
233 .name = "ME-4660s",
234 .ai_nchan = 32,
235 .ai_diff_nchan = 16,
236 .ai_sh_nchan = 8,
237 .dio_nchan = 32,
238 .has_counter = 1,
239 },
240 [BOARD_ME4660IS] = {
241 .name = "ME-4660is",
242 .ai_nchan = 32,
243 .ai_diff_nchan = 16,
244 .ai_sh_nchan = 8,
245 .dio_nchan = 32,
246 .has_counter = 1,
247 },
248 [BOARD_ME4670] = {
249 .name = "ME-4670",
250 .ao_nchan = 4,
251 .ai_nchan = 32,
252 .ai_diff_nchan = 16,
253 .ex_trig_analog = 1,
254 .dio_nchan = 32,
255 .has_counter = 1,
256 },
257 [BOARD_ME4670I] = {
258 .name = "ME-4670i",
259 .ao_nchan = 4,
260 .ai_nchan = 32,
261 .ai_diff_nchan = 16,
262 .ex_trig_analog = 1,
263 .dio_nchan = 32,
264 .has_counter = 1,
265 },
266 [BOARD_ME4670S] = {
267 .name = "ME-4670s",
268 .ao_nchan = 4,
269 .ai_nchan = 32,
270 .ai_diff_nchan = 16,
271 .ai_sh_nchan = 8,
272 .ex_trig_analog = 1,
273 .dio_nchan = 32,
274 .has_counter = 1,
275 },
276 [BOARD_ME4670IS] = {
277 .name = "ME-4670is",
278 .ao_nchan = 4,
279 .ai_nchan = 32,
280 .ai_diff_nchan = 16,
281 .ai_sh_nchan = 8,
282 .ex_trig_analog = 1,
283 .dio_nchan = 32,
284 .has_counter = 1,
285 },
286 [BOARD_ME4680] = {
287 .name = "ME-4680",
288 .ao_nchan = 4,
289 .ao_fifo = 4,
290 .ai_nchan = 32,
291 .ai_diff_nchan = 16,
292 .ex_trig_analog = 1,
293 .dio_nchan = 32,
294 .has_counter = 1,
295 },
296 [BOARD_ME4680I] = {
297 .name = "ME-4680i",
298 .ao_nchan = 4,
299 .ao_fifo = 4,
300 .ai_nchan = 32,
301 .ai_diff_nchan = 16,
302 .ex_trig_analog = 1,
303 .dio_nchan = 32,
304 .has_counter = 1,
305 },
306 [BOARD_ME4680S] = {
307 .name = "ME-4680s",
308 .ao_nchan = 4,
309 .ao_fifo = 4,
310 .ai_nchan = 32,
311 .ai_diff_nchan = 16,
312 .ai_sh_nchan = 8,
313 .ex_trig_analog = 1,
314 .dio_nchan = 32,
315 .has_counter = 1,
316 },
317 [BOARD_ME4680IS] = {
318 .name = "ME-4680is",
319 .ao_nchan = 4,
320 .ao_fifo = 4,
321 .ai_nchan = 32,
322 .ai_diff_nchan = 16,
323 .ai_sh_nchan = 8,
324 .ex_trig_analog = 1,
325 .dio_nchan = 32,
326 .has_counter = 1,
327 },
328 };
329
330 static const struct comedi_lrange me4000_ai_range = {
331 4, {
332 UNI_RANGE(2.5),
333 UNI_RANGE(10),
334 BIP_RANGE(2.5),
335 BIP_RANGE(10)
336 }
337 };
338
339 #define FIRMWARE_NOT_AVAILABLE 1
340 #if FIRMWARE_NOT_AVAILABLE
341 extern unsigned char *xilinx_firm;
342 #endif
343
344 static int xilinx_download(struct comedi_device *dev)
345 {
346 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
347 struct me4000_info *info = dev->private;
348 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
349 u32 value = 0;
350 wait_queue_head_t queue;
351 int idx = 0;
352 int size = 0;
353 unsigned int intcsr;
354
355 if (!xilinx_iobase)
356 return -ENODEV;
357
358 init_waitqueue_head(&queue);
359
360 /*
361 * Set PLX local interrupt 2 polarity to high.
362 * Interrupt is thrown by init pin of xilinx.
363 */
364 outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
365
366 /* Set /CS and /WRITE of the Xilinx */
367 value = inl(info->plx_regbase + PLX9052_CNTRL);
368 value |= PLX9052_CNTRL_UIO2_DATA;
369 outl(value, info->plx_regbase + PLX9052_CNTRL);
370
371 /* Init Xilinx with CS1 */
372 inb(xilinx_iobase + 0xC8);
373
374 /* Wait until /INIT pin is set */
375 udelay(20);
376 intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
377 if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
378 dev_err(dev->class_dev, "Can't init Xilinx\n");
379 return -EIO;
380 }
381
382 /* Reset /CS and /WRITE of the Xilinx */
383 value = inl(info->plx_regbase + PLX9052_CNTRL);
384 value &= ~PLX9052_CNTRL_UIO2_DATA;
385 outl(value, info->plx_regbase + PLX9052_CNTRL);
386 if (FIRMWARE_NOT_AVAILABLE) {
387 dev_err(dev->class_dev,
388 "xilinx firmware unavailable due to licensing, aborting");
389 return -EIO;
390 } else {
391 /* Download Xilinx firmware */
392 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
393 (xilinx_firm[2] << 8) + xilinx_firm[3];
394 udelay(10);
395
396 for (idx = 0; idx < size; idx++) {
397 outb(xilinx_firm[16 + idx], xilinx_iobase);
398 udelay(10);
399
400 /* Check if BUSY flag is low */
401 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
402 dev_err(dev->class_dev,
403 "Xilinx is still busy (idx = %d)\n",
404 idx);
405 return -EIO;
406 }
407 }
408 }
409
410 /* If done flag is high download was successful */
411 if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
412 } else {
413 dev_err(dev->class_dev, "DONE flag is not set\n");
414 dev_err(dev->class_dev, "Download not successful\n");
415 return -EIO;
416 }
417
418 /* Set /CS and /WRITE */
419 value = inl(info->plx_regbase + PLX9052_CNTRL);
420 value |= PLX9052_CNTRL_UIO2_DATA;
421 outl(value, info->plx_regbase + PLX9052_CNTRL);
422
423 return 0;
424 }
425
426 static void me4000_reset(struct comedi_device *dev)
427 {
428 struct me4000_info *info = dev->private;
429 unsigned int val;
430 int chan;
431
432 /* Make a hardware reset */
433 val = inl(info->plx_regbase + PLX9052_CNTRL);
434 val |= PLX9052_CNTRL_PCI_RESET;
435 outl(val, info->plx_regbase + PLX9052_CNTRL);
436 val &= ~PLX9052_CNTRL_PCI_RESET;
437 outl(val , info->plx_regbase + PLX9052_CNTRL);
438
439 /* 0x8000 to the DACs means an output voltage of 0V */
440 for (chan = 0; chan < 4; chan++)
441 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
442
443 /* Set both stop bits in the analog input control register */
444 outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
445 dev->iobase + ME4000_AI_CTRL_REG);
446
447 /* Set both stop bits in the analog output control register */
448 val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
449 for (chan = 0; chan < 4; chan++)
450 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
451
452 /* Enable interrupts on the PLX */
453 outl(PLX9052_INTCSR_LI1ENAB |
454 PLX9052_INTCSR_LI1POL |
455 PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
456
457 /* Set the adustment register for AO demux */
458 outl(ME4000_AO_DEMUX_ADJUST_VALUE,
459 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
460
461 /*
462 * Set digital I/O direction for port 0
463 * to output on isolated versions
464 */
465 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
466 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
467 }
468
469 /*=============================================================================
470 Analog input section
471 ===========================================================================*/
472
473 static int me4000_ai_insn_read(struct comedi_device *dev,
474 struct comedi_subdevice *subdevice,
475 struct comedi_insn *insn, unsigned int *data)
476 {
477 const struct me4000_board *thisboard = comedi_board(dev);
478 int chan = CR_CHAN(insn->chanspec);
479 int rang = CR_RANGE(insn->chanspec);
480 int aref = CR_AREF(insn->chanspec);
481
482 unsigned int entry = 0;
483 unsigned int tmp;
484 unsigned int lval;
485
486 if (insn->n == 0) {
487 return 0;
488 } else if (insn->n > 1) {
489 dev_err(dev->class_dev, "Invalid instruction length %d\n",
490 insn->n);
491 return -EINVAL;
492 }
493
494 switch (rang) {
495 case 0:
496 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
497 break;
498 case 1:
499 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
500 break;
501 case 2:
502 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
503 break;
504 case 3:
505 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
506 break;
507 default:
508 dev_err(dev->class_dev, "Invalid range specified\n");
509 return -EINVAL;
510 }
511
512 switch (aref) {
513 case AREF_GROUND:
514 case AREF_COMMON:
515 if (chan >= thisboard->ai_nchan) {
516 dev_err(dev->class_dev,
517 "Analog input is not available\n");
518 return -EINVAL;
519 }
520 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
521 break;
522
523 case AREF_DIFF:
524 if (rang == 0 || rang == 1) {
525 dev_err(dev->class_dev,
526 "Range must be bipolar when aref = diff\n");
527 return -EINVAL;
528 }
529
530 if (chan >= thisboard->ai_diff_nchan) {
531 dev_err(dev->class_dev,
532 "Analog input is not available\n");
533 return -EINVAL;
534 }
535 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
536 break;
537 default:
538 dev_err(dev->class_dev, "Invalid aref specified\n");
539 return -EINVAL;
540 }
541
542 entry |= ME4000_AI_LIST_LAST_ENTRY;
543
544 /* Clear channel list, data fifo and both stop bits */
545 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
546 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
547 ME4000_AI_CTRL_BIT_DATA_FIFO |
548 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
549 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
550
551 /* Set the acquisition mode to single */
552 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
553 ME4000_AI_CTRL_BIT_MODE_2);
554 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
555
556 /* Enable channel list and data fifo */
557 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
558 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
559
560 /* Generate channel list entry */
561 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
562
563 /* Set the timer to maximum sample rate */
564 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
565 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
566
567 /* Start conversion by dummy read */
568 inl(dev->iobase + ME4000_AI_START_REG);
569
570 /* Wait until ready */
571 udelay(10);
572 if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
573 ME4000_AI_STATUS_BIT_EF_DATA)) {
574 dev_err(dev->class_dev, "Value not available after wait\n");
575 return -EIO;
576 }
577
578 /* Read value from data fifo */
579 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
580 data[0] = lval ^ 0x8000;
581
582 return 1;
583 }
584
585 static int me4000_ai_cancel(struct comedi_device *dev,
586 struct comedi_subdevice *s)
587 {
588 unsigned int tmp;
589
590 /* Stop any running conversion */
591 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
592 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
593 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
594
595 /* Clear the control register */
596 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
597
598 return 0;
599 }
600
601 static int me4000_ai_check_chanlist(struct comedi_device *dev,
602 struct comedi_subdevice *s,
603 struct comedi_cmd *cmd)
604 {
605 const struct me4000_board *board = comedi_board(dev);
606 unsigned int max_diff_chan = board->ai_diff_nchan;
607 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
608 int i;
609
610 for (i = 0; i < cmd->chanlist_len; i++) {
611 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
612 unsigned int range = CR_RANGE(cmd->chanlist[i]);
613 unsigned int aref = CR_AREF(cmd->chanlist[i]);
614
615 if (aref != aref0) {
616 dev_dbg(dev->class_dev,
617 "Mode is not equal for all entries\n");
618 return -EINVAL;
619 }
620
621 if (aref == SDF_DIFF) {
622 if (chan >= max_diff_chan) {
623 dev_dbg(dev->class_dev,
624 "Channel number to high\n");
625 return -EINVAL;
626 }
627
628 if (!comedi_range_is_bipolar(s, range)) {
629 dev_dbg(dev->class_dev,
630 "Bipolar is not selected in differential mode\n");
631 return -EINVAL;
632 }
633 }
634 }
635
636 return 0;
637 }
638
639 static int ai_round_cmd_args(struct comedi_device *dev,
640 struct comedi_subdevice *s,
641 struct comedi_cmd *cmd,
642 unsigned int *init_ticks,
643 unsigned int *scan_ticks, unsigned int *chan_ticks)
644 {
645
646 int rest;
647
648 *init_ticks = 0;
649 *scan_ticks = 0;
650 *chan_ticks = 0;
651
652 if (cmd->start_arg) {
653 *init_ticks = (cmd->start_arg * 33) / 1000;
654 rest = (cmd->start_arg * 33) % 1000;
655
656 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
657 if (rest > 33)
658 (*init_ticks)++;
659 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
660 if (rest)
661 (*init_ticks)++;
662 }
663 }
664
665 if (cmd->scan_begin_arg) {
666 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
667 rest = (cmd->scan_begin_arg * 33) % 1000;
668
669 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
670 if (rest > 33)
671 (*scan_ticks)++;
672 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
673 if (rest)
674 (*scan_ticks)++;
675 }
676 }
677
678 if (cmd->convert_arg) {
679 *chan_ticks = (cmd->convert_arg * 33) / 1000;
680 rest = (cmd->convert_arg * 33) % 1000;
681
682 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
683 if (rest > 33)
684 (*chan_ticks)++;
685 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
686 if (rest)
687 (*chan_ticks)++;
688 }
689 }
690
691 return 0;
692 }
693
694 static void ai_write_timer(struct comedi_device *dev,
695 unsigned int init_ticks,
696 unsigned int scan_ticks, unsigned int chan_ticks)
697 {
698 outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
699 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
700
701 if (scan_ticks) {
702 outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
703 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
704 }
705
706 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
707 outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
708 }
709
710 static int ai_write_chanlist(struct comedi_device *dev,
711 struct comedi_subdevice *s, struct comedi_cmd *cmd)
712 {
713 unsigned int entry;
714 unsigned int chan;
715 unsigned int rang;
716 unsigned int aref;
717 int i;
718
719 for (i = 0; i < cmd->chanlist_len; i++) {
720 chan = CR_CHAN(cmd->chanlist[i]);
721 rang = CR_RANGE(cmd->chanlist[i]);
722 aref = CR_AREF(cmd->chanlist[i]);
723
724 entry = chan;
725
726 if (rang == 0)
727 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
728 else if (rang == 1)
729 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
730 else if (rang == 2)
731 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
732 else
733 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
734
735 if (aref == SDF_DIFF)
736 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
737 else
738 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
739
740 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
741 }
742
743 return 0;
744 }
745
746 static int ai_prepare(struct comedi_device *dev,
747 struct comedi_subdevice *s,
748 struct comedi_cmd *cmd,
749 unsigned int init_ticks,
750 unsigned int scan_ticks, unsigned int chan_ticks)
751 {
752
753 unsigned int tmp = 0;
754
755 /* Write timer arguments */
756 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
757
758 /* Reset control register */
759 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
760
761 /* Start sources */
762 if ((cmd->start_src == TRIG_EXT &&
763 cmd->scan_begin_src == TRIG_TIMER &&
764 cmd->convert_src == TRIG_TIMER) ||
765 (cmd->start_src == TRIG_EXT &&
766 cmd->scan_begin_src == TRIG_FOLLOW &&
767 cmd->convert_src == TRIG_TIMER)) {
768 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
769 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
770 ME4000_AI_CTRL_BIT_DATA_FIFO;
771 } else if (cmd->start_src == TRIG_EXT &&
772 cmd->scan_begin_src == TRIG_EXT &&
773 cmd->convert_src == TRIG_TIMER) {
774 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
775 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
776 ME4000_AI_CTRL_BIT_DATA_FIFO;
777 } else if (cmd->start_src == TRIG_EXT &&
778 cmd->scan_begin_src == TRIG_EXT &&
779 cmd->convert_src == TRIG_EXT) {
780 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
781 ME4000_AI_CTRL_BIT_MODE_1 |
782 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
783 ME4000_AI_CTRL_BIT_DATA_FIFO;
784 } else {
785 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
786 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
787 ME4000_AI_CTRL_BIT_DATA_FIFO;
788 }
789
790 /* Stop triggers */
791 if (cmd->stop_src == TRIG_COUNT) {
792 outl(cmd->chanlist_len * cmd->stop_arg,
793 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
794 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
795 } else if (cmd->stop_src == TRIG_NONE &&
796 cmd->scan_end_src == TRIG_COUNT) {
797 outl(cmd->scan_end_arg,
798 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
799 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
800 } else {
801 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
802 }
803
804 /* Write the setup to the control register */
805 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
806
807 /* Write the channel list */
808 ai_write_chanlist(dev, s, cmd);
809
810 return 0;
811 }
812
813 static int me4000_ai_do_cmd(struct comedi_device *dev,
814 struct comedi_subdevice *s)
815 {
816 int err;
817 unsigned int init_ticks = 0;
818 unsigned int scan_ticks = 0;
819 unsigned int chan_ticks = 0;
820 struct comedi_cmd *cmd = &s->async->cmd;
821
822 /* Reset the analog input */
823 err = me4000_ai_cancel(dev, s);
824 if (err)
825 return err;
826
827 /* Round the timer arguments */
828 err = ai_round_cmd_args(dev,
829 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
830 if (err)
831 return err;
832
833 /* Prepare the AI for acquisition */
834 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
835 if (err)
836 return err;
837
838 /* Start acquistion by dummy read */
839 inl(dev->iobase + ME4000_AI_START_REG);
840
841 return 0;
842 }
843
844 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
845 struct comedi_subdevice *s,
846 struct comedi_cmd *cmd)
847 {
848
849 unsigned int init_ticks;
850 unsigned int chan_ticks;
851 unsigned int scan_ticks;
852 int err = 0;
853
854 /* Only rounding flags are implemented */
855 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
856
857 /* Round the timer arguments */
858 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
859
860 /* Step 1 : check if triggers are trivially valid */
861
862 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
863 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
864 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
865 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
866 err |= cfc_check_trigger_src(&cmd->scan_end_src,
867 TRIG_NONE | TRIG_COUNT);
868 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
869
870 if (err)
871 return 1;
872
873 /* Step 2a : make sure trigger sources are unique */
874
875 err |= cfc_check_trigger_is_unique(cmd->start_src);
876 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
877 err |= cfc_check_trigger_is_unique(cmd->convert_src);
878 err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
879 err |= cfc_check_trigger_is_unique(cmd->stop_src);
880
881 /* Step 2b : and mutually compatible */
882
883 if (cmd->start_src == TRIG_NOW &&
884 cmd->scan_begin_src == TRIG_TIMER &&
885 cmd->convert_src == TRIG_TIMER) {
886 } else if (cmd->start_src == TRIG_NOW &&
887 cmd->scan_begin_src == TRIG_FOLLOW &&
888 cmd->convert_src == TRIG_TIMER) {
889 } else if (cmd->start_src == TRIG_EXT &&
890 cmd->scan_begin_src == TRIG_TIMER &&
891 cmd->convert_src == TRIG_TIMER) {
892 } else if (cmd->start_src == TRIG_EXT &&
893 cmd->scan_begin_src == TRIG_FOLLOW &&
894 cmd->convert_src == TRIG_TIMER) {
895 } else if (cmd->start_src == TRIG_EXT &&
896 cmd->scan_begin_src == TRIG_EXT &&
897 cmd->convert_src == TRIG_TIMER) {
898 } else if (cmd->start_src == TRIG_EXT &&
899 cmd->scan_begin_src == TRIG_EXT &&
900 cmd->convert_src == TRIG_EXT) {
901 } else {
902 err |= -EINVAL;
903 }
904
905 if (err)
906 return 2;
907
908 /* Step 3: check if arguments are trivially valid */
909
910 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
911
912 if (cmd->chanlist_len < 1) {
913 cmd->chanlist_len = 1;
914 err |= -EINVAL;
915 }
916 if (init_ticks < 66) {
917 cmd->start_arg = 2000;
918 err |= -EINVAL;
919 }
920 if (scan_ticks && scan_ticks < 67) {
921 cmd->scan_begin_arg = 2031;
922 err |= -EINVAL;
923 }
924 if (chan_ticks < 66) {
925 cmd->convert_arg = 2000;
926 err |= -EINVAL;
927 }
928
929 if (err)
930 return 3;
931
932 /*
933 * Stage 4. Check for argument conflicts.
934 */
935 if (cmd->start_src == TRIG_NOW &&
936 cmd->scan_begin_src == TRIG_TIMER &&
937 cmd->convert_src == TRIG_TIMER) {
938
939 /* Check timer arguments */
940 if (init_ticks < ME4000_AI_MIN_TICKS) {
941 dev_err(dev->class_dev, "Invalid start arg\n");
942 cmd->start_arg = 2000; /* 66 ticks at least */
943 err++;
944 }
945 if (chan_ticks < ME4000_AI_MIN_TICKS) {
946 dev_err(dev->class_dev, "Invalid convert arg\n");
947 cmd->convert_arg = 2000; /* 66 ticks at least */
948 err++;
949 }
950 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
951 dev_err(dev->class_dev, "Invalid scan end arg\n");
952
953 /* At least one tick more */
954 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
955 err++;
956 }
957 } else if (cmd->start_src == TRIG_NOW &&
958 cmd->scan_begin_src == TRIG_FOLLOW &&
959 cmd->convert_src == TRIG_TIMER) {
960
961 /* Check timer arguments */
962 if (init_ticks < ME4000_AI_MIN_TICKS) {
963 dev_err(dev->class_dev, "Invalid start arg\n");
964 cmd->start_arg = 2000; /* 66 ticks at least */
965 err++;
966 }
967 if (chan_ticks < ME4000_AI_MIN_TICKS) {
968 dev_err(dev->class_dev, "Invalid convert arg\n");
969 cmd->convert_arg = 2000; /* 66 ticks at least */
970 err++;
971 }
972 } else if (cmd->start_src == TRIG_EXT &&
973 cmd->scan_begin_src == TRIG_TIMER &&
974 cmd->convert_src == TRIG_TIMER) {
975
976 /* Check timer arguments */
977 if (init_ticks < ME4000_AI_MIN_TICKS) {
978 dev_err(dev->class_dev, "Invalid start arg\n");
979 cmd->start_arg = 2000; /* 66 ticks at least */
980 err++;
981 }
982 if (chan_ticks < ME4000_AI_MIN_TICKS) {
983 dev_err(dev->class_dev, "Invalid convert arg\n");
984 cmd->convert_arg = 2000; /* 66 ticks at least */
985 err++;
986 }
987 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
988 dev_err(dev->class_dev, "Invalid scan end arg\n");
989
990 /* At least one tick more */
991 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
992 err++;
993 }
994 } else if (cmd->start_src == TRIG_EXT &&
995 cmd->scan_begin_src == TRIG_FOLLOW &&
996 cmd->convert_src == TRIG_TIMER) {
997
998 /* Check timer arguments */
999 if (init_ticks < ME4000_AI_MIN_TICKS) {
1000 dev_err(dev->class_dev, "Invalid start arg\n");
1001 cmd->start_arg = 2000; /* 66 ticks at least */
1002 err++;
1003 }
1004 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1005 dev_err(dev->class_dev, "Invalid convert arg\n");
1006 cmd->convert_arg = 2000; /* 66 ticks at least */
1007 err++;
1008 }
1009 } else if (cmd->start_src == TRIG_EXT &&
1010 cmd->scan_begin_src == TRIG_EXT &&
1011 cmd->convert_src == TRIG_TIMER) {
1012
1013 /* Check timer arguments */
1014 if (init_ticks < ME4000_AI_MIN_TICKS) {
1015 dev_err(dev->class_dev, "Invalid start arg\n");
1016 cmd->start_arg = 2000; /* 66 ticks at least */
1017 err++;
1018 }
1019 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1020 dev_err(dev->class_dev, "Invalid convert arg\n");
1021 cmd->convert_arg = 2000; /* 66 ticks at least */
1022 err++;
1023 }
1024 } else if (cmd->start_src == TRIG_EXT &&
1025 cmd->scan_begin_src == TRIG_EXT &&
1026 cmd->convert_src == TRIG_EXT) {
1027
1028 /* Check timer arguments */
1029 if (init_ticks < ME4000_AI_MIN_TICKS) {
1030 dev_err(dev->class_dev, "Invalid start arg\n");
1031 cmd->start_arg = 2000; /* 66 ticks at least */
1032 err++;
1033 }
1034 }
1035 if (cmd->stop_src == TRIG_COUNT) {
1036 if (cmd->stop_arg == 0) {
1037 dev_err(dev->class_dev, "Invalid stop arg\n");
1038 cmd->stop_arg = 1;
1039 err++;
1040 }
1041 }
1042 if (cmd->scan_end_src == TRIG_COUNT) {
1043 if (cmd->scan_end_arg == 0) {
1044 dev_err(dev->class_dev, "Invalid scan end arg\n");
1045 cmd->scan_end_arg = 1;
1046 err++;
1047 }
1048 }
1049
1050 if (err)
1051 return 4;
1052
1053 /* Step 5: check channel list if it exists */
1054 if (cmd->chanlist && cmd->chanlist_len > 0)
1055 err |= me4000_ai_check_chanlist(dev, s, cmd);
1056
1057 if (err)
1058 return 5;
1059
1060 return 0;
1061 }
1062
1063 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1064 {
1065 unsigned int tmp;
1066 struct comedi_device *dev = dev_id;
1067 struct comedi_subdevice *s = dev->read_subdev;
1068 int i;
1069 int c = 0;
1070 unsigned int lval;
1071
1072 if (!dev->attached)
1073 return IRQ_NONE;
1074
1075 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1076 ME4000_IRQ_STATUS_BIT_AI_HF) {
1077 /* Read status register to find out what happened */
1078 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1079
1080 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1081 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1082 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1083 c = ME4000_AI_FIFO_COUNT;
1084
1085 /*
1086 * FIFO overflow, so stop conversion
1087 * and disable all interrupts
1088 */
1089 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1090 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1091 ME4000_AI_CTRL_BIT_SC_IRQ);
1092 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1093
1094 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1095
1096 dev_err(dev->class_dev, "FIFO overflow\n");
1097 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1098 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1099 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1100 s->async->events |= COMEDI_CB_BLOCK;
1101
1102 c = ME4000_AI_FIFO_COUNT / 2;
1103 } else {
1104 dev_err(dev->class_dev,
1105 "Can't determine state of fifo\n");
1106 c = 0;
1107
1108 /*
1109 * Undefined state, so stop conversion
1110 * and disable all interrupts
1111 */
1112 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1113 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1114 ME4000_AI_CTRL_BIT_SC_IRQ);
1115 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1116
1117 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1118
1119 dev_err(dev->class_dev, "Undefined FIFO state\n");
1120 }
1121
1122 for (i = 0; i < c; i++) {
1123 /* Read value from data fifo */
1124 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1125 lval ^= 0x8000;
1126
1127 if (!comedi_buf_put(s->async, lval)) {
1128 /*
1129 * Buffer overflow, so stop conversion
1130 * and disable all interrupts
1131 */
1132 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1133 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1134 ME4000_AI_CTRL_BIT_SC_IRQ);
1135 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1136
1137 s->async->events |= COMEDI_CB_OVERFLOW;
1138
1139 dev_err(dev->class_dev, "Buffer overflow\n");
1140
1141 break;
1142 }
1143 }
1144
1145 /* Work is done, so reset the interrupt */
1146 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1147 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1148 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1149 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1150 }
1151
1152 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1153 ME4000_IRQ_STATUS_BIT_SC) {
1154 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1155
1156 /*
1157 * Acquisition is complete, so stop
1158 * conversion and disable all interrupts
1159 */
1160 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1161 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1162 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1163 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1164
1165 /* Poll data until fifo empty */
1166 while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1167 ME4000_AI_STATUS_BIT_EF_DATA) {
1168 /* Read value from data fifo */
1169 lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1170 lval ^= 0x8000;
1171
1172 if (!comedi_buf_put(s->async, lval)) {
1173 dev_err(dev->class_dev, "Buffer overflow\n");
1174 s->async->events |= COMEDI_CB_OVERFLOW;
1175 break;
1176 }
1177 }
1178
1179 /* Work is done, so reset the interrupt */
1180 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1181 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1182 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1183 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1184 }
1185
1186 if (s->async->events)
1187 comedi_event(dev, s);
1188
1189 return IRQ_HANDLED;
1190 }
1191
1192 /*=============================================================================
1193 Analog output section
1194 ===========================================================================*/
1195
1196 static int me4000_ao_insn_write(struct comedi_device *dev,
1197 struct comedi_subdevice *s,
1198 struct comedi_insn *insn, unsigned int *data)
1199 {
1200 const struct me4000_board *thisboard = comedi_board(dev);
1201 struct me4000_info *info = dev->private;
1202 int chan = CR_CHAN(insn->chanspec);
1203 int rang = CR_RANGE(insn->chanspec);
1204 int aref = CR_AREF(insn->chanspec);
1205 unsigned int tmp;
1206
1207 if (insn->n == 0) {
1208 return 0;
1209 } else if (insn->n > 1) {
1210 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1211 insn->n);
1212 return -EINVAL;
1213 }
1214
1215 if (chan >= thisboard->ao_nchan) {
1216 dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
1217 return -EINVAL;
1218 }
1219
1220 if (rang != 0) {
1221 dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
1222 return -EINVAL;
1223 }
1224
1225 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1226 dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
1227 return -EINVAL;
1228 }
1229
1230 /* Stop any running conversion */
1231 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1232 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1233 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1234
1235 /* Clear control register and set to single mode */
1236 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1237
1238 /* Write data value */
1239 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1240
1241 /* Store in the mirror */
1242 info->ao_readback[chan] = data[0];
1243
1244 return 1;
1245 }
1246
1247 static int me4000_ao_insn_read(struct comedi_device *dev,
1248 struct comedi_subdevice *s,
1249 struct comedi_insn *insn, unsigned int *data)
1250 {
1251 struct me4000_info *info = dev->private;
1252 int chan = CR_CHAN(insn->chanspec);
1253
1254 if (insn->n == 0) {
1255 return 0;
1256 } else if (insn->n > 1) {
1257 dev_err(dev->class_dev, "Invalid instruction length\n");
1258 return -EINVAL;
1259 }
1260
1261 data[0] = info->ao_readback[chan];
1262
1263 return 1;
1264 }
1265
1266 static int me4000_dio_insn_bits(struct comedi_device *dev,
1267 struct comedi_subdevice *s,
1268 struct comedi_insn *insn,
1269 unsigned int *data)
1270 {
1271 if (comedi_dio_update_state(s, data)) {
1272 outl((s->state >> 0) & 0xFF,
1273 dev->iobase + ME4000_DIO_PORT_0_REG);
1274 outl((s->state >> 8) & 0xFF,
1275 dev->iobase + ME4000_DIO_PORT_1_REG);
1276 outl((s->state >> 16) & 0xFF,
1277 dev->iobase + ME4000_DIO_PORT_2_REG);
1278 outl((s->state >> 24) & 0xFF,
1279 dev->iobase + ME4000_DIO_PORT_3_REG);
1280 }
1281
1282 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1283 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1284 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1285 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1286
1287 return insn->n;
1288 }
1289
1290 static int me4000_dio_insn_config(struct comedi_device *dev,
1291 struct comedi_subdevice *s,
1292 struct comedi_insn *insn,
1293 unsigned int *data)
1294 {
1295 unsigned int chan = CR_CHAN(insn->chanspec);
1296 unsigned int mask;
1297 unsigned int tmp;
1298 int ret;
1299
1300 if (chan < 8)
1301 mask = 0x000000ff;
1302 else if (chan < 16)
1303 mask = 0x0000ff00;
1304 else if (chan < 24)
1305 mask = 0x00ff0000;
1306 else
1307 mask = 0xff000000;
1308
1309 ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1310 if (ret)
1311 return ret;
1312
1313 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1314 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
1315 ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 |
1316 ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 |
1317 ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
1318 if (s->io_bits & 0x000000ff)
1319 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1320 if (s->io_bits & 0x0000ff00)
1321 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1322 if (s->io_bits & 0x00ff0000)
1323 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1324 if (s->io_bits & 0xff000000)
1325 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1326
1327 /*
1328 * Check for optoisolated ME-4000 version.
1329 * If one the first port is a fixed output
1330 * port and the second is a fixed input port.
1331 */
1332 if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1333 s->io_bits |= 0x000000ff;
1334 s->io_bits &= ~0x0000ff00;
1335 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1336 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1337 ME4000_DIO_CTRL_BIT_MODE_3);
1338 }
1339
1340 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1341
1342 return insn->n;
1343 }
1344
1345 /*=============================================================================
1346 Counter section
1347 ===========================================================================*/
1348
1349 static int me4000_cnt_insn_config(struct comedi_device *dev,
1350 struct comedi_subdevice *s,
1351 struct comedi_insn *insn,
1352 unsigned int *data)
1353 {
1354 struct me4000_info *info = dev->private;
1355 unsigned int chan = CR_CHAN(insn->chanspec);
1356 int err;
1357
1358 switch (data[0]) {
1359 case GPCT_RESET:
1360 if (insn->n != 1)
1361 return -EINVAL;
1362
1363 err = i8254_set_mode(info->timer_regbase, 0, chan,
1364 I8254_MODE0 | I8254_BINARY);
1365 if (err)
1366 return err;
1367 i8254_write(info->timer_regbase, 0, chan, 0);
1368 break;
1369 case GPCT_SET_OPERATION:
1370 if (insn->n != 2)
1371 return -EINVAL;
1372
1373 err = i8254_set_mode(info->timer_regbase, 0, chan,
1374 (data[1] << 1) | I8254_BINARY);
1375 if (err)
1376 return err;
1377 break;
1378 default:
1379 return -EINVAL;
1380 }
1381
1382 return insn->n;
1383 }
1384
1385 static int me4000_cnt_insn_read(struct comedi_device *dev,
1386 struct comedi_subdevice *s,
1387 struct comedi_insn *insn, unsigned int *data)
1388 {
1389 struct me4000_info *info = dev->private;
1390
1391 if (insn->n == 0)
1392 return 0;
1393
1394 if (insn->n > 1) {
1395 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1396 insn->n);
1397 return -EINVAL;
1398 }
1399
1400 data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
1401
1402 return 1;
1403 }
1404
1405 static int me4000_cnt_insn_write(struct comedi_device *dev,
1406 struct comedi_subdevice *s,
1407 struct comedi_insn *insn, unsigned int *data)
1408 {
1409 struct me4000_info *info = dev->private;
1410
1411 if (insn->n == 0) {
1412 return 0;
1413 } else if (insn->n > 1) {
1414 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1415 insn->n);
1416 return -EINVAL;
1417 }
1418
1419 i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
1420
1421 return 1;
1422 }
1423
1424 static int me4000_auto_attach(struct comedi_device *dev,
1425 unsigned long context)
1426 {
1427 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1428 const struct me4000_board *thisboard = NULL;
1429 struct me4000_info *info;
1430 struct comedi_subdevice *s;
1431 int result;
1432
1433 if (context < ARRAY_SIZE(me4000_boards))
1434 thisboard = &me4000_boards[context];
1435 if (!thisboard)
1436 return -ENODEV;
1437 dev->board_ptr = thisboard;
1438 dev->board_name = thisboard->name;
1439
1440 info = comedi_alloc_devpriv(dev, sizeof(*info));
1441 if (!info)
1442 return -ENOMEM;
1443
1444 result = comedi_pci_enable(dev);
1445 if (result)
1446 return result;
1447
1448 info->plx_regbase = pci_resource_start(pcidev, 1);
1449 dev->iobase = pci_resource_start(pcidev, 2);
1450 info->timer_regbase = pci_resource_start(pcidev, 3);
1451 if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1452 return -ENODEV;
1453
1454 result = xilinx_download(dev);
1455 if (result)
1456 return result;
1457
1458 me4000_reset(dev);
1459
1460 if (pcidev->irq > 0) {
1461 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1462 dev->board_name, dev);
1463 if (result == 0)
1464 dev->irq = pcidev->irq;
1465 }
1466
1467 result = comedi_alloc_subdevices(dev, 4);
1468 if (result)
1469 return result;
1470
1471 /*=========================================================================
1472 Analog input subdevice
1473 ========================================================================*/
1474
1475 s = &dev->subdevices[0];
1476
1477 if (thisboard->ai_nchan) {
1478 s->type = COMEDI_SUBD_AI;
1479 s->subdev_flags =
1480 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1481 s->n_chan = thisboard->ai_nchan;
1482 s->maxdata = 0xFFFF; /* 16 bit ADC */
1483 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1484 s->range_table = &me4000_ai_range;
1485 s->insn_read = me4000_ai_insn_read;
1486
1487 if (dev->irq) {
1488 dev->read_subdev = s;
1489 s->subdev_flags |= SDF_CMD_READ;
1490 s->cancel = me4000_ai_cancel;
1491 s->do_cmdtest = me4000_ai_do_cmd_test;
1492 s->do_cmd = me4000_ai_do_cmd;
1493 }
1494 } else {
1495 s->type = COMEDI_SUBD_UNUSED;
1496 }
1497
1498 /*=========================================================================
1499 Analog output subdevice
1500 ========================================================================*/
1501
1502 s = &dev->subdevices[1];
1503
1504 if (thisboard->ao_nchan) {
1505 s->type = COMEDI_SUBD_AO;
1506 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1507 s->n_chan = thisboard->ao_nchan;
1508 s->maxdata = 0xFFFF; /* 16 bit DAC */
1509 s->range_table = &range_bipolar10;
1510 s->insn_write = me4000_ao_insn_write;
1511 s->insn_read = me4000_ao_insn_read;
1512 } else {
1513 s->type = COMEDI_SUBD_UNUSED;
1514 }
1515
1516 /*=========================================================================
1517 Digital I/O subdevice
1518 ========================================================================*/
1519
1520 s = &dev->subdevices[2];
1521
1522 if (thisboard->dio_nchan) {
1523 s->type = COMEDI_SUBD_DIO;
1524 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1525 s->n_chan = thisboard->dio_nchan;
1526 s->maxdata = 1;
1527 s->range_table = &range_digital;
1528 s->insn_bits = me4000_dio_insn_bits;
1529 s->insn_config = me4000_dio_insn_config;
1530 } else {
1531 s->type = COMEDI_SUBD_UNUSED;
1532 }
1533
1534 /*
1535 * Check for optoisolated ME-4000 version. If one the first
1536 * port is a fixed output port and the second is a fixed input port.
1537 */
1538 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1539 s->io_bits |= 0xFF;
1540 outl(ME4000_DIO_CTRL_BIT_MODE_0,
1541 dev->iobase + ME4000_DIO_DIR_REG);
1542 }
1543
1544 /*=========================================================================
1545 Counter subdevice
1546 ========================================================================*/
1547
1548 s = &dev->subdevices[3];
1549
1550 if (thisboard->has_counter) {
1551 s->type = COMEDI_SUBD_COUNTER;
1552 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1553 s->n_chan = 3;
1554 s->maxdata = 0xFFFF; /* 16 bit counters */
1555 s->insn_read = me4000_cnt_insn_read;
1556 s->insn_write = me4000_cnt_insn_write;
1557 s->insn_config = me4000_cnt_insn_config;
1558 } else {
1559 s->type = COMEDI_SUBD_UNUSED;
1560 }
1561
1562 return 0;
1563 }
1564
1565 static void me4000_detach(struct comedi_device *dev)
1566 {
1567 if (dev->irq)
1568 free_irq(dev->irq, dev);
1569 if (dev->iobase)
1570 me4000_reset(dev);
1571 comedi_pci_disable(dev);
1572 }
1573
1574 static struct comedi_driver me4000_driver = {
1575 .driver_name = "me4000",
1576 .module = THIS_MODULE,
1577 .auto_attach = me4000_auto_attach,
1578 .detach = me4000_detach,
1579 };
1580
1581 static int me4000_pci_probe(struct pci_dev *dev,
1582 const struct pci_device_id *id)
1583 {
1584 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1585 }
1586
1587 static const struct pci_device_id me4000_pci_table[] = {
1588 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1589 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1590 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1591 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1592 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1593 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1594 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1595 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1596 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1597 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1598 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1599 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1600 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1601 { 0 }
1602 };
1603 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1604
1605 static struct pci_driver me4000_pci_driver = {
1606 .name = "me4000",
1607 .id_table = me4000_pci_table,
1608 .probe = me4000_pci_probe,
1609 .remove = comedi_pci_auto_unconfig,
1610 };
1611 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1612
1613 MODULE_AUTHOR("Comedi http://www.comedi.org");
1614 MODULE_DESCRIPTION("Comedi low-level driver");
1615 MODULE_LICENSE("GPL");
This page took 0.081079 seconds and 4 git commands to generate.