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