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