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