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