]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/staging/comedi/drivers/me4000.c
Staging: comedi: Cleanup on dmm32at.c from checkpatch.pl
[mirror_ubuntu-zesty-kernel.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 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23 /*
24 Driver: me4000
25 Description: Meilhaus ME-4000 series boards
26 Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
27 Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
28 Updated: Mon, 18 Mar 2002 15:34:01 -0800
29 Status: broken (no support for loading firmware)
30
31 Supports:
32
33 - Analog Input
34 - Analog Output
35 - Digital I/O
36 - Counter
37
38 Configuration Options:
39
40 [0] - PCI bus number (optional)
41 [1] - PCI slot number (optional)
42
43 If bus/slot is not specified, the first available PCI
44 device will be used.
45
46 The firmware required by these boards is available in the
47 comedi_nonfree_firmware tarball available from
48 http://www.comedi.org. However, the driver's support for
49 loading the firmware through comedi_config is currently
50 broken.
51
52 */
53
54 #include <linux/interrupt.h>
55 #include "../comedidev.h"
56
57 #include <linux/delay.h>
58 #include <linux/list.h>
59 #include <linux/spinlock.h>
60
61 #include "comedi_pci.h"
62 #include "me4000.h"
63 #if 0
64 /* file removed due to GPL incompatibility */
65 #include "me4000_fw.h"
66 #endif
67
68 /*=============================================================================
69 PCI device table.
70 This is used by modprobe to translate PCI IDs to drivers.
71 ===========================================================================*/
72
73 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
74 {
75 PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
76 PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
77 PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
78 PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
79 PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
80 PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
81 PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
82 PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
83 PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
84 PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
85 PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
86 PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
87 PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
88 0}
89 };
90
91 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
92
93 static const struct me4000_board me4000_boards[] = {
94 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} },
95
96 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
97 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
98 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
99 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
100
101 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
102 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
103 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
104 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
105
106 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
107 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
108 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
109 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
110
111 {0},
112 };
113
114 #define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1)
115
116 /*-----------------------------------------------------------------------------
117 Comedi function prototypes
118 ---------------------------------------------------------------------------*/
119 static int me4000_attach(struct comedi_device *dev,
120 struct comedi_devconfig *it);
121 static int me4000_detach(struct comedi_device *dev);
122 static struct comedi_driver driver_me4000 = {
123 driver_name: "me4000",
124 module : THIS_MODULE,
125 attach : me4000_attach,
126 detach : me4000_detach,
127 };
128
129 /*-----------------------------------------------------------------------------
130 Meilhaus function prototypes
131 ---------------------------------------------------------------------------*/
132 static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it);
133 static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
134 static int init_board_info(struct comedi_device *dev,
135 struct pci_dev *pci_dev_p);
136 static int init_ao_context(struct comedi_device *dev);
137 static int init_ai_context(struct comedi_device *dev);
138 static int init_dio_context(struct comedi_device *dev);
139 static int init_cnt_context(struct comedi_device *dev);
140 static int xilinx_download(struct comedi_device *dev);
141 static int reset_board(struct comedi_device *dev);
142
143 static int me4000_dio_insn_bits(struct comedi_device *dev,
144 struct comedi_subdevice *s,
145 struct comedi_insn *insn, unsigned int *data);
146
147 static int me4000_dio_insn_config(struct comedi_device *dev,
148 struct comedi_subdevice *s,
149 struct comedi_insn *insn, unsigned int *data);
150
151 static int cnt_reset(struct comedi_device *dev, unsigned int channel);
152
153 static int cnt_config(struct comedi_device *dev,
154 unsigned int channel, unsigned int mode);
155
156 static int me4000_cnt_insn_config(struct comedi_device *dev,
157 struct comedi_subdevice *s,
158 struct comedi_insn *insn, unsigned int *data);
159
160 static int me4000_cnt_insn_write(struct comedi_device *dev,
161 struct comedi_subdevice *s,
162 struct comedi_insn *insn, unsigned int *data);
163
164 static int me4000_cnt_insn_read(struct comedi_device *dev,
165 struct comedi_subdevice *s,
166 struct comedi_insn *insn, unsigned int *data);
167
168 static int me4000_ai_insn_read(struct comedi_device *dev,
169 struct comedi_subdevice *subdevice,
170 struct comedi_insn *insn, unsigned int *data);
171
172 static int me4000_ai_cancel(struct comedi_device *dev,
173 struct comedi_subdevice *s);
174
175 static int ai_check_chanlist(struct comedi_device *dev,
176 struct comedi_subdevice *s,
177 struct comedi_cmd *cmd);
178
179 static int ai_round_cmd_args(struct comedi_device *dev,
180 struct comedi_subdevice *s,
181 struct comedi_cmd *cmd,
182 unsigned int *init_ticks,
183 unsigned int *scan_ticks,
184 unsigned int *chan_ticks);
185
186 static int ai_prepare(struct comedi_device *dev,
187 struct comedi_subdevice *s,
188 struct comedi_cmd *cmd,
189 unsigned int init_ticks,
190 unsigned int scan_ticks, unsigned int chan_ticks);
191
192 static int ai_write_chanlist(struct comedi_device *dev,
193 struct comedi_subdevice *s,
194 struct comedi_cmd *cmd);
195
196 static irqreturn_t me4000_ai_isr(int irq, void *dev_id);
197
198 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
199 struct comedi_subdevice *s,
200 struct comedi_cmd *cmd);
201
202 static int me4000_ai_do_cmd(struct comedi_device *dev,
203 struct comedi_subdevice *s);
204
205 static int me4000_ao_insn_write(struct comedi_device *dev,
206 struct comedi_subdevice *s,
207 struct comedi_insn *insn, unsigned int *data);
208
209 static int me4000_ao_insn_read(struct comedi_device *dev,
210 struct comedi_subdevice *s,
211 struct comedi_insn *insn, unsigned int *data);
212
213 /*-----------------------------------------------------------------------------
214 Meilhaus inline functions
215 ---------------------------------------------------------------------------*/
216
217 static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
218 unsigned long port)
219 {
220 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
221 outb(value, port);
222 }
223
224 static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
225 unsigned long port)
226 {
227 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
228 outl(value, port);
229 }
230
231 static inline unsigned long me4000_inl(struct comedi_device *dev,
232 unsigned long port)
233 {
234 unsigned long value;
235 value = inl(port);
236 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
237 return value;
238 }
239
240 static inline unsigned char me4000_inb(struct comedi_device *dev,
241 unsigned long port)
242 {
243 unsigned char value;
244 value = inb(port);
245 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
246 return value;
247 }
248
249 static const struct comedi_lrange me4000_ai_range = {
250 4,
251 {
252 UNI_RANGE(2.5),
253 UNI_RANGE(10),
254 BIP_RANGE(2.5),
255 BIP_RANGE(10),
256 }
257 };
258
259 static const struct comedi_lrange me4000_ao_range = {
260 1,
261 {
262 BIP_RANGE(10),
263 }
264 };
265
266 static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
267 {
268 struct comedi_subdevice *s;
269 int result;
270
271 CALL_PDEBUG("In me4000_attach()\n");
272
273 result = me4000_probe(dev, it);
274 if (result)
275 return result;
276
277 /*
278 * Allocate the subdevice structures. alloc_subdevice() is a
279 * convenient macro defined in comedidev.h. It relies on
280 * n_subdevices being set correctly.
281 */
282 if (alloc_subdevices(dev, 4) < 0)
283 return -ENOMEM;
284
285 /*=========================================================================
286 Analog input subdevice
287 ========================================================================*/
288
289 s = dev->subdevices + 0;
290
291 if (thisboard->ai.count) {
292 s->type = COMEDI_SUBD_AI;
293 s->subdev_flags =
294 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
295 s->n_chan = thisboard->ai.count;
296 s->maxdata = 0xFFFF; /* 16 bit ADC */
297 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
298 s->range_table = &me4000_ai_range;
299 s->insn_read = me4000_ai_insn_read;
300
301 if (info->irq > 0) {
302 if (request_irq(info->irq, me4000_ai_isr,
303 IRQF_SHARED, "ME-4000", dev)) {
304 printk
305 ("comedi%d: me4000: me4000_attach(): "
306 "Unable to allocate irq\n", dev->minor);
307 } else {
308 dev->read_subdev = s;
309 s->subdev_flags |= SDF_CMD_READ;
310 s->cancel = me4000_ai_cancel;
311 s->do_cmdtest = me4000_ai_do_cmd_test;
312 s->do_cmd = me4000_ai_do_cmd;
313 }
314 } else {
315 printk(KERN_WARNING
316 "comedi%d: me4000: me4000_attach(): "
317 "No interrupt available\n", dev->minor);
318 }
319 } else {
320 s->type = COMEDI_SUBD_UNUSED;
321 }
322
323 /*=========================================================================
324 Analog output subdevice
325 ========================================================================*/
326
327 s = dev->subdevices + 1;
328
329 if (thisboard->ao.count) {
330 s->type = COMEDI_SUBD_AO;
331 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
332 s->n_chan = thisboard->ao.count;
333 s->maxdata = 0xFFFF; /* 16 bit DAC */
334 s->range_table = &me4000_ao_range;
335 s->insn_write = me4000_ao_insn_write;
336 s->insn_read = me4000_ao_insn_read;
337 } else {
338 s->type = COMEDI_SUBD_UNUSED;
339 }
340
341 /*=========================================================================
342 Digital I/O subdevice
343 ========================================================================*/
344
345 s = dev->subdevices + 2;
346
347 if (thisboard->dio.count) {
348 s->type = COMEDI_SUBD_DIO;
349 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
350 s->n_chan = thisboard->dio.count * 8;
351 s->maxdata = 1;
352 s->range_table = &range_digital;
353 s->insn_bits = me4000_dio_insn_bits;
354 s->insn_config = me4000_dio_insn_config;
355 } else {
356 s->type = COMEDI_SUBD_UNUSED;
357 }
358
359 /*
360 * Check for optoisolated ME-4000 version. If one the first
361 * port is a fixed output port and the second is a fixed input port.
362 */
363 if (!me4000_inl(dev, info->dio_context.dir_reg)) {
364 s->io_bits |= 0xFF;
365 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
366 info->dio_context.dir_reg);
367 }
368
369 /*=========================================================================
370 Counter subdevice
371 ========================================================================*/
372
373 s = dev->subdevices + 3;
374
375 if (thisboard->cnt.count) {
376 s->type = COMEDI_SUBD_COUNTER;
377 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
378 s->n_chan = thisboard->cnt.count;
379 s->maxdata = 0xFFFF; /* 16 bit counters */
380 s->insn_read = me4000_cnt_insn_read;
381 s->insn_write = me4000_cnt_insn_write;
382 s->insn_config = me4000_cnt_insn_config;
383 } else {
384 s->type = COMEDI_SUBD_UNUSED;
385 }
386
387 return 0;
388 }
389
390 static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
391 {
392 struct pci_dev *pci_device;
393 int result, i;
394 struct me4000_board *board;
395
396 CALL_PDEBUG("In me4000_probe()\n");
397
398 /* Allocate private memory */
399 if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
400 return -ENOMEM;
401
402 /*
403 * Probe the device to determine what device in the series it is.
404 */
405 for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
406 pci_device != NULL;
407 pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
408 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
409 for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
410 if (me4000_boards[i].device_id ==
411 pci_device->device) {
412 /*
413 * Was a particular
414 * bus/slot requested?
415 */
416 if ((it->options[0] != 0)
417 || (it->options[1] != 0)) {
418 /*
419 * Are we on the wrong
420 * bus/slot?
421 */
422 if (pci_device->bus->number !=
423 it->options[0]
424 ||
425 PCI_SLOT(pci_device->devfn)
426 != it->options[1]) {
427 continue;
428 }
429 }
430 dev->board_ptr = me4000_boards + i;
431 board =
432 (struct me4000_board *)
433 dev->board_ptr;
434 info->pci_dev_p = pci_device;
435 goto found;
436 }
437 }
438 }
439 }
440
441 printk(KERN_ERR
442 "comedi%d: me4000: me4000_probe(): "
443 "No supported board found (req. bus/slot : %d/%d)\n",
444 dev->minor, it->options[0], it->options[1]);
445 return -ENODEV;
446
447 found:
448
449 printk(KERN_INFO
450 "comedi%d: me4000: me4000_probe(): "
451 "Found %s at PCI bus %d, slot %d\n",
452 dev->minor, me4000_boards[i].name, pci_device->bus->number,
453 PCI_SLOT(pci_device->devfn));
454
455 /* Set data in device structure */
456 dev->board_name = board->name;
457
458 /* Enable PCI device and request regions */
459 result = comedi_pci_enable(pci_device, dev->board_name);
460 if (result) {
461 printk(KERN_ERR
462 "comedi%d: me4000: me4000_probe(): Cannot enable PCI "
463 "device and request I/O regions\n", dev->minor);
464 return result;
465 }
466
467 /* Get the PCI base registers */
468 result = get_registers(dev, pci_device);
469 if (result) {
470 printk(KERN_ERR
471 "comedi%d: me4000: me4000_probe(): "
472 "Cannot get registers\n", dev->minor);
473 return result;
474 }
475 /* Initialize board info */
476 result = init_board_info(dev, pci_device);
477 if (result) {
478 printk(KERN_ERR
479 "comedi%d: me4000: me4000_probe(): "
480 "Cannot init baord info\n", dev->minor);
481 return result;
482 }
483
484 /* Init analog output context */
485 result = init_ao_context(dev);
486 if (result) {
487 printk(KERN_ERR
488 "comedi%d: me4000: me4000_probe(): "
489 "Cannot init ao context\n", dev->minor);
490 return result;
491 }
492
493 /* Init analog input context */
494 result = init_ai_context(dev);
495 if (result) {
496 printk(KERN_ERR
497 "comedi%d: me4000: me4000_probe(): "
498 "Cannot init ai context\n", dev->minor);
499 return result;
500 }
501
502 /* Init digital I/O context */
503 result = init_dio_context(dev);
504 if (result) {
505 printk(KERN_ERR
506 "comedi%d: me4000: me4000_probe(): "
507 "Cannot init dio context\n", dev->minor);
508 return result;
509 }
510
511 /* Init counter context */
512 result = init_cnt_context(dev);
513 if (result) {
514 printk(KERN_ERR
515 "comedi%d: me4000: me4000_probe(): "
516 "Cannot init cnt context\n", dev->minor);
517 return result;
518 }
519
520 /* Download the xilinx firmware */
521 result = xilinx_download(dev);
522 if (result) {
523 printk(KERN_ERR
524 "comedi%d: me4000: me4000_probe(): "
525 "Can't download firmware\n", dev->minor);
526 return result;
527 }
528
529 /* Make a hardware reset */
530 result = reset_board(dev);
531 if (result) {
532 printk(KERN_ERR
533 "comedi%d: me4000: me4000_probe(): Can't reset board\n",
534 dev->minor);
535 return result;
536 }
537
538 return 0;
539 }
540
541 static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
542 {
543
544 CALL_PDEBUG("In get_registers()\n");
545
546 /*--------------------------- plx regbase -------------------------------*/
547
548 info->plx_regbase = pci_resource_start(pci_dev_p, 1);
549 if (info->plx_regbase == 0) {
550 printk(KERN_ERR
551 "comedi%d: me4000: get_registers(): "
552 "PCI base address 1 is not available\n", dev->minor);
553 return -ENODEV;
554 }
555 info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
556
557 /*--------------------------- me4000 regbase ----------------------------*/
558
559 info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
560 if (info->me4000_regbase == 0) {
561 printk(KERN_ERR
562 "comedi%d: me4000: get_registers(): "
563 "PCI base address 2 is not available\n", dev->minor);
564 return -ENODEV;
565 }
566 info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
567
568 /*--------------------------- timer regbase ------------------------------*/
569
570 info->timer_regbase = pci_resource_start(pci_dev_p, 3);
571 if (info->timer_regbase == 0) {
572 printk(KERN_ERR
573 "comedi%d: me4000: get_registers(): "
574 "PCI base address 3 is not available\n", dev->minor);
575 return -ENODEV;
576 }
577 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
578
579 /*--------------------------- program regbase ----------------------------*/
580
581 info->program_regbase = pci_resource_start(pci_dev_p, 5);
582 if (info->program_regbase == 0) {
583 printk(KERN_ERR
584 "comedi%d: me4000: get_registers(): "
585 "PCI base address 5 is not available\n", dev->minor);
586 return -ENODEV;
587 }
588 info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
589
590 return 0;
591 }
592
593 static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
594 {
595 int result;
596
597 CALL_PDEBUG("In init_board_info()\n");
598
599 /* Init spin locks */
600 /* spin_lock_init(&info->preload_lock); */
601 /* spin_lock_init(&info->ai_ctrl_lock); */
602
603 /* Get the serial number */
604 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
605 if (result != PCIBIOS_SUCCESSFUL)
606 return result;
607
608 /* Get the hardware revision */
609 result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
610 if (result != PCIBIOS_SUCCESSFUL)
611 return result;
612
613 /* Get the vendor id */
614 info->vendor_id = pci_dev_p->vendor;
615
616 /* Get the device id */
617 info->device_id = pci_dev_p->device;
618
619 /* Get the irq assigned to the board */
620 info->irq = pci_dev_p->irq;
621
622 return 0;
623 }
624
625 static int init_ao_context(struct comedi_device *dev)
626 {
627 int i;
628
629 CALL_PDEBUG("In init_ao_context()\n");
630
631 for (i = 0; i < thisboard->ao.count; i++) {
632 /* spin_lock_init(&info->ao_context[i].use_lock); */
633 info->ao_context[i].irq = info->irq;
634
635 switch (i) {
636 case 0:
637 info->ao_context[i].ctrl_reg =
638 info->me4000_regbase + ME4000_AO_00_CTRL_REG;
639 info->ao_context[i].status_reg =
640 info->me4000_regbase + ME4000_AO_00_STATUS_REG;
641 info->ao_context[i].fifo_reg =
642 info->me4000_regbase + ME4000_AO_00_FIFO_REG;
643 info->ao_context[i].single_reg =
644 info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
645 info->ao_context[i].timer_reg =
646 info->me4000_regbase + ME4000_AO_00_TIMER_REG;
647 info->ao_context[i].irq_status_reg =
648 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
649 info->ao_context[i].preload_reg =
650 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
651 break;
652 case 1:
653 info->ao_context[i].ctrl_reg =
654 info->me4000_regbase + ME4000_AO_01_CTRL_REG;
655 info->ao_context[i].status_reg =
656 info->me4000_regbase + ME4000_AO_01_STATUS_REG;
657 info->ao_context[i].fifo_reg =
658 info->me4000_regbase + ME4000_AO_01_FIFO_REG;
659 info->ao_context[i].single_reg =
660 info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
661 info->ao_context[i].timer_reg =
662 info->me4000_regbase + ME4000_AO_01_TIMER_REG;
663 info->ao_context[i].irq_status_reg =
664 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
665 info->ao_context[i].preload_reg =
666 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
667 break;
668 case 2:
669 info->ao_context[i].ctrl_reg =
670 info->me4000_regbase + ME4000_AO_02_CTRL_REG;
671 info->ao_context[i].status_reg =
672 info->me4000_regbase + ME4000_AO_02_STATUS_REG;
673 info->ao_context[i].fifo_reg =
674 info->me4000_regbase + ME4000_AO_02_FIFO_REG;
675 info->ao_context[i].single_reg =
676 info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
677 info->ao_context[i].timer_reg =
678 info->me4000_regbase + ME4000_AO_02_TIMER_REG;
679 info->ao_context[i].irq_status_reg =
680 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
681 info->ao_context[i].preload_reg =
682 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
683 break;
684 case 3:
685 info->ao_context[i].ctrl_reg =
686 info->me4000_regbase + ME4000_AO_03_CTRL_REG;
687 info->ao_context[i].status_reg =
688 info->me4000_regbase + ME4000_AO_03_STATUS_REG;
689 info->ao_context[i].fifo_reg =
690 info->me4000_regbase + ME4000_AO_03_FIFO_REG;
691 info->ao_context[i].single_reg =
692 info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
693 info->ao_context[i].timer_reg =
694 info->me4000_regbase + ME4000_AO_03_TIMER_REG;
695 info->ao_context[i].irq_status_reg =
696 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
697 info->ao_context[i].preload_reg =
698 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
699 break;
700 default:
701 break;
702 }
703 }
704
705 return 0;
706 }
707
708 static int init_ai_context(struct comedi_device *dev)
709 {
710
711 CALL_PDEBUG("In init_ai_context()\n");
712
713 info->ai_context.irq = info->irq;
714
715 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
716 info->ai_context.status_reg =
717 info->me4000_regbase + ME4000_AI_STATUS_REG;
718 info->ai_context.channel_list_reg =
719 info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
720 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
721 info->ai_context.chan_timer_reg =
722 info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
723 info->ai_context.chan_pre_timer_reg =
724 info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
725 info->ai_context.scan_timer_low_reg =
726 info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
727 info->ai_context.scan_timer_high_reg =
728 info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
729 info->ai_context.scan_pre_timer_low_reg =
730 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
731 info->ai_context.scan_pre_timer_high_reg =
732 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
733 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
734 info->ai_context.irq_status_reg =
735 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
736 info->ai_context.sample_counter_reg =
737 info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
738
739 return 0;
740 }
741
742 static int init_dio_context(struct comedi_device *dev)
743 {
744
745 CALL_PDEBUG("In init_dio_context()\n");
746
747 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
748 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
749 info->dio_context.port_0_reg =
750 info->me4000_regbase + ME4000_DIO_PORT_0_REG;
751 info->dio_context.port_1_reg =
752 info->me4000_regbase + ME4000_DIO_PORT_1_REG;
753 info->dio_context.port_2_reg =
754 info->me4000_regbase + ME4000_DIO_PORT_2_REG;
755 info->dio_context.port_3_reg =
756 info->me4000_regbase + ME4000_DIO_PORT_3_REG;
757
758 return 0;
759 }
760
761 static int init_cnt_context(struct comedi_device *dev)
762 {
763
764 CALL_PDEBUG("In init_cnt_context()\n");
765
766 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
767 info->cnt_context.counter_0_reg =
768 info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
769 info->cnt_context.counter_1_reg =
770 info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
771 info->cnt_context.counter_2_reg =
772 info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
773
774 return 0;
775 }
776
777 #define FIRMWARE_NOT_AVAILABLE 1
778 #if FIRMWARE_NOT_AVAILABLE
779 extern unsigned char *xilinx_firm;
780 #endif
781
782 static int xilinx_download(struct comedi_device *dev)
783 {
784 u32 value = 0;
785 wait_queue_head_t queue;
786 int idx = 0;
787 int size = 0;
788
789 CALL_PDEBUG("In xilinx_download()\n");
790
791 init_waitqueue_head(&queue);
792
793 /*
794 * Set PLX local interrupt 2 polarity to high.
795 * Interrupt is thrown by init pin of xilinx.
796 */
797 outl(0x10, info->plx_regbase + PLX_INTCSR);
798
799 /* Set /CS and /WRITE of the Xilinx */
800 value = inl(info->plx_regbase + PLX_ICR);
801 value |= 0x100;
802 outl(value, info->plx_regbase + PLX_ICR);
803
804 /* Init Xilinx with CS1 */
805 inb(info->program_regbase + 0xC8);
806
807 /* Wait until /INIT pin is set */
808 udelay(20);
809 if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
810 printk(KERN_ERR
811 "comedi%d: me4000: xilinx_download(): "
812 "Can't init Xilinx\n", dev->minor);
813 return -EIO;
814 }
815
816 /* Reset /CS and /WRITE of the Xilinx */
817 value = inl(info->plx_regbase + PLX_ICR);
818 value &= ~0x100;
819 outl(value, info->plx_regbase + PLX_ICR);
820 if (FIRMWARE_NOT_AVAILABLE) {
821 comedi_error(dev, "xilinx firmware unavailable "
822 "due to licensing, aborting");
823 return -EIO;
824 } else {
825 /* Download Xilinx firmware */
826 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
827 (xilinx_firm[2] << 8) + xilinx_firm[3];
828 udelay(10);
829
830 for (idx = 0; idx < size; idx++) {
831 outb(xilinx_firm[16 + idx], info->program_regbase);
832 udelay(10);
833
834 /* Check if BUSY flag is low */
835 if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
836 printk(KERN_ERR
837 "comedi%d: me4000: xilinx_download(): "
838 "Xilinx is still busy (idx = %d)\n",
839 dev->minor, idx);
840 return -EIO;
841 }
842 }
843 }
844
845 /* If done flag is high download was successful */
846 if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
847 } else {
848 printk(KERN_ERR
849 "comedi%d: me4000: xilinx_download(): "
850 "DONE flag is not set\n", dev->minor);
851 printk(KERN_ERR
852 "comedi%d: me4000: xilinx_download(): "
853 "Download not successful\n", dev->minor);
854 return -EIO;
855 }
856
857 /* Set /CS and /WRITE */
858 value = inl(info->plx_regbase + PLX_ICR);
859 value |= 0x100;
860 outl(value, info->plx_regbase + PLX_ICR);
861
862 return 0;
863 }
864
865 static int reset_board(struct comedi_device *dev)
866 {
867 unsigned long icr;
868
869 CALL_PDEBUG("In reset_board()\n");
870
871 /* Make a hardware reset */
872 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
873 icr |= 0x40000000;
874 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
875 icr &= ~0x40000000;
876 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
877
878 /* 0x8000 to the DACs means an output voltage of 0V */
879 me4000_outl(dev, 0x8000,
880 info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
881 me4000_outl(dev, 0x8000,
882 info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
883 me4000_outl(dev, 0x8000,
884 info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
885 me4000_outl(dev, 0x8000,
886 info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
887
888 /* Set both stop bits in the analog input control register */
889 me4000_outl(dev,
890 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
891 info->me4000_regbase + ME4000_AI_CTRL_REG);
892
893 /* Set both stop bits in the analog output control register */
894 me4000_outl(dev,
895 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
896 info->me4000_regbase + ME4000_AO_00_CTRL_REG);
897 me4000_outl(dev,
898 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
899 info->me4000_regbase + ME4000_AO_01_CTRL_REG);
900 me4000_outl(dev,
901 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
902 info->me4000_regbase + ME4000_AO_02_CTRL_REG);
903 me4000_outl(dev,
904 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
905 info->me4000_regbase + ME4000_AO_03_CTRL_REG);
906
907 /* Enable interrupts on the PLX */
908 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
909
910 /* Set the adustment register for AO demux */
911 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
912 info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
913
914 /*
915 * Set digital I/O direction for port 0
916 * to output on isolated versions
917 */
918 if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
919 me4000_outl(dev, 0x1,
920 info->me4000_regbase + ME4000_DIO_CTRL_REG);
921 }
922
923 return 0;
924 }
925
926 static int me4000_detach(struct comedi_device *dev)
927 {
928 CALL_PDEBUG("In me4000_detach()\n");
929
930 if (info) {
931 if (info->pci_dev_p) {
932 reset_board(dev);
933 if (info->plx_regbase)
934 comedi_pci_disable(info->pci_dev_p);
935 pci_dev_put(info->pci_dev_p);
936 }
937 }
938
939 return 0;
940 }
941
942 /*=============================================================================
943 Analog input section
944 ===========================================================================*/
945
946 static int me4000_ai_insn_read(struct comedi_device *dev,
947 struct comedi_subdevice *subdevice,
948 struct comedi_insn *insn, unsigned int *data)
949 {
950
951 int chan = CR_CHAN(insn->chanspec);
952 int rang = CR_RANGE(insn->chanspec);
953 int aref = CR_AREF(insn->chanspec);
954
955 unsigned long entry = 0;
956 unsigned long tmp;
957 long lval;
958
959 CALL_PDEBUG("In me4000_ai_insn_read()\n");
960
961 if (insn->n == 0) {
962 return 0;
963 } else if (insn->n > 1) {
964 printk(KERN_ERR
965 "comedi%d: me4000: me4000_ai_insn_read(): "
966 "Invalid instruction length %d\n", dev->minor, insn->n);
967 return -EINVAL;
968 }
969
970 switch (rang) {
971 case 0:
972 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
973 break;
974 case 1:
975 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
976 break;
977 case 2:
978 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
979 break;
980 case 3:
981 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
982 break;
983 default:
984 printk(KERN_ERR
985 "comedi%d: me4000: me4000_ai_insn_read(): "
986 "Invalid range specified\n", dev->minor);
987 return -EINVAL;
988 }
989
990 switch (aref) {
991 case AREF_GROUND:
992 case AREF_COMMON:
993 if (chan >= thisboard->ai.count) {
994 printk(KERN_ERR
995 "comedi%d: me4000: me4000_ai_insn_read(): "
996 "Analog input is not available\n", dev->minor);
997 return -EINVAL;
998 }
999 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
1000 break;
1001
1002 case AREF_DIFF:
1003 if (rang == 0 || rang == 1) {
1004 printk(KERN_ERR
1005 "comedi%d: me4000: me4000_ai_insn_read(): "
1006 "Range must be bipolar when aref = diff\n",
1007 dev->minor);
1008 return -EINVAL;
1009 }
1010
1011 if (chan >= thisboard->ai.diff_count) {
1012 printk(KERN_ERR
1013 "comedi%d: me4000: me4000_ai_insn_read(): "
1014 "Analog input is not available\n", dev->minor);
1015 return -EINVAL;
1016 }
1017 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
1018 break;
1019 default:
1020 printk(KERN_ERR
1021 "comedi%d: me4000: me4000_ai_insn_read(): "
1022 "Invalid aref specified\n", dev->minor);
1023 return -EINVAL;
1024 }
1025
1026 entry |= ME4000_AI_LIST_LAST_ENTRY;
1027
1028 /* Clear channel list, data fifo and both stop bits */
1029 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1030 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1031 ME4000_AI_CTRL_BIT_DATA_FIFO |
1032 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1033 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1034
1035 /* Set the acquisition mode to single */
1036 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
1037 ME4000_AI_CTRL_BIT_MODE_2);
1038 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1039
1040 /* Enable channel list and data fifo */
1041 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
1042 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1043
1044 /* Generate channel list entry */
1045 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1046
1047 /* Set the timer to maximum sample rate */
1048 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
1049 me4000_outl(dev, ME4000_AI_MIN_TICKS,
1050 info->ai_context.chan_pre_timer_reg);
1051
1052 /* Start conversion by dummy read */
1053 me4000_inl(dev, info->ai_context.start_reg);
1054
1055 /* Wait until ready */
1056 udelay(10);
1057 if (!
1058 (me4000_inl(dev, info->ai_context.status_reg) &
1059 ME4000_AI_STATUS_BIT_EF_DATA)) {
1060 printk(KERN_ERR
1061 "comedi%d: me4000: me4000_ai_insn_read(): "
1062 "Value not available after wait\n", dev->minor);
1063 return -EIO;
1064 }
1065
1066 /* Read value from data fifo */
1067 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
1068 data[0] = lval ^ 0x8000;
1069
1070 return 1;
1071 }
1072
1073 static int me4000_ai_cancel(struct comedi_device *dev,
1074 struct comedi_subdevice *s)
1075 {
1076 unsigned long tmp;
1077
1078 CALL_PDEBUG("In me4000_ai_cancel()\n");
1079
1080 /* Stop any running conversion */
1081 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1082 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1083 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1084
1085 /* Clear the control register */
1086 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1087
1088 return 0;
1089 }
1090
1091 static int ai_check_chanlist(struct comedi_device *dev,
1092 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1093 {
1094 int aref;
1095 int i;
1096
1097 CALL_PDEBUG("In ai_check_chanlist()\n");
1098
1099 /* Check whether a channel list is available */
1100 if (!cmd->chanlist_len) {
1101 printk(KERN_ERR
1102 "comedi%d: me4000: ai_check_chanlist(): "
1103 "No channel list available\n", dev->minor);
1104 return -EINVAL;
1105 }
1106
1107 /* Check the channel list size */
1108 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
1109 printk(KERN_ERR
1110 "comedi%d: me4000: ai_check_chanlist(): "
1111 "Channel list is to large\n", dev->minor);
1112 return -EINVAL;
1113 }
1114
1115 /* Check the pointer */
1116 if (!cmd->chanlist) {
1117 printk(KERN_ERR
1118 "comedi%d: me4000: ai_check_chanlist(): "
1119 "NULL pointer to channel list\n", dev->minor);
1120 return -EFAULT;
1121 }
1122
1123 /* Check whether aref is equal for all entries */
1124 aref = CR_AREF(cmd->chanlist[0]);
1125 for (i = 0; i < cmd->chanlist_len; i++) {
1126 if (CR_AREF(cmd->chanlist[i]) != aref) {
1127 printk(KERN_ERR
1128 "comedi%d: me4000: ai_check_chanlist(): "
1129 "Mode is not equal for all entries\n",
1130 dev->minor);
1131 return -EINVAL;
1132 }
1133 }
1134
1135 /* Check whether channels are available for this ending */
1136 if (aref == SDF_DIFF) {
1137 for (i = 0; i < cmd->chanlist_len; i++) {
1138 if (CR_CHAN(cmd->chanlist[i]) >=
1139 thisboard->ai.diff_count) {
1140 printk(KERN_ERR
1141 "comedi%d: me4000: ai_check_chanlist():"
1142 " Channel number to high\n", dev->minor);
1143 return -EINVAL;
1144 }
1145 }
1146 } else {
1147 for (i = 0; i < cmd->chanlist_len; i++) {
1148 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
1149 printk(KERN_ERR
1150 "comedi%d: me4000: ai_check_chanlist(): "
1151 "Channel number to high\n", dev->minor);
1152 return -EINVAL;
1153 }
1154 }
1155 }
1156
1157 /* Check if bipolar is set for all entries when in differential mode */
1158 if (aref == SDF_DIFF) {
1159 for (i = 0; i < cmd->chanlist_len; i++) {
1160 if (CR_RANGE(cmd->chanlist[i]) != 1 &&
1161 CR_RANGE(cmd->chanlist[i]) != 2) {
1162 printk(KERN_ERR
1163 "comedi%d: me4000: ai_check_chanlist(): "
1164 "Bipolar is not selected in "
1165 "differential mode\n",
1166 dev->minor);
1167 return -EINVAL;
1168 }
1169 }
1170 }
1171
1172 return 0;
1173 }
1174
1175 static int ai_round_cmd_args(struct comedi_device *dev,
1176 struct comedi_subdevice *s,
1177 struct comedi_cmd *cmd,
1178 unsigned int *init_ticks,
1179 unsigned int *scan_ticks, unsigned int *chan_ticks)
1180 {
1181
1182 int rest;
1183
1184 CALL_PDEBUG("In ai_round_cmd_args()\n");
1185
1186 *init_ticks = 0;
1187 *scan_ticks = 0;
1188 *chan_ticks = 0;
1189
1190 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1191 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1192 cmd->scan_begin_arg);
1193 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1194
1195 if (cmd->start_arg) {
1196 *init_ticks = (cmd->start_arg * 33) / 1000;
1197 rest = (cmd->start_arg * 33) % 1000;
1198
1199 if (cmd->flags & TRIG_ROUND_NEAREST) {
1200 if (rest > 33)
1201 (*init_ticks)++;
1202 } else if (cmd->flags & TRIG_ROUND_UP) {
1203 if (rest)
1204 (*init_ticks)++;
1205 }
1206 }
1207
1208 if (cmd->scan_begin_arg) {
1209 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1210 rest = (cmd->scan_begin_arg * 33) % 1000;
1211
1212 if (cmd->flags & TRIG_ROUND_NEAREST) {
1213 if (rest > 33)
1214 (*scan_ticks)++;
1215 } else if (cmd->flags & TRIG_ROUND_UP) {
1216 if (rest)
1217 (*scan_ticks)++;
1218 }
1219 }
1220
1221 if (cmd->convert_arg) {
1222 *chan_ticks = (cmd->convert_arg * 33) / 1000;
1223 rest = (cmd->convert_arg * 33) % 1000;
1224
1225 if (cmd->flags & TRIG_ROUND_NEAREST) {
1226 if (rest > 33)
1227 (*chan_ticks)++;
1228 } else if (cmd->flags & TRIG_ROUND_UP) {
1229 if (rest)
1230 (*chan_ticks)++;
1231 }
1232 }
1233
1234 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1235 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1236 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1237
1238 return 0;
1239 }
1240
1241 static void ai_write_timer(struct comedi_device *dev,
1242 unsigned int init_ticks,
1243 unsigned int scan_ticks, unsigned int chan_ticks)
1244 {
1245
1246 CALL_PDEBUG("In ai_write_timer()\n");
1247
1248 me4000_outl(dev, init_ticks - 1,
1249 info->ai_context.scan_pre_timer_low_reg);
1250 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1251
1252 if (scan_ticks) {
1253 me4000_outl(dev, scan_ticks - 1,
1254 info->ai_context.scan_timer_low_reg);
1255 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1256 }
1257
1258 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1259 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1260 }
1261
1262 static int ai_prepare(struct comedi_device *dev,
1263 struct comedi_subdevice *s,
1264 struct comedi_cmd *cmd,
1265 unsigned int init_ticks,
1266 unsigned int scan_ticks, unsigned int chan_ticks)
1267 {
1268
1269 unsigned long tmp = 0;
1270
1271 CALL_PDEBUG("In ai_prepare()\n");
1272
1273 /* Write timer arguments */
1274 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1275
1276 /* Reset control register */
1277 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1278
1279 /* Start sources */
1280 if ((cmd->start_src == TRIG_EXT &&
1281 cmd->scan_begin_src == TRIG_TIMER &&
1282 cmd->convert_src == TRIG_TIMER) ||
1283 (cmd->start_src == TRIG_EXT &&
1284 cmd->scan_begin_src == TRIG_FOLLOW &&
1285 cmd->convert_src == TRIG_TIMER)) {
1286 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
1287 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1288 ME4000_AI_CTRL_BIT_DATA_FIFO;
1289 } else if (cmd->start_src == TRIG_EXT &&
1290 cmd->scan_begin_src == TRIG_EXT &&
1291 cmd->convert_src == TRIG_TIMER) {
1292 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
1293 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1294 ME4000_AI_CTRL_BIT_DATA_FIFO;
1295 } else if (cmd->start_src == TRIG_EXT &&
1296 cmd->scan_begin_src == TRIG_EXT &&
1297 cmd->convert_src == TRIG_EXT) {
1298 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1299 ME4000_AI_CTRL_BIT_MODE_1 |
1300 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1301 ME4000_AI_CTRL_BIT_DATA_FIFO;
1302 } else {
1303 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1304 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1305 ME4000_AI_CTRL_BIT_DATA_FIFO;
1306 }
1307
1308 /* Stop triggers */
1309 if (cmd->stop_src == TRIG_COUNT) {
1310 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
1311 info->ai_context.sample_counter_reg);
1312 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1313 } else if (cmd->stop_src == TRIG_NONE &&
1314 cmd->scan_end_src == TRIG_COUNT) {
1315 me4000_outl(dev, cmd->scan_end_arg,
1316 info->ai_context.sample_counter_reg);
1317 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1318 } else {
1319 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1320 }
1321
1322 /* Write the setup to the control register */
1323 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1324
1325 /* Write the channel list */
1326 ai_write_chanlist(dev, s, cmd);
1327
1328 return 0;
1329 }
1330
1331 static int ai_write_chanlist(struct comedi_device *dev,
1332 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1333 {
1334 unsigned int entry;
1335 unsigned int chan;
1336 unsigned int rang;
1337 unsigned int aref;
1338 int i;
1339
1340 CALL_PDEBUG("In ai_write_chanlist()\n");
1341
1342 for (i = 0; i < cmd->chanlist_len; i++) {
1343 chan = CR_CHAN(cmd->chanlist[i]);
1344 rang = CR_RANGE(cmd->chanlist[i]);
1345 aref = CR_AREF(cmd->chanlist[i]);
1346
1347 entry = chan;
1348
1349 if (rang == 0)
1350 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1351 else if (rang == 1)
1352 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1353 else if (rang == 2)
1354 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1355 else
1356 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1357
1358 if (aref == SDF_DIFF)
1359 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1360 else
1361 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1362
1363 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1364 }
1365
1366 return 0;
1367 }
1368
1369 static int me4000_ai_do_cmd(struct comedi_device *dev,
1370 struct comedi_subdevice *s)
1371 {
1372 int err;
1373 unsigned int init_ticks = 0;
1374 unsigned int scan_ticks = 0;
1375 unsigned int chan_ticks = 0;
1376 struct comedi_cmd *cmd = &s->async->cmd;
1377
1378 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1379
1380 /* Reset the analog input */
1381 err = me4000_ai_cancel(dev, s);
1382 if (err)
1383 return err;
1384
1385 /* Round the timer arguments */
1386 err = ai_round_cmd_args(dev,
1387 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1388 if (err)
1389 return err;
1390
1391 /* Prepare the AI for acquisition */
1392 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
1393 if (err)
1394 return err;
1395
1396 /* Start acquistion by dummy read */
1397 me4000_inl(dev, info->ai_context.start_reg);
1398
1399 return 0;
1400 }
1401
1402 /*
1403 * me4000_ai_do_cmd_test():
1404 *
1405 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1406 * - success
1407 * - invalid source
1408 * - source conflict
1409 * - invalid argument
1410 * - argument conflict
1411 * - invalid chanlist
1412 * So I tried to adopt this scheme.
1413 */
1414 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
1415 struct comedi_subdevice *s,
1416 struct comedi_cmd *cmd)
1417 {
1418
1419 unsigned int init_ticks;
1420 unsigned int chan_ticks;
1421 unsigned int scan_ticks;
1422 int err = 0;
1423
1424 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1425
1426 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev);
1427 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags);
1428 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n",
1429 cmd->start_src);
1430 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n",
1431 cmd->start_arg);
1432 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1433 cmd->scan_begin_src);
1434 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1435 cmd->scan_begin_arg);
1436 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n",
1437 cmd->convert_src);
1438 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n",
1439 cmd->convert_arg);
1440 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n",
1441 cmd->scan_end_src);
1442 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n",
1443 cmd->scan_end_arg);
1444 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n",
1445 cmd->stop_src);
1446 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg);
1447 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n",
1448 (unsigned int)cmd->chanlist);
1449 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n",
1450 cmd->chanlist_len);
1451
1452 /* Only rounding flags are implemented */
1453 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1454
1455 /* Round the timer arguments */
1456 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1457
1458 /*
1459 * Stage 1. Check if the trigger sources are generally valid.
1460 */
1461 switch (cmd->start_src) {
1462 case TRIG_NOW:
1463 case TRIG_EXT:
1464 break;
1465 case TRIG_ANY:
1466 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1467 err++;
1468 break;
1469 default:
1470 printk(KERN_ERR
1471 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1472 "Invalid start source\n", dev->minor);
1473 cmd->start_src = TRIG_NOW;
1474 err++;
1475 }
1476 switch (cmd->scan_begin_src) {
1477 case TRIG_FOLLOW:
1478 case TRIG_TIMER:
1479 case TRIG_EXT:
1480 break;
1481 case TRIG_ANY:
1482 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1483 err++;
1484 break;
1485 default:
1486 printk(KERN_ERR
1487 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1488 "Invalid scan begin source\n", dev->minor);
1489 cmd->scan_begin_src = TRIG_FOLLOW;
1490 err++;
1491 }
1492 switch (cmd->convert_src) {
1493 case TRIG_TIMER:
1494 case TRIG_EXT:
1495 break;
1496 case TRIG_ANY:
1497 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1498 err++;
1499 break;
1500 default:
1501 printk(KERN_ERR
1502 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1503 "Invalid convert source\n", dev->minor);
1504 cmd->convert_src = TRIG_TIMER;
1505 err++;
1506 }
1507 switch (cmd->scan_end_src) {
1508 case TRIG_NONE:
1509 case TRIG_COUNT:
1510 break;
1511 case TRIG_ANY:
1512 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1513 err++;
1514 break;
1515 default:
1516 printk(KERN_ERR
1517 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1518 "Invalid scan end source\n", dev->minor);
1519 cmd->scan_end_src = TRIG_NONE;
1520 err++;
1521 }
1522 switch (cmd->stop_src) {
1523 case TRIG_NONE:
1524 case TRIG_COUNT:
1525 break;
1526 case TRIG_ANY:
1527 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1528 err++;
1529 break;
1530 default:
1531 printk(KERN_ERR
1532 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1533 "Invalid stop source\n", dev->minor);
1534 cmd->stop_src = TRIG_NONE;
1535 err++;
1536 }
1537 if (err)
1538 return 1;
1539
1540 /*
1541 * Stage 2. Check for trigger source conflicts.
1542 */
1543 if (cmd->start_src == TRIG_NOW &&
1544 cmd->scan_begin_src == TRIG_TIMER &&
1545 cmd->convert_src == TRIG_TIMER) {
1546 } else if (cmd->start_src == TRIG_NOW &&
1547 cmd->scan_begin_src == TRIG_FOLLOW &&
1548 cmd->convert_src == TRIG_TIMER) {
1549 } else if (cmd->start_src == TRIG_EXT &&
1550 cmd->scan_begin_src == TRIG_TIMER &&
1551 cmd->convert_src == TRIG_TIMER) {
1552 } else if (cmd->start_src == TRIG_EXT &&
1553 cmd->scan_begin_src == TRIG_FOLLOW &&
1554 cmd->convert_src == TRIG_TIMER) {
1555 } else if (cmd->start_src == TRIG_EXT &&
1556 cmd->scan_begin_src == TRIG_EXT &&
1557 cmd->convert_src == TRIG_TIMER) {
1558 } else if (cmd->start_src == TRIG_EXT &&
1559 cmd->scan_begin_src == TRIG_EXT &&
1560 cmd->convert_src == TRIG_EXT) {
1561 } else {
1562 printk(KERN_ERR
1563 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1564 "Invalid start trigger combination\n", dev->minor);
1565 cmd->start_src = TRIG_NOW;
1566 cmd->scan_begin_src = TRIG_FOLLOW;
1567 cmd->convert_src = TRIG_TIMER;
1568 err++;
1569 }
1570
1571 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
1572 } else if (cmd->stop_src == TRIG_COUNT &&
1573 cmd->scan_end_src == TRIG_NONE) {
1574 } else if (cmd->stop_src == TRIG_NONE &&
1575 cmd->scan_end_src == TRIG_COUNT) {
1576 } else if (cmd->stop_src == TRIG_COUNT &&
1577 cmd->scan_end_src == TRIG_COUNT) {
1578 } else {
1579 printk(KERN_ERR
1580 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1581 "Invalid stop trigger combination\n", dev->minor);
1582 cmd->stop_src = TRIG_NONE;
1583 cmd->scan_end_src = TRIG_NONE;
1584 err++;
1585 }
1586 if (err)
1587 return 2;
1588
1589 /*
1590 * Stage 3. Check if arguments are generally valid.
1591 */
1592 if (cmd->chanlist_len < 1) {
1593 printk(KERN_ERR
1594 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1595 "No channel list\n", dev->minor);
1596 cmd->chanlist_len = 1;
1597 err++;
1598 }
1599 if (init_ticks < 66) {
1600 printk(KERN_ERR
1601 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1602 "Start arg to low\n", dev->minor);
1603 cmd->start_arg = 2000;
1604 err++;
1605 }
1606 if (scan_ticks && scan_ticks < 67) {
1607 printk(KERN_ERR
1608 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1609 "Scan begin arg to low\n", dev->minor);
1610 cmd->scan_begin_arg = 2031;
1611 err++;
1612 }
1613 if (chan_ticks < 66) {
1614 printk(KERN_ERR
1615 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1616 "Convert arg to low\n", dev->minor);
1617 cmd->convert_arg = 2000;
1618 err++;
1619 }
1620
1621 if (err)
1622 return 3;
1623
1624 /*
1625 * Stage 4. Check for argument conflicts.
1626 */
1627 if (cmd->start_src == TRIG_NOW &&
1628 cmd->scan_begin_src == TRIG_TIMER &&
1629 cmd->convert_src == TRIG_TIMER) {
1630
1631 /* Check timer arguments */
1632 if (init_ticks < ME4000_AI_MIN_TICKS) {
1633 printk(KERN_ERR
1634 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1635 "Invalid start arg\n", dev->minor);
1636 cmd->start_arg = 2000; /* 66 ticks at least */
1637 err++;
1638 }
1639 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1640 printk(KERN_ERR
1641 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1642 "Invalid convert arg\n", dev->minor);
1643 cmd->convert_arg = 2000; /* 66 ticks at least */
1644 err++;
1645 }
1646 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1647 printk(KERN_ERR
1648 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1649 "Invalid scan end arg\n", dev->minor);
1650
1651 /* At least one tick more */
1652 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1653 err++;
1654 }
1655 } else if (cmd->start_src == TRIG_NOW &&
1656 cmd->scan_begin_src == TRIG_FOLLOW &&
1657 cmd->convert_src == TRIG_TIMER) {
1658
1659 /* Check timer arguments */
1660 if (init_ticks < ME4000_AI_MIN_TICKS) {
1661 printk(KERN_ERR
1662 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1663 "Invalid start arg\n", dev->minor);
1664 cmd->start_arg = 2000; /* 66 ticks at least */
1665 err++;
1666 }
1667 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1668 printk(KERN_ERR
1669 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1670 "Invalid convert arg\n", dev->minor);
1671 cmd->convert_arg = 2000; /* 66 ticks at least */
1672 err++;
1673 }
1674 } else if (cmd->start_src == TRIG_EXT &&
1675 cmd->scan_begin_src == TRIG_TIMER &&
1676 cmd->convert_src == TRIG_TIMER) {
1677
1678 /* Check timer arguments */
1679 if (init_ticks < ME4000_AI_MIN_TICKS) {
1680 printk(KERN_ERR
1681 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1682 "Invalid start arg\n", dev->minor);
1683 cmd->start_arg = 2000; /* 66 ticks at least */
1684 err++;
1685 }
1686 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1687 printk(KERN_ERR
1688 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1689 "Invalid convert arg\n", dev->minor);
1690 cmd->convert_arg = 2000; /* 66 ticks at least */
1691 err++;
1692 }
1693 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1694 printk(KERN_ERR
1695 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1696 "Invalid scan end arg\n", dev->minor);
1697
1698 /* At least one tick more */
1699 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1700 err++;
1701 }
1702 } else if (cmd->start_src == TRIG_EXT &&
1703 cmd->scan_begin_src == TRIG_FOLLOW &&
1704 cmd->convert_src == TRIG_TIMER) {
1705
1706 /* Check timer arguments */
1707 if (init_ticks < ME4000_AI_MIN_TICKS) {
1708 printk(KERN_ERR
1709 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1710 "Invalid start arg\n", dev->minor);
1711 cmd->start_arg = 2000; /* 66 ticks at least */
1712 err++;
1713 }
1714 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1715 printk(KERN_ERR
1716 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1717 "Invalid convert arg\n", dev->minor);
1718 cmd->convert_arg = 2000; /* 66 ticks at least */
1719 err++;
1720 }
1721 } else if (cmd->start_src == TRIG_EXT &&
1722 cmd->scan_begin_src == TRIG_EXT &&
1723 cmd->convert_src == TRIG_TIMER) {
1724
1725 /* Check timer arguments */
1726 if (init_ticks < ME4000_AI_MIN_TICKS) {
1727 printk(KERN_ERR
1728 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1729 "Invalid start arg\n", dev->minor);
1730 cmd->start_arg = 2000; /* 66 ticks at least */
1731 err++;
1732 }
1733 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1734 printk(KERN_ERR
1735 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1736 "Invalid convert arg\n", dev->minor);
1737 cmd->convert_arg = 2000; /* 66 ticks at least */
1738 err++;
1739 }
1740 } else if (cmd->start_src == TRIG_EXT &&
1741 cmd->scan_begin_src == TRIG_EXT &&
1742 cmd->convert_src == TRIG_EXT) {
1743
1744 /* Check timer arguments */
1745 if (init_ticks < ME4000_AI_MIN_TICKS) {
1746 printk(KERN_ERR
1747 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1748 "Invalid start arg\n", dev->minor);
1749 cmd->start_arg = 2000; /* 66 ticks at least */
1750 err++;
1751 }
1752 }
1753 if (cmd->stop_src == TRIG_COUNT) {
1754 if (cmd->stop_arg == 0) {
1755 printk(KERN_ERR
1756 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1757 "Invalid stop arg\n", dev->minor);
1758 cmd->stop_arg = 1;
1759 err++;
1760 }
1761 }
1762 if (cmd->scan_end_src == TRIG_COUNT) {
1763 if (cmd->scan_end_arg == 0) {
1764 printk(KERN_ERR
1765 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1766 "Invalid scan end arg\n", dev->minor);
1767 cmd->scan_end_arg = 1;
1768 err++;
1769 }
1770 }
1771
1772 if (err)
1773 return 4;
1774
1775 /*
1776 * Stage 5. Check the channel list.
1777 */
1778 if (ai_check_chanlist(dev, s, cmd))
1779 return 5;
1780
1781 return 0;
1782 }
1783
1784 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1785 {
1786 unsigned int tmp;
1787 struct comedi_device *dev = dev_id;
1788 struct comedi_subdevice *s = dev->subdevices;
1789 struct me4000_ai_context *ai_context = &info->ai_context;
1790 int i;
1791 int c = 0;
1792 long lval;
1793
1794 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1795
1796 if (!dev->attached) {
1797 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1798 return IRQ_NONE;
1799 }
1800
1801 /* Reset all events */
1802 s->async->events = 0;
1803
1804 /* Check if irq number is right */
1805 if (irq != ai_context->irq) {
1806 printk(KERN_ERR
1807 "comedi%d: me4000: me4000_ai_isr(): "
1808 "Incorrect interrupt num: %d\n", dev->minor, irq);
1809 return IRQ_HANDLED;
1810 }
1811
1812 if (me4000_inl(dev,
1813 ai_context->irq_status_reg) &
1814 ME4000_IRQ_STATUS_BIT_AI_HF) {
1815 ISR_PDEBUG
1816 ("me4000_ai_isr(): Fifo half full interrupt occured\n");
1817
1818 /* Read status register to find out what happened */
1819 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1820
1821 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1822 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1823 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1824 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1825 c = ME4000_AI_FIFO_COUNT;
1826
1827 /*
1828 * FIFO overflow, so stop conversion
1829 * and disable all interrupts
1830 */
1831 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1832 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1833 ME4000_AI_CTRL_BIT_SC_IRQ);
1834 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1835
1836 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1837
1838 printk(KERN_ERR
1839 "comedi%d: me4000: me4000_ai_isr(): "
1840 "FIFO overflow\n", dev->minor);
1841 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1842 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1843 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1844 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1845
1846 s->async->events |= COMEDI_CB_BLOCK;
1847
1848 c = ME4000_AI_FIFO_COUNT / 2;
1849 } else {
1850 printk(KERN_ERR
1851 "comedi%d: me4000: me4000_ai_isr(): "
1852 "Can't determine state of fifo\n", dev->minor);
1853 c = 0;
1854
1855 /*
1856 * Undefined state, so stop conversion
1857 * and disable all interrupts
1858 */
1859 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1860 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1861 ME4000_AI_CTRL_BIT_SC_IRQ);
1862 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1863
1864 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1865
1866 printk(KERN_ERR
1867 "comedi%d: me4000: me4000_ai_isr(): "
1868 "Undefined FIFO state\n", dev->minor);
1869 }
1870
1871 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1872
1873 for (i = 0; i < c; i++) {
1874 /* Read value from data fifo */
1875 lval = inl(ai_context->data_reg) & 0xFFFF;
1876 lval ^= 0x8000;
1877
1878 if (!comedi_buf_put(s->async, lval)) {
1879 /*
1880 * Buffer overflow, so stop conversion
1881 * and disable all interrupts
1882 */
1883 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1884 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1885 ME4000_AI_CTRL_BIT_SC_IRQ);
1886 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1887
1888 s->async->events |= COMEDI_CB_OVERFLOW;
1889
1890 printk(KERN_ERR
1891 "comedi%d: me4000: me4000_ai_isr(): "
1892 "Buffer overflow\n", dev->minor);
1893
1894 break;
1895 }
1896 }
1897
1898 /* Work is done, so reset the interrupt */
1899 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1900 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1901 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1902 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1903 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1904 }
1905
1906 if (me4000_inl(dev,
1907 ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
1908 ISR_PDEBUG
1909 ("me4000_ai_isr(): Sample counter interrupt occured\n");
1910
1911 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1912
1913 /*
1914 * Acquisition is complete, so stop
1915 * conversion and disable all interrupts
1916 */
1917 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1918 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1919 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1920 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1921
1922 /* Poll data until fifo empty */
1923 while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
1924 /* Read value from data fifo */
1925 lval = inl(ai_context->data_reg) & 0xFFFF;
1926 lval ^= 0x8000;
1927
1928 if (!comedi_buf_put(s->async, lval)) {
1929 printk(KERN_ERR
1930 "comedi%d: me4000: me4000_ai_isr(): "
1931 "Buffer overflow\n", dev->minor);
1932 s->async->events |= COMEDI_CB_OVERFLOW;
1933 break;
1934 }
1935 }
1936
1937 /* Work is done, so reset the interrupt */
1938 ISR_PDEBUG
1939 ("me4000_ai_isr(): Reset interrupt from sample counter\n");
1940 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1941 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1942 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1943 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1944 }
1945
1946 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1947
1948 if (s->async->events)
1949 comedi_event(dev, s);
1950
1951 return IRQ_HANDLED;
1952 }
1953
1954 /*=============================================================================
1955 Analog output section
1956 ===========================================================================*/
1957
1958 static int me4000_ao_insn_write(struct comedi_device *dev,
1959 struct comedi_subdevice *s,
1960 struct comedi_insn *insn, unsigned int *data)
1961 {
1962
1963 int chan = CR_CHAN(insn->chanspec);
1964 int rang = CR_RANGE(insn->chanspec);
1965 int aref = CR_AREF(insn->chanspec);
1966 unsigned long tmp;
1967
1968 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1969
1970 if (insn->n == 0) {
1971 return 0;
1972 } else if (insn->n > 1) {
1973 printk(KERN_ERR
1974 "comedi%d: me4000: me4000_ao_insn_write(): "
1975 "Invalid instruction length %d\n", dev->minor, insn->n);
1976 return -EINVAL;
1977 }
1978
1979 if (chan >= thisboard->ao.count) {
1980 printk(KERN_ERR
1981 "comedi%d: me4000: me4000_ao_insn_write(): "
1982 "Invalid channel %d\n", dev->minor, insn->n);
1983 return -EINVAL;
1984 }
1985
1986 if (rang != 0) {
1987 printk(KERN_ERR
1988 "comedi%d: me4000: me4000_ao_insn_write(): "
1989 "Invalid range %d\n", dev->minor, insn->n);
1990 return -EINVAL;
1991 }
1992
1993 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1994 printk(KERN_ERR
1995 "comedi%d: me4000: me4000_ao_insn_write(): "
1996 "Invalid aref %d\n", dev->minor, insn->n);
1997 return -EINVAL;
1998 }
1999
2000 /* Stop any running conversion */
2001 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
2002 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
2003 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
2004
2005 /* Clear control register and set to single mode */
2006 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
2007
2008 /* Write data value */
2009 me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
2010
2011 /* Store in the mirror */
2012 info->ao_context[chan].mirror = data[0];
2013
2014 return 1;
2015 }
2016
2017 static int me4000_ao_insn_read(struct comedi_device *dev,
2018 struct comedi_subdevice *s,
2019 struct comedi_insn *insn, unsigned int *data)
2020 {
2021 int chan = CR_CHAN(insn->chanspec);
2022
2023 if (insn->n == 0) {
2024 return 0;
2025 } else if (insn->n > 1) {
2026 printk
2027 ("comedi%d: me4000: me4000_ao_insn_read(): "
2028 "Invalid instruction length\n", dev->minor);
2029 return -EINVAL;
2030 }
2031
2032 data[0] = info->ao_context[chan].mirror;
2033
2034 return 1;
2035 }
2036
2037 /*=============================================================================
2038 Digital I/O section
2039 ===========================================================================*/
2040
2041 static int me4000_dio_insn_bits(struct comedi_device *dev,
2042 struct comedi_subdevice *s,
2043 struct comedi_insn *insn, unsigned int *data)
2044 {
2045
2046 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
2047
2048 /* Length of data must be 2 (mask and new data, see below) */
2049 if (insn->n == 0)
2050 return 0;
2051
2052 if (insn->n != 2) {
2053 printk
2054 ("comedi%d: me4000: me4000_dio_insn_bits(): "
2055 "Invalid instruction length\n", dev->minor);
2056 return -EINVAL;
2057 }
2058
2059 /*
2060 * The insn data consists of a mask in data[0] and the new data
2061 * in data[1]. The mask defines which bits we are concerning about.
2062 * The new data must be anded with the mask.
2063 * Each channel corresponds to a bit.
2064 */
2065 if (data[0]) {
2066 /* Check if requested ports are configured for output */
2067 if ((s->io_bits & data[0]) != data[0])
2068 return -EIO;
2069
2070 s->state &= ~data[0];
2071 s->state |= data[0] & data[1];
2072
2073 /* Write out the new digital output lines */
2074 me4000_outl(dev, (s->state >> 0) & 0xFF,
2075 info->dio_context.port_0_reg);
2076 me4000_outl(dev, (s->state >> 8) & 0xFF,
2077 info->dio_context.port_1_reg);
2078 me4000_outl(dev, (s->state >> 16) & 0xFF,
2079 info->dio_context.port_2_reg);
2080 me4000_outl(dev, (s->state >> 24) & 0xFF,
2081 info->dio_context.port_3_reg);
2082 }
2083
2084 /* On return, data[1] contains the value of
2085 the digital input and output lines. */
2086 data[1] =
2087 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
2088 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
2089 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
2090 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
2091
2092 return 2;
2093 }
2094
2095 static int me4000_dio_insn_config(struct comedi_device *dev,
2096 struct comedi_subdevice *s,
2097 struct comedi_insn *insn, unsigned int *data)
2098 {
2099 unsigned long tmp;
2100 int chan = CR_CHAN(insn->chanspec);
2101
2102 CALL_PDEBUG("In me4000_dio_insn_config()\n");
2103
2104 if (data[0] == INSN_CONFIG_DIO_QUERY) {
2105 data[1] =
2106 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2107 return insn->n;
2108 }
2109
2110 /*
2111 * The input or output configuration of each digital line is
2112 * configured by a special insn_config instruction. chanspec
2113 * contains the channel to be changed, and data[0] contains the
2114 * value COMEDI_INPUT or COMEDI_OUTPUT.
2115 * On the ME-4000 it is only possible to switch port wise (8 bit)
2116 */
2117
2118 tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
2119
2120 if (data[0] == COMEDI_OUTPUT) {
2121 if (chan < 8) {
2122 s->io_bits |= 0xFF;
2123 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2124 ME4000_DIO_CTRL_BIT_MODE_1);
2125 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
2126 } else if (chan < 16) {
2127 /*
2128 * Chech for optoisolated ME-4000 version.
2129 * If one the first port is a fixed output
2130 * port and the second is a fixed input port.
2131 */
2132 if (!me4000_inl(dev, info->dio_context.dir_reg))
2133 return -ENODEV;
2134
2135 s->io_bits |= 0xFF00;
2136 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2137 ME4000_DIO_CTRL_BIT_MODE_3);
2138 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
2139 } else if (chan < 24) {
2140 s->io_bits |= 0xFF0000;
2141 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2142 ME4000_DIO_CTRL_BIT_MODE_5);
2143 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2144 } else if (chan < 32) {
2145 s->io_bits |= 0xFF000000;
2146 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2147 ME4000_DIO_CTRL_BIT_MODE_7);
2148 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2149 } else {
2150 return -EINVAL;
2151 }
2152 } else {
2153 if (chan < 8) {
2154 /*
2155 * Chech for optoisolated ME-4000 version.
2156 * If one the first port is a fixed output
2157 * port and the second is a fixed input port.
2158 */
2159 if (!me4000_inl(dev, info->dio_context.dir_reg))
2160 return -ENODEV;
2161
2162 s->io_bits &= ~0xFF;
2163 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2164 ME4000_DIO_CTRL_BIT_MODE_1);
2165 } else if (chan < 16) {
2166 s->io_bits &= ~0xFF00;
2167 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2168 ME4000_DIO_CTRL_BIT_MODE_3);
2169 } else if (chan < 24) {
2170 s->io_bits &= ~0xFF0000;
2171 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2172 ME4000_DIO_CTRL_BIT_MODE_5);
2173 } else if (chan < 32) {
2174 s->io_bits &= ~0xFF000000;
2175 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2176 ME4000_DIO_CTRL_BIT_MODE_7);
2177 } else {
2178 return -EINVAL;
2179 }
2180 }
2181
2182 me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2183
2184 return 1;
2185 }
2186
2187 /*=============================================================================
2188 Counter section
2189 ===========================================================================*/
2190
2191 static int cnt_reset(struct comedi_device *dev, unsigned int channel)
2192 {
2193
2194 CALL_PDEBUG("In cnt_reset()\n");
2195
2196 switch (channel) {
2197 case 0:
2198 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2199 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2200 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2201 break;
2202 case 1:
2203 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2204 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2205 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2206 break;
2207 case 2:
2208 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2209 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2210 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2211 break;
2212 default:
2213 printk(KERN_ERR
2214 "comedi%d: me4000: cnt_reset(): Invalid channel\n",
2215 dev->minor);
2216 return -EINVAL;
2217 }
2218
2219 return 0;
2220 }
2221
2222 static int cnt_config(struct comedi_device *dev, unsigned int channel,
2223 unsigned int mode)
2224 {
2225 int tmp = 0;
2226
2227 CALL_PDEBUG("In cnt_config()\n");
2228
2229 switch (channel) {
2230 case 0:
2231 tmp |= ME4000_CNT_COUNTER_0;
2232 break;
2233 case 1:
2234 tmp |= ME4000_CNT_COUNTER_1;
2235 break;
2236 case 2:
2237 tmp |= ME4000_CNT_COUNTER_2;
2238 break;
2239 default:
2240 printk(KERN_ERR
2241 "comedi%d: me4000: cnt_config(): Invalid channel\n",
2242 dev->minor);
2243 return -EINVAL;
2244 }
2245
2246 switch (mode) {
2247 case 0:
2248 tmp |= ME4000_CNT_MODE_0;
2249 break;
2250 case 1:
2251 tmp |= ME4000_CNT_MODE_1;
2252 break;
2253 case 2:
2254 tmp |= ME4000_CNT_MODE_2;
2255 break;
2256 case 3:
2257 tmp |= ME4000_CNT_MODE_3;
2258 break;
2259 case 4:
2260 tmp |= ME4000_CNT_MODE_4;
2261 break;
2262 case 5:
2263 tmp |= ME4000_CNT_MODE_5;
2264 break;
2265 default:
2266 printk(KERN_ERR
2267 "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2268 dev->minor);
2269 return -EINVAL;
2270 }
2271
2272 /* Write the control word */
2273 tmp |= 0x30;
2274 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2275
2276 return 0;
2277 }
2278
2279 static int me4000_cnt_insn_config(struct comedi_device *dev,
2280 struct comedi_subdevice *s,
2281 struct comedi_insn *insn, unsigned int *data)
2282 {
2283
2284 int err;
2285
2286 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2287
2288 switch (data[0]) {
2289 case GPCT_RESET:
2290 if (insn->n != 1) {
2291 printk(KERN_ERR
2292 "comedi%d: me4000: me4000_cnt_insn_config(): "
2293 "Invalid instruction length%d\n",
2294 dev->minor, insn->n);
2295 return -EINVAL;
2296 }
2297
2298 err = cnt_reset(dev, insn->chanspec);
2299 if (err)
2300 return err;
2301 break;
2302 case GPCT_SET_OPERATION:
2303 if (insn->n != 2) {
2304 printk(KERN_ERR
2305 "comedi%d: me4000: me4000_cnt_insn_config(): "
2306 "Invalid instruction length%d\n",
2307 dev->minor, insn->n);
2308 return -EINVAL;
2309 }
2310
2311 err = cnt_config(dev, insn->chanspec, data[1]);
2312 if (err)
2313 return err;
2314 break;
2315 default:
2316 printk(KERN_ERR
2317 "comedi%d: me4000: me4000_cnt_insn_config(): "
2318 "Invalid instruction\n", dev->minor);
2319 return -EINVAL;
2320 }
2321
2322 return 2;
2323 }
2324
2325 static int me4000_cnt_insn_read(struct comedi_device *dev,
2326 struct comedi_subdevice *s,
2327 struct comedi_insn *insn, unsigned int *data)
2328 {
2329
2330 unsigned short tmp;
2331
2332 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2333
2334 if (insn->n == 0)
2335 return 0;
2336
2337 if (insn->n > 1) {
2338 printk(KERN_ERR
2339 "comedi%d: me4000: me4000_cnt_insn_read(): "
2340 "Invalid instruction length %d\n",
2341 dev->minor, insn->n);
2342 return -EINVAL;
2343 }
2344
2345 switch (insn->chanspec) {
2346 case 0:
2347 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2348 data[0] = tmp;
2349 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2350 data[0] |= tmp << 8;
2351 break;
2352 case 1:
2353 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2354 data[0] = tmp;
2355 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2356 data[0] |= tmp << 8;
2357 break;
2358 case 2:
2359 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2360 data[0] = tmp;
2361 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2362 data[0] |= tmp << 8;
2363 break;
2364 default:
2365 printk(KERN_ERR
2366 "comedi%d: me4000: me4000_cnt_insn_read(): "
2367 "Invalid channel %d\n",
2368 dev->minor, insn->chanspec);
2369 return -EINVAL;
2370 }
2371
2372 return 1;
2373 }
2374
2375 static int me4000_cnt_insn_write(struct comedi_device *dev,
2376 struct comedi_subdevice *s,
2377 struct comedi_insn *insn, unsigned int *data)
2378 {
2379
2380 unsigned short tmp;
2381
2382 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2383
2384 if (insn->n == 0) {
2385 return 0;
2386 } else if (insn->n > 1) {
2387 printk(KERN_ERR
2388 "comedi%d: me4000: me4000_cnt_insn_write(): "
2389 "Invalid instruction length %d\n",
2390 dev->minor, insn->n);
2391 return -EINVAL;
2392 }
2393
2394 switch (insn->chanspec) {
2395 case 0:
2396 tmp = data[0] & 0xFF;
2397 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2398 tmp = (data[0] >> 8) & 0xFF;
2399 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2400 break;
2401 case 1:
2402 tmp = data[0] & 0xFF;
2403 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2404 tmp = (data[0] >> 8) & 0xFF;
2405 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2406 break;
2407 case 2:
2408 tmp = data[0] & 0xFF;
2409 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2410 tmp = (data[0] >> 8) & 0xFF;
2411 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2412 break;
2413 default:
2414 printk(KERN_ERR
2415 "comedi%d: me4000: me4000_cnt_insn_write(): "
2416 "Invalid channel %d\n",
2417 dev->minor, insn->chanspec);
2418 return -EINVAL;
2419 }
2420
2421 return 1;
2422 }
2423
2424 static int __devinit driver_me4000_pci_probe(struct pci_dev *dev,
2425 const struct pci_device_id *ent)
2426 {
2427 return comedi_pci_auto_config(dev, driver_me4000.driver_name);
2428 }
2429
2430 static void __devexit driver_me4000_pci_remove(struct pci_dev *dev)
2431 {
2432 comedi_pci_auto_unconfig(dev);
2433 }
2434
2435 static struct pci_driver driver_me4000_pci_driver = {
2436 .id_table = me4000_pci_table,
2437 .probe = &driver_me4000_pci_probe,
2438 .remove = __devexit_p(&driver_me4000_pci_remove)
2439 };
2440
2441 static int __init driver_me4000_init_module(void)
2442 {
2443 int retval;
2444
2445 retval = comedi_driver_register(&driver_me4000);
2446 if (retval < 0)
2447 return retval;
2448
2449 driver_me4000_pci_driver.name = (char *)driver_me4000.driver_name;
2450 return pci_register_driver(&driver_me4000_pci_driver);
2451 }
2452
2453 static void __exit driver_me4000_cleanup_module(void)
2454 {
2455 pci_unregister_driver(&driver_me4000_pci_driver);
2456 comedi_driver_unregister(&driver_me4000);
2457 }
2458
2459 module_init(driver_me4000_init_module);
2460 module_exit(driver_me4000_cleanup_module);
2461
2462 MODULE_AUTHOR("Comedi http://www.comedi.org");
2463 MODULE_DESCRIPTION("Comedi low-level driver");
2464 MODULE_LICENSE("GPL");