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