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