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