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