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