staging: comedi: me4000: fix the interrupt request/free
[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: not applicable, uses PCI auto config
39
40 The firmware required by these boards is available in the
41 comedi_nonfree_firmware tarball available from
42 http://www.comedi.org.  However, the driver's support for
43 loading the firmware through comedi_config is currently
44 broken.
45
46  */
47
48 #include <linux/interrupt.h>
49 #include "../comedidev.h"
50
51 #include <linux/delay.h>
52 #include <linux/list.h>
53 #include <linux/spinlock.h>
54
55 #include "me4000.h"
56 #if 0
57 /* file removed due to GPL incompatibility */
58 #include "me4000_fw.h"
59 #endif
60
61 #define PCI_VENDOR_ID_MEILHAUS          0x1402
62
63 #define PCI_DEVICE_ID_MEILHAUS_ME4650   0x4650
64 #define PCI_DEVICE_ID_MEILHAUS_ME4660   0x4660
65 #define PCI_DEVICE_ID_MEILHAUS_ME4660I  0x4661
66 #define PCI_DEVICE_ID_MEILHAUS_ME4660S  0x4662
67 #define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663
68 #define PCI_DEVICE_ID_MEILHAUS_ME4670   0x4670
69 #define PCI_DEVICE_ID_MEILHAUS_ME4670I  0x4671
70 #define PCI_DEVICE_ID_MEILHAUS_ME4670S  0x4672
71 #define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673
72 #define PCI_DEVICE_ID_MEILHAUS_ME4680   0x4680
73 #define PCI_DEVICE_ID_MEILHAUS_ME4680I  0x4681
74 #define PCI_DEVICE_ID_MEILHAUS_ME4680S  0x4682
75 #define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683
76
77 struct me4000_board {
78         const char *name;
79         unsigned short device_id;
80         int ao_nchan;
81         int ao_fifo;
82         int ai_nchan;
83         int ai_diff_nchan;
84         int ai_sh_nchan;
85         int ex_trig_analog;
86         int dio_nchan;
87         int has_counter;
88 };
89
90 static const struct me4000_board me4000_boards[] = {
91         {
92                 .name           = "ME-4650",
93                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4650,
94                 .ai_nchan       = 16,
95                 .dio_nchan      = 32,
96         }, {
97                 .name           = "ME-4660",
98                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4660,
99                 .ai_nchan       = 32,
100                 .ai_diff_nchan  = 16,
101                 .dio_nchan      = 32,
102                 .has_counter    = 1,
103         }, {
104                 .name           = "ME-4660i",
105                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4660I,
106                 .ai_nchan       = 32,
107                 .ai_diff_nchan  = 16,
108                 .dio_nchan      = 32,
109                 .has_counter    = 1,
110         }, {
111                 .name           = "ME-4660s",
112                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4660S,
113                 .ai_nchan       = 32,
114                 .ai_diff_nchan  = 16,
115                 .ai_sh_nchan    = 8,
116                 .dio_nchan      = 32,
117                 .has_counter    = 1,
118         }, {
119                 .name           = "ME-4660is",
120                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4660IS,
121                 .ai_nchan       = 32,
122                 .ai_diff_nchan  = 16,
123                 .ai_sh_nchan    = 8,
124                 .dio_nchan      = 32,
125                 .has_counter    = 1,
126         }, {
127                 .name           = "ME-4670",
128                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4670,
129                 .ao_nchan       = 4,
130                 .ai_nchan       = 32,
131                 .ai_diff_nchan  = 16,
132                 .ex_trig_analog = 1,
133                 .dio_nchan      = 32,
134                 .has_counter    = 1,
135         }, {
136                 .name           = "ME-4670i",
137                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4670I,
138                 .ao_nchan       = 4,
139                 .ai_nchan       = 32,
140                 .ai_diff_nchan  = 16,
141                 .ex_trig_analog = 1,
142                 .dio_nchan      = 32,
143                 .has_counter    = 1,
144         }, {
145                 .name           = "ME-4670s",
146                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4670S,
147                 .ao_nchan       = 4,
148                 .ai_nchan       = 32,
149                 .ai_diff_nchan  = 16,
150                 .ai_sh_nchan    = 8,
151                 .ex_trig_analog = 1,
152                 .dio_nchan      = 32,
153                 .has_counter    = 1,
154         }, {
155                 .name           = "ME-4670is",
156                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4670IS,
157                 .ao_nchan       = 4,
158                 .ai_nchan       = 32,
159                 .ai_diff_nchan  = 16,
160                 .ai_sh_nchan    = 8,
161                 .ex_trig_analog = 1,
162                 .dio_nchan      = 32,
163                 .has_counter    = 1,
164         }, {
165                 .name           = "ME-4680",
166                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4680,
167                 .ao_nchan       = 4,
168                 .ao_fifo        = 4,
169                 .ai_nchan       = 32,
170                 .ai_diff_nchan  = 16,
171                 .ex_trig_analog = 1,
172                 .dio_nchan      = 32,
173                 .has_counter    = 1,
174         }, {
175                 .name           = "ME-4680i",
176                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4680I,
177                 .ao_nchan       = 4,
178                 .ao_fifo        = 4,
179                 .ai_nchan       = 32,
180                 .ai_diff_nchan  = 16,
181                 .ex_trig_analog = 1,
182                 .dio_nchan      = 32,
183                 .has_counter    = 1,
184         }, {
185                 .name           = "ME-4680s",
186                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4680S,
187                 .ao_nchan       = 4,
188                 .ao_fifo        = 4,
189                 .ai_nchan       = 32,
190                 .ai_diff_nchan  = 16,
191                 .ai_sh_nchan    = 8,
192                 .ex_trig_analog = 1,
193                 .dio_nchan      = 32,
194                 .has_counter    = 1,
195         }, {
196                 .name           = "ME-4680is",
197                 .device_id      = PCI_DEVICE_ID_MEILHAUS_ME4680IS,
198                 .ao_nchan       = 4,
199                 .ao_fifo        = 4,
200                 .ai_nchan       = 32,
201                 .ai_diff_nchan  = 16,
202                 .ai_sh_nchan    = 8,
203                 .ex_trig_analog = 1,
204                 .dio_nchan      = 32,
205                 .has_counter    = 1,
206         },
207 };
208
209 static const struct comedi_lrange me4000_ai_range = {
210         4,
211         {
212          UNI_RANGE(2.5),
213          UNI_RANGE(10),
214          BIP_RANGE(2.5),
215          BIP_RANGE(10),
216          }
217 };
218
219 #define FIRMWARE_NOT_AVAILABLE 1
220 #if FIRMWARE_NOT_AVAILABLE
221 extern unsigned char *xilinx_firm;
222 #endif
223
224 static int xilinx_download(struct comedi_device *dev)
225 {
226         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
227         struct me4000_info *info = dev->private;
228         unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
229         u32 value = 0;
230         wait_queue_head_t queue;
231         int idx = 0;
232         int size = 0;
233
234         if (!xilinx_iobase)
235                 return -ENODEV;
236
237         init_waitqueue_head(&queue);
238
239         /*
240          * Set PLX local interrupt 2 polarity to high.
241          * Interrupt is thrown by init pin of xilinx.
242          */
243         outl(0x10, info->plx_regbase + PLX_INTCSR);
244
245         /* Set /CS and /WRITE of the Xilinx */
246         value = inl(info->plx_regbase + PLX_ICR);
247         value |= 0x100;
248         outl(value, info->plx_regbase + PLX_ICR);
249
250         /* Init Xilinx with CS1 */
251         inb(xilinx_iobase + 0xC8);
252
253         /* Wait until /INIT pin is set */
254         udelay(20);
255         if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
256                 printk(KERN_ERR
257                        "comedi%d: me4000: xilinx_download(): "
258                        "Can't init Xilinx\n", dev->minor);
259                 return -EIO;
260         }
261
262         /* Reset /CS and /WRITE of the Xilinx */
263         value = inl(info->plx_regbase + PLX_ICR);
264         value &= ~0x100;
265         outl(value, info->plx_regbase + PLX_ICR);
266         if (FIRMWARE_NOT_AVAILABLE) {
267                 comedi_error(dev, "xilinx firmware unavailable "
268                              "due to licensing, aborting");
269                 return -EIO;
270         } else {
271                 /* Download Xilinx firmware */
272                 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
273                     (xilinx_firm[2] << 8) + xilinx_firm[3];
274                 udelay(10);
275
276                 for (idx = 0; idx < size; idx++) {
277                         outb(xilinx_firm[16 + idx], xilinx_iobase);
278                         udelay(10);
279
280                         /* Check if BUSY flag is low */
281                         if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
282                                 printk(KERN_ERR
283                                        "comedi%d: me4000: xilinx_download(): "
284                                        "Xilinx is still busy (idx = %d)\n",
285                                        dev->minor, idx);
286                                 return -EIO;
287                         }
288                 }
289         }
290
291         /* If done flag is high download was successful */
292         if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
293         } else {
294                 printk(KERN_ERR
295                        "comedi%d: me4000: xilinx_download(): "
296                        "DONE flag is not set\n", dev->minor);
297                 printk(KERN_ERR
298                        "comedi%d: me4000: xilinx_download(): "
299                        "Download not successful\n", dev->minor);
300                 return -EIO;
301         }
302
303         /* Set /CS and /WRITE */
304         value = inl(info->plx_regbase + PLX_ICR);
305         value |= 0x100;
306         outl(value, info->plx_regbase + PLX_ICR);
307
308         return 0;
309 }
310
311 static int reset_board(struct comedi_device *dev)
312 {
313         struct me4000_info *info = dev->private;
314         unsigned long val;
315         int chan;
316
317         /* Make a hardware reset */
318         val = inl(info->plx_regbase + PLX_ICR);
319         val |= 0x40000000;
320         outl(val, info->plx_regbase + PLX_ICR);
321         val &= ~0x40000000;
322         outl(val , info->plx_regbase + PLX_ICR);
323
324         /* 0x8000 to the DACs means an output voltage of 0V */
325         for (chan = 0; chan < 4; chan++)
326                 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
327
328         /* Set both stop bits in the analog input control register */
329         outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
330                 dev->iobase + ME4000_AI_CTRL_REG);
331
332         /* Set both stop bits in the analog output control register */
333         val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
334         for (chan = 0; chan < 4; chan++)
335                 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
336
337         /* Enable interrupts on the PLX */
338         outl(0x43, info->plx_regbase + PLX_INTCSR);
339
340         /* Set the adustment register for AO demux */
341         outl(ME4000_AO_DEMUX_ADJUST_VALUE,
342                     dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
343
344         /*
345          * Set digital I/O direction for port 0
346          * to output on isolated versions
347          */
348         if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
349                 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
350
351         return 0;
352 }
353
354 /*=============================================================================
355   Analog input section
356   ===========================================================================*/
357
358 static int me4000_ai_insn_read(struct comedi_device *dev,
359                                struct comedi_subdevice *subdevice,
360                                struct comedi_insn *insn, unsigned int *data)
361 {
362         const struct me4000_board *thisboard = comedi_board(dev);
363         int chan = CR_CHAN(insn->chanspec);
364         int rang = CR_RANGE(insn->chanspec);
365         int aref = CR_AREF(insn->chanspec);
366
367         unsigned long entry = 0;
368         unsigned long tmp;
369         long lval;
370
371         if (insn->n == 0) {
372                 return 0;
373         } else if (insn->n > 1) {
374                 printk(KERN_ERR
375                        "comedi%d: me4000: me4000_ai_insn_read(): "
376                        "Invalid instruction length %d\n", dev->minor, insn->n);
377                 return -EINVAL;
378         }
379
380         switch (rang) {
381         case 0:
382                 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
383                 break;
384         case 1:
385                 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
386                 break;
387         case 2:
388                 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
389                 break;
390         case 3:
391                 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
392                 break;
393         default:
394                 printk(KERN_ERR
395                        "comedi%d: me4000: me4000_ai_insn_read(): "
396                        "Invalid range specified\n", dev->minor);
397                 return -EINVAL;
398         }
399
400         switch (aref) {
401         case AREF_GROUND:
402         case AREF_COMMON:
403                 if (chan >= thisboard->ai_nchan) {
404                         printk(KERN_ERR
405                                "comedi%d: me4000: me4000_ai_insn_read(): "
406                                "Analog input is not available\n", dev->minor);
407                         return -EINVAL;
408                 }
409                 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
410                 break;
411
412         case AREF_DIFF:
413                 if (rang == 0 || rang == 1) {
414                         printk(KERN_ERR
415                                "comedi%d: me4000: me4000_ai_insn_read(): "
416                                "Range must be bipolar when aref = diff\n",
417                                dev->minor);
418                         return -EINVAL;
419                 }
420
421                 if (chan >= thisboard->ai_diff_nchan) {
422                         printk(KERN_ERR
423                                "comedi%d: me4000: me4000_ai_insn_read(): "
424                                "Analog input is not available\n", dev->minor);
425                         return -EINVAL;
426                 }
427                 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
428                 break;
429         default:
430                 printk(KERN_ERR
431                        "comedi%d: me4000: me4000_ai_insn_read(): "
432                        "Invalid aref specified\n", dev->minor);
433                 return -EINVAL;
434         }
435
436         entry |= ME4000_AI_LIST_LAST_ENTRY;
437
438         /* Clear channel list, data fifo and both stop bits */
439         tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
440         tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
441                  ME4000_AI_CTRL_BIT_DATA_FIFO |
442                  ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
443         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
444
445         /* Set the acquisition mode to single */
446         tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
447                  ME4000_AI_CTRL_BIT_MODE_2);
448         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
449
450         /* Enable channel list and data fifo */
451         tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
452         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
453
454         /* Generate channel list entry */
455         outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
456
457         /* Set the timer to maximum sample rate */
458         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
459         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
460
461         /* Start conversion by dummy read */
462         inl(dev->iobase + ME4000_AI_START_REG);
463
464         /* Wait until ready */
465         udelay(10);
466         if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
467              ME4000_AI_STATUS_BIT_EF_DATA)) {
468                 printk(KERN_ERR
469                        "comedi%d: me4000: me4000_ai_insn_read(): "
470                        "Value not available after wait\n", dev->minor);
471                 return -EIO;
472         }
473
474         /* Read value from data fifo */
475         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
476         data[0] = lval ^ 0x8000;
477
478         return 1;
479 }
480
481 static int me4000_ai_cancel(struct comedi_device *dev,
482                             struct comedi_subdevice *s)
483 {
484         unsigned long tmp;
485
486         /* Stop any running conversion */
487         tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
488         tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
489         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
490
491         /* Clear the control register */
492         outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
493
494         return 0;
495 }
496
497 static int ai_check_chanlist(struct comedi_device *dev,
498                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
499 {
500         const struct me4000_board *thisboard = comedi_board(dev);
501         int aref;
502         int i;
503
504         /* Check whether a channel list is available */
505         if (!cmd->chanlist_len) {
506                 printk(KERN_ERR
507                        "comedi%d: me4000: ai_check_chanlist(): "
508                        "No channel list available\n", dev->minor);
509                 return -EINVAL;
510         }
511
512         /* Check the channel list size */
513         if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
514                 printk(KERN_ERR
515                        "comedi%d: me4000: ai_check_chanlist(): "
516                        "Channel list is to large\n", dev->minor);
517                 return -EINVAL;
518         }
519
520         /* Check the pointer */
521         if (!cmd->chanlist) {
522                 printk(KERN_ERR
523                        "comedi%d: me4000: ai_check_chanlist(): "
524                        "NULL pointer to channel list\n", dev->minor);
525                 return -EFAULT;
526         }
527
528         /* Check whether aref is equal for all entries */
529         aref = CR_AREF(cmd->chanlist[0]);
530         for (i = 0; i < cmd->chanlist_len; i++) {
531                 if (CR_AREF(cmd->chanlist[i]) != aref) {
532                         printk(KERN_ERR
533                                "comedi%d: me4000: ai_check_chanlist(): "
534                                "Mode is not equal for all entries\n",
535                                dev->minor);
536                         return -EINVAL;
537                 }
538         }
539
540         /* Check whether channels are available for this ending */
541         if (aref == SDF_DIFF) {
542                 for (i = 0; i < cmd->chanlist_len; i++) {
543                         if (CR_CHAN(cmd->chanlist[i]) >=
544                             thisboard->ai_diff_nchan) {
545                                 printk(KERN_ERR
546                                        "comedi%d: me4000: ai_check_chanlist():"
547                                        " Channel number to high\n", dev->minor);
548                                 return -EINVAL;
549                         }
550                 }
551         } else {
552                 for (i = 0; i < cmd->chanlist_len; i++) {
553                         if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
554                                 printk(KERN_ERR
555                                        "comedi%d: me4000: ai_check_chanlist(): "
556                                        "Channel number to high\n", dev->minor);
557                                 return -EINVAL;
558                         }
559                 }
560         }
561
562         /* Check if bipolar is set for all entries when in differential mode */
563         if (aref == SDF_DIFF) {
564                 for (i = 0; i < cmd->chanlist_len; i++) {
565                         if (CR_RANGE(cmd->chanlist[i]) != 1 &&
566                             CR_RANGE(cmd->chanlist[i]) != 2) {
567                                 printk(KERN_ERR
568                                        "comedi%d: me4000: ai_check_chanlist(): "
569                                        "Bipolar is not selected in "
570                                        "differential mode\n",
571                                        dev->minor);
572                                 return -EINVAL;
573                         }
574                 }
575         }
576
577         return 0;
578 }
579
580 static int ai_round_cmd_args(struct comedi_device *dev,
581                              struct comedi_subdevice *s,
582                              struct comedi_cmd *cmd,
583                              unsigned int *init_ticks,
584                              unsigned int *scan_ticks, unsigned int *chan_ticks)
585 {
586
587         int rest;
588
589         *init_ticks = 0;
590         *scan_ticks = 0;
591         *chan_ticks = 0;
592
593         if (cmd->start_arg) {
594                 *init_ticks = (cmd->start_arg * 33) / 1000;
595                 rest = (cmd->start_arg * 33) % 1000;
596
597                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
598                         if (rest > 33)
599                                 (*init_ticks)++;
600                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
601                         if (rest)
602                                 (*init_ticks)++;
603                 }
604         }
605
606         if (cmd->scan_begin_arg) {
607                 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
608                 rest = (cmd->scan_begin_arg * 33) % 1000;
609
610                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
611                         if (rest > 33)
612                                 (*scan_ticks)++;
613                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
614                         if (rest)
615                                 (*scan_ticks)++;
616                 }
617         }
618
619         if (cmd->convert_arg) {
620                 *chan_ticks = (cmd->convert_arg * 33) / 1000;
621                 rest = (cmd->convert_arg * 33) % 1000;
622
623                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
624                         if (rest > 33)
625                                 (*chan_ticks)++;
626                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
627                         if (rest)
628                                 (*chan_ticks)++;
629                 }
630         }
631
632         return 0;
633 }
634
635 static void ai_write_timer(struct comedi_device *dev,
636                            unsigned int init_ticks,
637                            unsigned int scan_ticks, unsigned int chan_ticks)
638 {
639         outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
640         outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
641
642         if (scan_ticks) {
643                 outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
644                 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
645         }
646
647         outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
648         outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
649 }
650
651 static int ai_write_chanlist(struct comedi_device *dev,
652                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
653 {
654         unsigned int entry;
655         unsigned int chan;
656         unsigned int rang;
657         unsigned int aref;
658         int i;
659
660         for (i = 0; i < cmd->chanlist_len; i++) {
661                 chan = CR_CHAN(cmd->chanlist[i]);
662                 rang = CR_RANGE(cmd->chanlist[i]);
663                 aref = CR_AREF(cmd->chanlist[i]);
664
665                 entry = chan;
666
667                 if (rang == 0)
668                         entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
669                 else if (rang == 1)
670                         entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
671                 else if (rang == 2)
672                         entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
673                 else
674                         entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
675
676                 if (aref == SDF_DIFF)
677                         entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
678                 else
679                         entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
680
681                 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
682         }
683
684         return 0;
685 }
686
687 static int ai_prepare(struct comedi_device *dev,
688                       struct comedi_subdevice *s,
689                       struct comedi_cmd *cmd,
690                       unsigned int init_ticks,
691                       unsigned int scan_ticks, unsigned int chan_ticks)
692 {
693
694         unsigned long tmp = 0;
695
696         /* Write timer arguments */
697         ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
698
699         /* Reset control register */
700         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
701
702         /* Start sources */
703         if ((cmd->start_src == TRIG_EXT &&
704              cmd->scan_begin_src == TRIG_TIMER &&
705              cmd->convert_src == TRIG_TIMER) ||
706             (cmd->start_src == TRIG_EXT &&
707              cmd->scan_begin_src == TRIG_FOLLOW &&
708              cmd->convert_src == TRIG_TIMER)) {
709                 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
710                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
711                     ME4000_AI_CTRL_BIT_DATA_FIFO;
712         } else if (cmd->start_src == TRIG_EXT &&
713                    cmd->scan_begin_src == TRIG_EXT &&
714                    cmd->convert_src == TRIG_TIMER) {
715                 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
716                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
717                     ME4000_AI_CTRL_BIT_DATA_FIFO;
718         } else if (cmd->start_src == TRIG_EXT &&
719                    cmd->scan_begin_src == TRIG_EXT &&
720                    cmd->convert_src == TRIG_EXT) {
721                 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
722                     ME4000_AI_CTRL_BIT_MODE_1 |
723                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
724                     ME4000_AI_CTRL_BIT_DATA_FIFO;
725         } else {
726                 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
727                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
728                     ME4000_AI_CTRL_BIT_DATA_FIFO;
729         }
730
731         /* Stop triggers */
732         if (cmd->stop_src == TRIG_COUNT) {
733                 outl(cmd->chanlist_len * cmd->stop_arg,
734                             dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
735                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
736         } else if (cmd->stop_src == TRIG_NONE &&
737                    cmd->scan_end_src == TRIG_COUNT) {
738                 outl(cmd->scan_end_arg,
739                             dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
740                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
741         } else {
742                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
743         }
744
745         /* Write the setup to the control register */
746         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
747
748         /* Write the channel list */
749         ai_write_chanlist(dev, s, cmd);
750
751         return 0;
752 }
753
754 static int me4000_ai_do_cmd(struct comedi_device *dev,
755                             struct comedi_subdevice *s)
756 {
757         int err;
758         unsigned int init_ticks = 0;
759         unsigned int scan_ticks = 0;
760         unsigned int chan_ticks = 0;
761         struct comedi_cmd *cmd = &s->async->cmd;
762
763         /* Reset the analog input */
764         err = me4000_ai_cancel(dev, s);
765         if (err)
766                 return err;
767
768         /* Round the timer arguments */
769         err = ai_round_cmd_args(dev,
770                                 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
771         if (err)
772                 return err;
773
774         /* Prepare the AI for acquisition */
775         err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
776         if (err)
777                 return err;
778
779         /* Start acquistion by dummy read */
780         inl(dev->iobase + ME4000_AI_START_REG);
781
782         return 0;
783 }
784
785 /*
786  * me4000_ai_do_cmd_test():
787  *
788  * The demo cmd.c in ./comedilib/demo specifies 6 return values:
789  * - success
790  * - invalid source
791  * - source conflict
792  * - invalid argument
793  * - argument conflict
794  * - invalid chanlist
795  * So I tried to adopt this scheme.
796  */
797 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
798                                  struct comedi_subdevice *s,
799                                  struct comedi_cmd *cmd)
800 {
801
802         unsigned int init_ticks;
803         unsigned int chan_ticks;
804         unsigned int scan_ticks;
805         int err = 0;
806
807         /* Only rounding flags are implemented */
808         cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
809
810         /* Round the timer arguments */
811         ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
812
813         /*
814          * Stage 1. Check if the trigger sources are generally valid.
815          */
816         switch (cmd->start_src) {
817         case TRIG_NOW:
818         case TRIG_EXT:
819                 break;
820         case TRIG_ANY:
821                 cmd->start_src &= TRIG_NOW | TRIG_EXT;
822                 err++;
823                 break;
824         default:
825                 printk(KERN_ERR
826                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
827                        "Invalid start source\n", dev->minor);
828                 cmd->start_src = TRIG_NOW;
829                 err++;
830         }
831         switch (cmd->scan_begin_src) {
832         case TRIG_FOLLOW:
833         case TRIG_TIMER:
834         case TRIG_EXT:
835                 break;
836         case TRIG_ANY:
837                 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
838                 err++;
839                 break;
840         default:
841                 printk(KERN_ERR
842                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
843                        "Invalid scan begin source\n", dev->minor);
844                 cmd->scan_begin_src = TRIG_FOLLOW;
845                 err++;
846         }
847         switch (cmd->convert_src) {
848         case TRIG_TIMER:
849         case TRIG_EXT:
850                 break;
851         case TRIG_ANY:
852                 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
853                 err++;
854                 break;
855         default:
856                 printk(KERN_ERR
857                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
858                        "Invalid convert source\n", dev->minor);
859                 cmd->convert_src = TRIG_TIMER;
860                 err++;
861         }
862         switch (cmd->scan_end_src) {
863         case TRIG_NONE:
864         case TRIG_COUNT:
865                 break;
866         case TRIG_ANY:
867                 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
868                 err++;
869                 break;
870         default:
871                 printk(KERN_ERR
872                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
873                        "Invalid scan end source\n", dev->minor);
874                 cmd->scan_end_src = TRIG_NONE;
875                 err++;
876         }
877         switch (cmd->stop_src) {
878         case TRIG_NONE:
879         case TRIG_COUNT:
880                 break;
881         case TRIG_ANY:
882                 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
883                 err++;
884                 break;
885         default:
886                 printk(KERN_ERR
887                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
888                        "Invalid stop source\n", dev->minor);
889                 cmd->stop_src = TRIG_NONE;
890                 err++;
891         }
892         if (err)
893                 return 1;
894
895         /*
896          * Stage 2. Check for trigger source conflicts.
897          */
898         if (cmd->start_src == TRIG_NOW &&
899             cmd->scan_begin_src == TRIG_TIMER &&
900             cmd->convert_src == TRIG_TIMER) {
901         } else if (cmd->start_src == TRIG_NOW &&
902                    cmd->scan_begin_src == TRIG_FOLLOW &&
903                    cmd->convert_src == TRIG_TIMER) {
904         } else if (cmd->start_src == TRIG_EXT &&
905                    cmd->scan_begin_src == TRIG_TIMER &&
906                    cmd->convert_src == TRIG_TIMER) {
907         } else if (cmd->start_src == TRIG_EXT &&
908                    cmd->scan_begin_src == TRIG_FOLLOW &&
909                    cmd->convert_src == TRIG_TIMER) {
910         } else if (cmd->start_src == TRIG_EXT &&
911                    cmd->scan_begin_src == TRIG_EXT &&
912                    cmd->convert_src == TRIG_TIMER) {
913         } else if (cmd->start_src == TRIG_EXT &&
914                    cmd->scan_begin_src == TRIG_EXT &&
915                    cmd->convert_src == TRIG_EXT) {
916         } else {
917                 printk(KERN_ERR
918                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
919                        "Invalid start trigger combination\n", dev->minor);
920                 cmd->start_src = TRIG_NOW;
921                 cmd->scan_begin_src = TRIG_FOLLOW;
922                 cmd->convert_src = TRIG_TIMER;
923                 err++;
924         }
925
926         if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
927         } else if (cmd->stop_src == TRIG_COUNT &&
928                    cmd->scan_end_src == TRIG_NONE) {
929         } else if (cmd->stop_src == TRIG_NONE &&
930                    cmd->scan_end_src == TRIG_COUNT) {
931         } else if (cmd->stop_src == TRIG_COUNT &&
932                    cmd->scan_end_src == TRIG_COUNT) {
933         } else {
934                 printk(KERN_ERR
935                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
936                        "Invalid stop trigger combination\n", dev->minor);
937                 cmd->stop_src = TRIG_NONE;
938                 cmd->scan_end_src = TRIG_NONE;
939                 err++;
940         }
941         if (err)
942                 return 2;
943
944         /*
945          * Stage 3. Check if arguments are generally valid.
946          */
947         if (cmd->chanlist_len < 1) {
948                 printk(KERN_ERR
949                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
950                        "No channel list\n", dev->minor);
951                 cmd->chanlist_len = 1;
952                 err++;
953         }
954         if (init_ticks < 66) {
955                 printk(KERN_ERR
956                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
957                        "Start arg to low\n", dev->minor);
958                 cmd->start_arg = 2000;
959                 err++;
960         }
961         if (scan_ticks && scan_ticks < 67) {
962                 printk(KERN_ERR
963                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
964                        "Scan begin arg to low\n", dev->minor);
965                 cmd->scan_begin_arg = 2031;
966                 err++;
967         }
968         if (chan_ticks < 66) {
969                 printk(KERN_ERR
970                        "comedi%d: me4000: me4000_ai_do_cmd_test(): "
971                        "Convert arg to low\n", dev->minor);
972                 cmd->convert_arg = 2000;
973                 err++;
974         }
975
976         if (err)
977                 return 3;
978
979         /*
980          * Stage 4. Check for argument conflicts.
981          */
982         if (cmd->start_src == TRIG_NOW &&
983             cmd->scan_begin_src == TRIG_TIMER &&
984             cmd->convert_src == TRIG_TIMER) {
985
986                 /* Check timer arguments */
987                 if (init_ticks < ME4000_AI_MIN_TICKS) {
988                         printk(KERN_ERR
989                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
990                                "Invalid start arg\n", dev->minor);
991                         cmd->start_arg = 2000;  /*  66 ticks at least */
992                         err++;
993                 }
994                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
995                         printk(KERN_ERR
996                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
997                                "Invalid convert arg\n", dev->minor);
998                         cmd->convert_arg = 2000;        /*  66 ticks at least */
999                         err++;
1000                 }
1001                 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1002                         printk(KERN_ERR
1003                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1004                                "Invalid scan end arg\n", dev->minor);
1005
1006                         /*  At least one tick more */
1007                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1008                         err++;
1009                 }
1010         } else if (cmd->start_src == TRIG_NOW &&
1011                    cmd->scan_begin_src == TRIG_FOLLOW &&
1012                    cmd->convert_src == TRIG_TIMER) {
1013
1014                 /* Check timer arguments */
1015                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1016                         printk(KERN_ERR
1017                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1018                                "Invalid start arg\n", dev->minor);
1019                         cmd->start_arg = 2000;  /*  66 ticks at least */
1020                         err++;
1021                 }
1022                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1023                         printk(KERN_ERR
1024                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1025                                "Invalid convert arg\n", dev->minor);
1026                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1027                         err++;
1028                 }
1029         } else if (cmd->start_src == TRIG_EXT &&
1030                    cmd->scan_begin_src == TRIG_TIMER &&
1031                    cmd->convert_src == TRIG_TIMER) {
1032
1033                 /* Check timer arguments */
1034                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1035                         printk(KERN_ERR
1036                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1037                                "Invalid start arg\n", dev->minor);
1038                         cmd->start_arg = 2000;  /*  66 ticks at least */
1039                         err++;
1040                 }
1041                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1042                         printk(KERN_ERR
1043                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1044                                "Invalid convert arg\n", dev->minor);
1045                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1046                         err++;
1047                 }
1048                 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1049                         printk(KERN_ERR
1050                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1051                                "Invalid scan end arg\n", dev->minor);
1052
1053                         /*  At least one tick more */
1054                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1055                         err++;
1056                 }
1057         } else if (cmd->start_src == TRIG_EXT &&
1058                    cmd->scan_begin_src == TRIG_FOLLOW &&
1059                    cmd->convert_src == TRIG_TIMER) {
1060
1061                 /* Check timer arguments */
1062                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1063                         printk(KERN_ERR
1064                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1065                                "Invalid start arg\n", dev->minor);
1066                         cmd->start_arg = 2000;  /*  66 ticks at least */
1067                         err++;
1068                 }
1069                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1070                         printk(KERN_ERR
1071                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1072                                "Invalid convert arg\n", dev->minor);
1073                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1074                         err++;
1075                 }
1076         } else if (cmd->start_src == TRIG_EXT &&
1077                    cmd->scan_begin_src == TRIG_EXT &&
1078                    cmd->convert_src == TRIG_TIMER) {
1079
1080                 /* Check timer arguments */
1081                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1082                         printk(KERN_ERR
1083                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1084                                "Invalid start arg\n", dev->minor);
1085                         cmd->start_arg = 2000;  /*  66 ticks at least */
1086                         err++;
1087                 }
1088                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1089                         printk(KERN_ERR
1090                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1091                                "Invalid convert arg\n", dev->minor);
1092                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1093                         err++;
1094                 }
1095         } else if (cmd->start_src == TRIG_EXT &&
1096                    cmd->scan_begin_src == TRIG_EXT &&
1097                    cmd->convert_src == TRIG_EXT) {
1098
1099                 /* Check timer arguments */
1100                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1101                         printk(KERN_ERR
1102                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1103                                "Invalid start arg\n", dev->minor);
1104                         cmd->start_arg = 2000;  /*  66 ticks at least */
1105                         err++;
1106                 }
1107         }
1108         if (cmd->stop_src == TRIG_COUNT) {
1109                 if (cmd->stop_arg == 0) {
1110                         printk(KERN_ERR
1111                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1112                                "Invalid stop arg\n", dev->minor);
1113                         cmd->stop_arg = 1;
1114                         err++;
1115                 }
1116         }
1117         if (cmd->scan_end_src == TRIG_COUNT) {
1118                 if (cmd->scan_end_arg == 0) {
1119                         printk(KERN_ERR
1120                                "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1121                                "Invalid scan end arg\n", dev->minor);
1122                         cmd->scan_end_arg = 1;
1123                         err++;
1124                 }
1125         }
1126
1127         if (err)
1128                 return 4;
1129
1130         /*
1131          * Stage 5. Check the channel list.
1132          */
1133         if (ai_check_chanlist(dev, s, cmd))
1134                 return 5;
1135
1136         return 0;
1137 }
1138
1139 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1140 {
1141         unsigned int tmp;
1142         struct comedi_device *dev = dev_id;
1143         struct comedi_subdevice *s = &dev->subdevices[0];
1144         int i;
1145         int c = 0;
1146         long lval;
1147
1148         if (!dev->attached)
1149                 return IRQ_NONE;
1150
1151         /* Reset all events */
1152         s->async->events = 0;
1153
1154         /* Check if irq number is right */
1155         if (irq != dev->irq) {
1156                 printk(KERN_ERR
1157                        "comedi%d: me4000: me4000_ai_isr(): "
1158                        "Incorrect interrupt num: %d\n", dev->minor, irq);
1159                 return IRQ_HANDLED;
1160         }
1161
1162         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1163             ME4000_IRQ_STATUS_BIT_AI_HF) {
1164                 /* Read status register to find out what happened */
1165                 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1166
1167                 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1168                     !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1169                     (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1170                         c = ME4000_AI_FIFO_COUNT;
1171
1172                         /*
1173                          * FIFO overflow, so stop conversion
1174                          * and disable all interrupts
1175                          */
1176                         tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1177                         tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1178                                  ME4000_AI_CTRL_BIT_SC_IRQ);
1179                         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1180
1181                         s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1182
1183                         printk(KERN_ERR
1184                                "comedi%d: me4000: me4000_ai_isr(): "
1185                                "FIFO overflow\n", dev->minor);
1186                 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1187                            && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1188                            && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1189                         s->async->events |= COMEDI_CB_BLOCK;
1190
1191                         c = ME4000_AI_FIFO_COUNT / 2;
1192                 } else {
1193                         printk(KERN_ERR
1194                                "comedi%d: me4000: me4000_ai_isr(): "
1195                                "Can't determine state of fifo\n", dev->minor);
1196                         c = 0;
1197
1198                         /*
1199                          * Undefined state, so stop conversion
1200                          * and disable all interrupts
1201                          */
1202                         tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1203                         tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1204                                  ME4000_AI_CTRL_BIT_SC_IRQ);
1205                         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1206
1207                         s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1208
1209                         printk(KERN_ERR
1210                                "comedi%d: me4000: me4000_ai_isr(): "
1211                                "Undefined FIFO state\n", dev->minor);
1212                 }
1213
1214                 for (i = 0; i < c; i++) {
1215                         /* Read value from data fifo */
1216                         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1217                         lval ^= 0x8000;
1218
1219                         if (!comedi_buf_put(s->async, lval)) {
1220                                 /*
1221                                  * Buffer overflow, so stop conversion
1222                                  * and disable all interrupts
1223                                  */
1224                                 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1225                                 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1226                                          ME4000_AI_CTRL_BIT_SC_IRQ);
1227                                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1228
1229                                 s->async->events |= COMEDI_CB_OVERFLOW;
1230
1231                                 printk(KERN_ERR
1232                                        "comedi%d: me4000: me4000_ai_isr(): "
1233                                        "Buffer overflow\n", dev->minor);
1234
1235                                 break;
1236                         }
1237                 }
1238
1239                 /* Work is done, so reset the interrupt */
1240                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1241                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1242                 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1243                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1244         }
1245
1246         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1247             ME4000_IRQ_STATUS_BIT_SC) {
1248                 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1249
1250                 /*
1251                  * Acquisition is complete, so stop
1252                  * conversion and disable all interrupts
1253                  */
1254                 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1255                 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1256                 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1257                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1258
1259                 /* Poll data until fifo empty */
1260                 while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1261                        ME4000_AI_STATUS_BIT_EF_DATA) {
1262                         /* Read value from data fifo */
1263                         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1264                         lval ^= 0x8000;
1265
1266                         if (!comedi_buf_put(s->async, lval)) {
1267                                 printk(KERN_ERR
1268                                        "comedi%d: me4000: me4000_ai_isr(): "
1269                                        "Buffer overflow\n", dev->minor);
1270                                 s->async->events |= COMEDI_CB_OVERFLOW;
1271                                 break;
1272                         }
1273                 }
1274
1275                 /* Work is done, so reset the interrupt */
1276                 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1277                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1278                 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1279                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1280         }
1281
1282         if (s->async->events)
1283                 comedi_event(dev, s);
1284
1285         return IRQ_HANDLED;
1286 }
1287
1288 /*=============================================================================
1289   Analog output section
1290   ===========================================================================*/
1291
1292 static int me4000_ao_insn_write(struct comedi_device *dev,
1293                                 struct comedi_subdevice *s,
1294                                 struct comedi_insn *insn, unsigned int *data)
1295 {
1296         const struct me4000_board *thisboard = comedi_board(dev);
1297         struct me4000_info *info = dev->private;
1298         int chan = CR_CHAN(insn->chanspec);
1299         int rang = CR_RANGE(insn->chanspec);
1300         int aref = CR_AREF(insn->chanspec);
1301         unsigned long tmp;
1302
1303         if (insn->n == 0) {
1304                 return 0;
1305         } else if (insn->n > 1) {
1306                 printk(KERN_ERR
1307                        "comedi%d: me4000: me4000_ao_insn_write(): "
1308                        "Invalid instruction length %d\n", dev->minor, insn->n);
1309                 return -EINVAL;
1310         }
1311
1312         if (chan >= thisboard->ao_nchan) {
1313                 printk(KERN_ERR
1314                        "comedi%d: me4000: me4000_ao_insn_write(): "
1315                        "Invalid channel %d\n", dev->minor, insn->n);
1316                 return -EINVAL;
1317         }
1318
1319         if (rang != 0) {
1320                 printk(KERN_ERR
1321                        "comedi%d: me4000: me4000_ao_insn_write(): "
1322                        "Invalid range %d\n", dev->minor, insn->n);
1323                 return -EINVAL;
1324         }
1325
1326         if (aref != AREF_GROUND && aref != AREF_COMMON) {
1327                 printk(KERN_ERR
1328                        "comedi%d: me4000: me4000_ao_insn_write(): "
1329                        "Invalid aref %d\n", dev->minor, insn->n);
1330                 return -EINVAL;
1331         }
1332
1333         /* Stop any running conversion */
1334         tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1335         tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1336         outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1337
1338         /* Clear control register and set to single mode */
1339         outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1340
1341         /* Write data value */
1342         outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1343
1344         /* Store in the mirror */
1345         info->ao_readback[chan] = data[0];
1346
1347         return 1;
1348 }
1349
1350 static int me4000_ao_insn_read(struct comedi_device *dev,
1351                                struct comedi_subdevice *s,
1352                                struct comedi_insn *insn, unsigned int *data)
1353 {
1354         struct me4000_info *info = dev->private;
1355         int chan = CR_CHAN(insn->chanspec);
1356
1357         if (insn->n == 0) {
1358                 return 0;
1359         } else if (insn->n > 1) {
1360                 printk
1361                     ("comedi%d: me4000: me4000_ao_insn_read(): "
1362                      "Invalid instruction length\n", dev->minor);
1363                 return -EINVAL;
1364         }
1365
1366         data[0] = info->ao_readback[chan];
1367
1368         return 1;
1369 }
1370
1371 /*=============================================================================
1372   Digital I/O section
1373   ===========================================================================*/
1374
1375 static int me4000_dio_insn_bits(struct comedi_device *dev,
1376                                 struct comedi_subdevice *s,
1377                                 struct comedi_insn *insn, unsigned int *data)
1378 {
1379         /*
1380          * The insn data consists of a mask in data[0] and the new data
1381          * in data[1]. The mask defines which bits we are concerning about.
1382          * The new data must be anded with the mask.
1383          * Each channel corresponds to a bit.
1384          */
1385         if (data[0]) {
1386                 /* Check if requested ports are configured for output */
1387                 if ((s->io_bits & data[0]) != data[0])
1388                         return -EIO;
1389
1390                 s->state &= ~data[0];
1391                 s->state |= data[0] & data[1];
1392
1393                 /* Write out the new digital output lines */
1394                 outl((s->state >> 0) & 0xFF,
1395                             dev->iobase + ME4000_DIO_PORT_0_REG);
1396                 outl((s->state >> 8) & 0xFF,
1397                             dev->iobase + ME4000_DIO_PORT_1_REG);
1398                 outl((s->state >> 16) & 0xFF,
1399                             dev->iobase + ME4000_DIO_PORT_2_REG);
1400                 outl((s->state >> 24) & 0xFF,
1401                             dev->iobase + ME4000_DIO_PORT_3_REG);
1402         }
1403
1404         /* On return, data[1] contains the value of
1405            the digital input and output lines. */
1406         data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1407                   ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1408                   ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1409                   ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1410
1411         return insn->n;
1412 }
1413
1414 static int me4000_dio_insn_config(struct comedi_device *dev,
1415                                   struct comedi_subdevice *s,
1416                                   struct comedi_insn *insn, unsigned int *data)
1417 {
1418         unsigned long tmp;
1419         int chan = CR_CHAN(insn->chanspec);
1420
1421         switch (data[0]) {
1422         default:
1423                 return -EINVAL;
1424         case INSN_CONFIG_DIO_QUERY:
1425                 data[1] =
1426                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1427                 return insn->n;
1428         case INSN_CONFIG_DIO_INPUT:
1429         case INSN_CONFIG_DIO_OUTPUT:
1430                 break;
1431         }
1432
1433         /*
1434          * The input or output configuration of each digital line is
1435          * configured by a special insn_config instruction.  chanspec
1436          * contains the channel to be changed, and data[0] contains the
1437          * value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
1438          * On the ME-4000 it is only possible to switch port wise (8 bit)
1439          */
1440
1441         tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1442
1443         if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
1444                 if (chan < 8) {
1445                         s->io_bits |= 0xFF;
1446                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1447                                  ME4000_DIO_CTRL_BIT_MODE_1);
1448                         tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1449                 } else if (chan < 16) {
1450                         /*
1451                          * Chech for optoisolated ME-4000 version.
1452                          * If one the first port is a fixed output
1453                          * port and the second is a fixed input port.
1454                          */
1455                         if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1456                                 return -ENODEV;
1457
1458                         s->io_bits |= 0xFF00;
1459                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1460                                  ME4000_DIO_CTRL_BIT_MODE_3);
1461                         tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1462                 } else if (chan < 24) {
1463                         s->io_bits |= 0xFF0000;
1464                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1465                                  ME4000_DIO_CTRL_BIT_MODE_5);
1466                         tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1467                 } else if (chan < 32) {
1468                         s->io_bits |= 0xFF000000;
1469                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1470                                  ME4000_DIO_CTRL_BIT_MODE_7);
1471                         tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1472                 } else {
1473                         return -EINVAL;
1474                 }
1475         } else {
1476                 if (chan < 8) {
1477                         /*
1478                          * Chech for optoisolated ME-4000 version.
1479                          * If one the first port is a fixed output
1480                          * port and the second is a fixed input port.
1481                          */
1482                         if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1483                                 return -ENODEV;
1484
1485                         s->io_bits &= ~0xFF;
1486                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1487                                  ME4000_DIO_CTRL_BIT_MODE_1);
1488                 } else if (chan < 16) {
1489                         s->io_bits &= ~0xFF00;
1490                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1491                                  ME4000_DIO_CTRL_BIT_MODE_3);
1492                 } else if (chan < 24) {
1493                         s->io_bits &= ~0xFF0000;
1494                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1495                                  ME4000_DIO_CTRL_BIT_MODE_5);
1496                 } else if (chan < 32) {
1497                         s->io_bits &= ~0xFF000000;
1498                         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1499                                  ME4000_DIO_CTRL_BIT_MODE_7);
1500                 } else {
1501                         return -EINVAL;
1502                 }
1503         }
1504
1505         outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1506
1507         return 1;
1508 }
1509
1510 /*=============================================================================
1511   Counter section
1512   ===========================================================================*/
1513
1514 static int cnt_reset(struct comedi_device *dev, unsigned int channel)
1515 {
1516         struct me4000_info *info = dev->private;
1517
1518         switch (channel) {
1519         case 0:
1520                 outb(0x30, info->timer_regbase + ME4000_CNT_CTRL_REG);
1521                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1522                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1523                 break;
1524         case 1:
1525                 outb(0x70, info->timer_regbase + ME4000_CNT_CTRL_REG);
1526                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1527                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1528                 break;
1529         case 2:
1530                 outb(0xB0, info->timer_regbase + ME4000_CNT_CTRL_REG);
1531                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1532                 outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1533                 break;
1534         default:
1535                 printk(KERN_ERR
1536                        "comedi%d: me4000: cnt_reset(): Invalid channel\n",
1537                        dev->minor);
1538                 return -EINVAL;
1539         }
1540
1541         return 0;
1542 }
1543
1544 static int cnt_config(struct comedi_device *dev, unsigned int channel,
1545                       unsigned int mode)
1546 {
1547         struct me4000_info *info = dev->private;
1548         int tmp = 0;
1549
1550         switch (channel) {
1551         case 0:
1552                 tmp |= ME4000_CNT_COUNTER_0;
1553                 break;
1554         case 1:
1555                 tmp |= ME4000_CNT_COUNTER_1;
1556                 break;
1557         case 2:
1558                 tmp |= ME4000_CNT_COUNTER_2;
1559                 break;
1560         default:
1561                 printk(KERN_ERR
1562                        "comedi%d: me4000: cnt_config(): Invalid channel\n",
1563                        dev->minor);
1564                 return -EINVAL;
1565         }
1566
1567         switch (mode) {
1568         case 0:
1569                 tmp |= ME4000_CNT_MODE_0;
1570                 break;
1571         case 1:
1572                 tmp |= ME4000_CNT_MODE_1;
1573                 break;
1574         case 2:
1575                 tmp |= ME4000_CNT_MODE_2;
1576                 break;
1577         case 3:
1578                 tmp |= ME4000_CNT_MODE_3;
1579                 break;
1580         case 4:
1581                 tmp |= ME4000_CNT_MODE_4;
1582                 break;
1583         case 5:
1584                 tmp |= ME4000_CNT_MODE_5;
1585                 break;
1586         default:
1587                 printk(KERN_ERR
1588                        "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
1589                        dev->minor);
1590                 return -EINVAL;
1591         }
1592
1593         /* Write the control word */
1594         tmp |= 0x30;
1595         outb(tmp, info->timer_regbase + ME4000_CNT_CTRL_REG);
1596
1597         return 0;
1598 }
1599
1600 static int me4000_cnt_insn_config(struct comedi_device *dev,
1601                                   struct comedi_subdevice *s,
1602                                   struct comedi_insn *insn, unsigned int *data)
1603 {
1604
1605         int err;
1606
1607         switch (data[0]) {
1608         case GPCT_RESET:
1609                 if (insn->n != 1) {
1610                         printk(KERN_ERR
1611                                "comedi%d: me4000: me4000_cnt_insn_config(): "
1612                                "Invalid instruction length%d\n",
1613                                dev->minor, insn->n);
1614                         return -EINVAL;
1615                 }
1616
1617                 err = cnt_reset(dev, insn->chanspec);
1618                 if (err)
1619                         return err;
1620                 break;
1621         case GPCT_SET_OPERATION:
1622                 if (insn->n != 2) {
1623                         printk(KERN_ERR
1624                                "comedi%d: me4000: me4000_cnt_insn_config(): "
1625                                "Invalid instruction length%d\n",
1626                                dev->minor, insn->n);
1627                         return -EINVAL;
1628                 }
1629
1630                 err = cnt_config(dev, insn->chanspec, data[1]);
1631                 if (err)
1632                         return err;
1633                 break;
1634         default:
1635                 printk(KERN_ERR
1636                        "comedi%d: me4000: me4000_cnt_insn_config(): "
1637                        "Invalid instruction\n", dev->minor);
1638                 return -EINVAL;
1639         }
1640
1641         return 2;
1642 }
1643
1644 static int me4000_cnt_insn_read(struct comedi_device *dev,
1645                                 struct comedi_subdevice *s,
1646                                 struct comedi_insn *insn, unsigned int *data)
1647 {
1648         struct me4000_info *info = dev->private;
1649         unsigned short tmp;
1650
1651         if (insn->n == 0)
1652                 return 0;
1653
1654         if (insn->n > 1) {
1655                 printk(KERN_ERR
1656                        "comedi%d: me4000: me4000_cnt_insn_read(): "
1657                        "Invalid instruction length %d\n",
1658                        dev->minor, insn->n);
1659                 return -EINVAL;
1660         }
1661
1662         switch (insn->chanspec) {
1663         case 0:
1664                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1665                 data[0] = tmp;
1666                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1667                 data[0] |= tmp << 8;
1668                 break;
1669         case 1:
1670                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1671                 data[0] = tmp;
1672                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1673                 data[0] |= tmp << 8;
1674                 break;
1675         case 2:
1676                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1677                 data[0] = tmp;
1678                 tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1679                 data[0] |= tmp << 8;
1680                 break;
1681         default:
1682                 printk(KERN_ERR
1683                        "comedi%d: me4000: me4000_cnt_insn_read(): "
1684                        "Invalid channel %d\n",
1685                        dev->minor, insn->chanspec);
1686                 return -EINVAL;
1687         }
1688
1689         return 1;
1690 }
1691
1692 static int me4000_cnt_insn_write(struct comedi_device *dev,
1693                                  struct comedi_subdevice *s,
1694                                  struct comedi_insn *insn, unsigned int *data)
1695 {
1696         struct me4000_info *info = dev->private;
1697         unsigned short tmp;
1698
1699         if (insn->n == 0) {
1700                 return 0;
1701         } else if (insn->n > 1) {
1702                 printk(KERN_ERR
1703                        "comedi%d: me4000: me4000_cnt_insn_write(): "
1704                        "Invalid instruction length %d\n",
1705                        dev->minor, insn->n);
1706                 return -EINVAL;
1707         }
1708
1709         switch (insn->chanspec) {
1710         case 0:
1711                 tmp = data[0] & 0xFF;
1712                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1713                 tmp = (data[0] >> 8) & 0xFF;
1714                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG);
1715                 break;
1716         case 1:
1717                 tmp = data[0] & 0xFF;
1718                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1719                 tmp = (data[0] >> 8) & 0xFF;
1720                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG);
1721                 break;
1722         case 2:
1723                 tmp = data[0] & 0xFF;
1724                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1725                 tmp = (data[0] >> 8) & 0xFF;
1726                 outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG);
1727                 break;
1728         default:
1729                 printk(KERN_ERR
1730                        "comedi%d: me4000: me4000_cnt_insn_write(): "
1731                        "Invalid channel %d\n",
1732                        dev->minor, insn->chanspec);
1733                 return -EINVAL;
1734         }
1735
1736         return 1;
1737 }
1738
1739 static const void *me4000_find_boardinfo(struct comedi_device *dev,
1740                                          struct pci_dev *pcidev)
1741 {
1742         const struct me4000_board *thisboard;
1743         int i;
1744
1745         for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) {
1746                 thisboard = &me4000_boards[i];
1747                 if (thisboard->device_id == pcidev->device)
1748                         return thisboard;
1749         }
1750         return NULL;
1751 }
1752
1753 static int me4000_attach_pci(struct comedi_device *dev,
1754                              struct pci_dev *pcidev)
1755 {
1756         const struct me4000_board *thisboard;
1757         struct me4000_info *info;
1758         struct comedi_subdevice *s;
1759         int result;
1760
1761         comedi_set_hw_dev(dev, &pcidev->dev);
1762
1763         thisboard = me4000_find_boardinfo(dev, pcidev);
1764         if (!thisboard)
1765                 return -ENODEV;
1766         dev->board_ptr = thisboard;
1767         dev->board_name = thisboard->name;
1768
1769         result = alloc_private(dev, sizeof(*info));
1770         if (result)
1771                 return result;
1772         info = dev->private;
1773
1774         result = comedi_pci_enable(pcidev, dev->board_name);
1775         if (result)
1776                 return result;
1777
1778         info->plx_regbase = pci_resource_start(pcidev, 1);
1779         dev->iobase = pci_resource_start(pcidev, 2);
1780         info->timer_regbase = pci_resource_start(pcidev, 3);
1781         if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1782                 return -ENODEV;
1783
1784         result = xilinx_download(dev);
1785         if (result)
1786                 return result;
1787
1788         result = reset_board(dev);
1789         if (result)
1790                 return result;
1791
1792         result = comedi_alloc_subdevices(dev, 4);
1793         if (result)
1794                 return result;
1795
1796     /*=========================================================================
1797       Analog input subdevice
1798       ========================================================================*/
1799
1800         s = &dev->subdevices[0];
1801
1802         if (thisboard->ai_nchan) {
1803                 s->type = COMEDI_SUBD_AI;
1804                 s->subdev_flags =
1805                     SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1806                 s->n_chan = thisboard->ai_nchan;
1807                 s->maxdata = 0xFFFF;    /*  16 bit ADC */
1808                 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1809                 s->range_table = &me4000_ai_range;
1810                 s->insn_read = me4000_ai_insn_read;
1811
1812                 if (pcidev->irq > 0) {
1813                         if (request_irq(pcidev->irq, me4000_ai_isr,
1814                                         IRQF_SHARED, dev->board_name, dev)) {
1815                                 dev_warn(dev->class_dev,
1816                                         "request_irq failed\n");
1817                         } else {
1818                                 dev->read_subdev = s;
1819                                 s->subdev_flags |= SDF_CMD_READ;
1820                                 s->cancel = me4000_ai_cancel;
1821                                 s->do_cmdtest = me4000_ai_do_cmd_test;
1822                                 s->do_cmd = me4000_ai_do_cmd;
1823
1824                                 dev->irq = pcidev->irq;
1825                         }
1826                 } else {
1827                         dev_warn(dev->class_dev, "No interrupt available\n");
1828                 }
1829         } else {
1830                 s->type = COMEDI_SUBD_UNUSED;
1831         }
1832
1833     /*=========================================================================
1834       Analog output subdevice
1835       ========================================================================*/
1836
1837         s = &dev->subdevices[1];
1838
1839         if (thisboard->ao_nchan) {
1840                 s->type = COMEDI_SUBD_AO;
1841                 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1842                 s->n_chan = thisboard->ao_nchan;
1843                 s->maxdata = 0xFFFF;    /*  16 bit DAC */
1844                 s->range_table = &range_bipolar10;
1845                 s->insn_write = me4000_ao_insn_write;
1846                 s->insn_read = me4000_ao_insn_read;
1847         } else {
1848                 s->type = COMEDI_SUBD_UNUSED;
1849         }
1850
1851     /*=========================================================================
1852       Digital I/O subdevice
1853       ========================================================================*/
1854
1855         s = &dev->subdevices[2];
1856
1857         if (thisboard->dio_nchan) {
1858                 s->type = COMEDI_SUBD_DIO;
1859                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1860                 s->n_chan = thisboard->dio_nchan;
1861                 s->maxdata = 1;
1862                 s->range_table = &range_digital;
1863                 s->insn_bits = me4000_dio_insn_bits;
1864                 s->insn_config = me4000_dio_insn_config;
1865         } else {
1866                 s->type = COMEDI_SUBD_UNUSED;
1867         }
1868
1869         /*
1870          * Check for optoisolated ME-4000 version. If one the first
1871          * port is a fixed output port and the second is a fixed input port.
1872          */
1873         if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1874                 s->io_bits |= 0xFF;
1875                 outl(ME4000_DIO_CTRL_BIT_MODE_0,
1876                         dev->iobase + ME4000_DIO_DIR_REG);
1877         }
1878
1879     /*=========================================================================
1880       Counter subdevice
1881       ========================================================================*/
1882
1883         s = &dev->subdevices[3];
1884
1885         if (thisboard->has_counter) {
1886                 s->type = COMEDI_SUBD_COUNTER;
1887                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1888                 s->n_chan = 3;
1889                 s->maxdata = 0xFFFF;    /*  16 bit counters */
1890                 s->insn_read = me4000_cnt_insn_read;
1891                 s->insn_write = me4000_cnt_insn_write;
1892                 s->insn_config = me4000_cnt_insn_config;
1893         } else {
1894                 s->type = COMEDI_SUBD_UNUSED;
1895         }
1896
1897         return 0;
1898 }
1899
1900 static void me4000_detach(struct comedi_device *dev)
1901 {
1902         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1903
1904         if (dev->irq)
1905                 free_irq(dev->irq, dev);
1906         if (pcidev) {
1907                 if (dev->iobase) {
1908                         reset_board(dev);
1909                         comedi_pci_disable(pcidev);
1910                 }
1911         }
1912 }
1913
1914 static struct comedi_driver me4000_driver = {
1915         .driver_name    = "me4000",
1916         .module         = THIS_MODULE,
1917         .attach_pci     = me4000_attach_pci,
1918         .detach         = me4000_detach,
1919 };
1920
1921 static int __devinit me4000_pci_probe(struct pci_dev *dev,
1922                                       const struct pci_device_id *ent)
1923 {
1924         return comedi_pci_auto_config(dev, &me4000_driver);
1925 }
1926
1927 static void __devexit me4000_pci_remove(struct pci_dev *dev)
1928 {
1929         comedi_pci_auto_unconfig(dev);
1930 }
1931
1932 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
1933         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650)},
1934         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660)},
1935         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I)},
1936         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660S)},
1937         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660IS)},
1938         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670)},
1939         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I)},
1940         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S)},
1941         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS)},
1942         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680)},
1943         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I)},
1944         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S)},
1945         {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS)},
1946         {0}
1947 };
1948 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1949
1950 static struct pci_driver me4000_pci_driver = {
1951         .name           = "me4000",
1952         .id_table       = me4000_pci_table,
1953         .probe          = me4000_pci_probe,
1954         .remove         = __devexit_p(me4000_pci_remove),
1955 };
1956 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1957
1958 MODULE_AUTHOR("Comedi http://www.comedi.org");
1959 MODULE_DESCRIPTION("Comedi low-level driver");
1960 MODULE_LICENSE("GPL");