Mention branches and keyring.
[releases.git] / drivers / me4000.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * me4000.c
4  * Source code for the Meilhaus ME-4000 board family.
5  *
6  * COMEDI - Linux Control and Measurement Device Interface
7  * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8  */
9
10 /*
11  * Driver: me4000
12  * Description: Meilhaus ME-4000 series boards
13  * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i,
14  *          ME-4680is
15  * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
16  * Updated: Mon, 18 Mar 2002 15:34:01 -0800
17  * Status: untested
18  *
19  * Supports:
20  *      - Analog Input
21  *      - Analog Output
22  *      - Digital I/O
23  *      - Counter
24  *
25  * Configuration Options: not applicable, uses PCI auto config
26  *
27  * The firmware required by these boards is available in the
28  * comedi_nonfree_firmware tarball available from
29  * https://www.comedi.org.
30  */
31
32 #include <linux/module.h>
33 #include <linux/delay.h>
34 #include <linux/interrupt.h>
35 #include <linux/comedi/comedi_pci.h>
36 #include <linux/comedi/comedi_8254.h>
37
38 #include "plx9052.h"
39
40 #define ME4000_FIRMWARE         "/*(DEBLOBBED)*/"
41
42 /*
43  * ME4000 Register map and bit defines
44  */
45 #define ME4000_AO_CHAN(x)                       ((x) * 0x18)
46
47 #define ME4000_AO_CTRL_REG(x)                   (0x00 + ME4000_AO_CHAN(x))
48 #define ME4000_AO_CTRL_MODE_0                   BIT(0)
49 #define ME4000_AO_CTRL_MODE_1                   BIT(1)
50 #define ME4000_AO_CTRL_STOP                     BIT(2)
51 #define ME4000_AO_CTRL_ENABLE_FIFO              BIT(3)
52 #define ME4000_AO_CTRL_ENABLE_EX_TRIG           BIT(4)
53 #define ME4000_AO_CTRL_EX_TRIG_EDGE             BIT(5)
54 #define ME4000_AO_CTRL_IMMEDIATE_STOP           BIT(7)
55 #define ME4000_AO_CTRL_ENABLE_DO                BIT(8)
56 #define ME4000_AO_CTRL_ENABLE_IRQ               BIT(9)
57 #define ME4000_AO_CTRL_RESET_IRQ                BIT(10)
58 #define ME4000_AO_STATUS_REG(x)                 (0x04 + ME4000_AO_CHAN(x))
59 #define ME4000_AO_STATUS_FSM                    BIT(0)
60 #define ME4000_AO_STATUS_FF                     BIT(1)
61 #define ME4000_AO_STATUS_HF                     BIT(2)
62 #define ME4000_AO_STATUS_EF                     BIT(3)
63 #define ME4000_AO_FIFO_REG(x)                   (0x08 + ME4000_AO_CHAN(x))
64 #define ME4000_AO_SINGLE_REG(x)                 (0x0c + ME4000_AO_CHAN(x))
65 #define ME4000_AO_TIMER_REG(x)                  (0x10 + ME4000_AO_CHAN(x))
66 #define ME4000_AI_CTRL_REG                      0x74
67 #define ME4000_AI_STATUS_REG                    0x74
68 #define ME4000_AI_CTRL_MODE_0                   BIT(0)
69 #define ME4000_AI_CTRL_MODE_1                   BIT(1)
70 #define ME4000_AI_CTRL_MODE_2                   BIT(2)
71 #define ME4000_AI_CTRL_SAMPLE_HOLD              BIT(3)
72 #define ME4000_AI_CTRL_IMMEDIATE_STOP           BIT(4)
73 #define ME4000_AI_CTRL_STOP                     BIT(5)
74 #define ME4000_AI_CTRL_CHANNEL_FIFO             BIT(6)
75 #define ME4000_AI_CTRL_DATA_FIFO                BIT(7)
76 #define ME4000_AI_CTRL_FULLSCALE                BIT(8)
77 #define ME4000_AI_CTRL_OFFSET                   BIT(9)
78 #define ME4000_AI_CTRL_EX_TRIG_ANALOG           BIT(10)
79 #define ME4000_AI_CTRL_EX_TRIG                  BIT(11)
80 #define ME4000_AI_CTRL_EX_TRIG_FALLING          BIT(12)
81 #define ME4000_AI_CTRL_EX_IRQ                   BIT(13)
82 #define ME4000_AI_CTRL_EX_IRQ_RESET             BIT(14)
83 #define ME4000_AI_CTRL_LE_IRQ                   BIT(15)
84 #define ME4000_AI_CTRL_LE_IRQ_RESET             BIT(16)
85 #define ME4000_AI_CTRL_HF_IRQ                   BIT(17)
86 #define ME4000_AI_CTRL_HF_IRQ_RESET             BIT(18)
87 #define ME4000_AI_CTRL_SC_IRQ                   BIT(19)
88 #define ME4000_AI_CTRL_SC_IRQ_RESET             BIT(20)
89 #define ME4000_AI_CTRL_SC_RELOAD                BIT(21)
90 #define ME4000_AI_STATUS_EF_CHANNEL             BIT(22)
91 #define ME4000_AI_STATUS_HF_CHANNEL             BIT(23)
92 #define ME4000_AI_STATUS_FF_CHANNEL             BIT(24)
93 #define ME4000_AI_STATUS_EF_DATA                BIT(25)
94 #define ME4000_AI_STATUS_HF_DATA                BIT(26)
95 #define ME4000_AI_STATUS_FF_DATA                BIT(27)
96 #define ME4000_AI_STATUS_LE                     BIT(28)
97 #define ME4000_AI_STATUS_FSM                    BIT(29)
98 #define ME4000_AI_CTRL_EX_TRIG_BOTH             BIT(31)
99 #define ME4000_AI_CHANNEL_LIST_REG              0x78
100 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL       BIT(5)
101 #define ME4000_AI_LIST_RANGE(x)                 ((3 - ((x) & 3)) << 6)
102 #define ME4000_AI_LIST_LAST_ENTRY               BIT(8)
103 #define ME4000_AI_DATA_REG                      0x7c
104 #define ME4000_AI_CHAN_TIMER_REG                0x80
105 #define ME4000_AI_CHAN_PRE_TIMER_REG            0x84
106 #define ME4000_AI_SCAN_TIMER_LOW_REG            0x88
107 #define ME4000_AI_SCAN_TIMER_HIGH_REG           0x8c
108 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG        0x90
109 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG       0x94
110 #define ME4000_AI_START_REG                     0x98
111 #define ME4000_IRQ_STATUS_REG                   0x9c
112 #define ME4000_IRQ_STATUS_EX                    BIT(0)
113 #define ME4000_IRQ_STATUS_LE                    BIT(1)
114 #define ME4000_IRQ_STATUS_AI_HF                 BIT(2)
115 #define ME4000_IRQ_STATUS_AO_0_HF               BIT(3)
116 #define ME4000_IRQ_STATUS_AO_1_HF               BIT(4)
117 #define ME4000_IRQ_STATUS_AO_2_HF               BIT(5)
118 #define ME4000_IRQ_STATUS_AO_3_HF               BIT(6)
119 #define ME4000_IRQ_STATUS_SC                    BIT(7)
120 #define ME4000_DIO_PORT_0_REG                   0xa0
121 #define ME4000_DIO_PORT_1_REG                   0xa4
122 #define ME4000_DIO_PORT_2_REG                   0xa8
123 #define ME4000_DIO_PORT_3_REG                   0xac
124 #define ME4000_DIO_DIR_REG                      0xb0
125 #define ME4000_AO_LOADSETREG_XX                 0xb4
126 #define ME4000_DIO_CTRL_REG                     0xb8
127 #define ME4000_DIO_CTRL_MODE_0                  BIT(0)
128 #define ME4000_DIO_CTRL_MODE_1                  BIT(1)
129 #define ME4000_DIO_CTRL_MODE_2                  BIT(2)
130 #define ME4000_DIO_CTRL_MODE_3                  BIT(3)
131 #define ME4000_DIO_CTRL_MODE_4                  BIT(4)
132 #define ME4000_DIO_CTRL_MODE_5                  BIT(5)
133 #define ME4000_DIO_CTRL_MODE_6                  BIT(6)
134 #define ME4000_DIO_CTRL_MODE_7                  BIT(7)
135 #define ME4000_DIO_CTRL_FUNCTION_0              BIT(8)
136 #define ME4000_DIO_CTRL_FUNCTION_1              BIT(9)
137 #define ME4000_DIO_CTRL_FIFO_HIGH_0             BIT(10)
138 #define ME4000_DIO_CTRL_FIFO_HIGH_1             BIT(11)
139 #define ME4000_DIO_CTRL_FIFO_HIGH_2             BIT(12)
140 #define ME4000_DIO_CTRL_FIFO_HIGH_3             BIT(13)
141 #define ME4000_AO_DEMUX_ADJUST_REG              0xbc
142 #define ME4000_AO_DEMUX_ADJUST_VALUE            0x4c
143 #define ME4000_AI_SAMPLE_COUNTER_REG            0xc0
144
145 #define ME4000_AI_FIFO_COUNT                    2048
146
147 #define ME4000_AI_MIN_TICKS                     66
148 #define ME4000_AI_MIN_SAMPLE_TIME               2000
149
150 #define ME4000_AI_CHANNEL_LIST_COUNT            1024
151
152 struct me4000_private {
153         unsigned long plx_regbase;
154         unsigned int ai_ctrl_mode;
155         unsigned int ai_init_ticks;
156         unsigned int ai_scan_ticks;
157         unsigned int ai_chan_ticks;
158 };
159
160 enum me4000_boardid {
161         BOARD_ME4650,
162         BOARD_ME4660,
163         BOARD_ME4660I,
164         BOARD_ME4660S,
165         BOARD_ME4660IS,
166         BOARD_ME4670,
167         BOARD_ME4670I,
168         BOARD_ME4670S,
169         BOARD_ME4670IS,
170         BOARD_ME4680,
171         BOARD_ME4680I,
172         BOARD_ME4680S,
173         BOARD_ME4680IS,
174 };
175
176 struct me4000_board {
177         const char *name;
178         int ai_nchan;
179         unsigned int can_do_diff_ai:1;
180         unsigned int can_do_sh_ai:1;    /* sample & hold (8 channels) */
181         unsigned int ex_trig_analog:1;
182         unsigned int has_ao:1;
183         unsigned int has_ao_fifo:1;
184         unsigned int has_counter:1;
185 };
186
187 static const struct me4000_board me4000_boards[] = {
188         [BOARD_ME4650] = {
189                 .name           = "ME-4650",
190                 .ai_nchan       = 16,
191         },
192         [BOARD_ME4660] = {
193                 .name           = "ME-4660",
194                 .ai_nchan       = 32,
195                 .can_do_diff_ai = 1,
196                 .has_counter    = 1,
197         },
198         [BOARD_ME4660I] = {
199                 .name           = "ME-4660i",
200                 .ai_nchan       = 32,
201                 .can_do_diff_ai = 1,
202                 .has_counter    = 1,
203         },
204         [BOARD_ME4660S] = {
205                 .name           = "ME-4660s",
206                 .ai_nchan       = 32,
207                 .can_do_diff_ai = 1,
208                 .can_do_sh_ai   = 1,
209                 .has_counter    = 1,
210         },
211         [BOARD_ME4660IS] = {
212                 .name           = "ME-4660is",
213                 .ai_nchan       = 32,
214                 .can_do_diff_ai = 1,
215                 .can_do_sh_ai   = 1,
216                 .has_counter    = 1,
217         },
218         [BOARD_ME4670] = {
219                 .name           = "ME-4670",
220                 .ai_nchan       = 32,
221                 .can_do_diff_ai = 1,
222                 .ex_trig_analog = 1,
223                 .has_ao         = 1,
224                 .has_counter    = 1,
225         },
226         [BOARD_ME4670I] = {
227                 .name           = "ME-4670i",
228                 .ai_nchan       = 32,
229                 .can_do_diff_ai = 1,
230                 .ex_trig_analog = 1,
231                 .has_ao         = 1,
232                 .has_counter    = 1,
233         },
234         [BOARD_ME4670S] = {
235                 .name           = "ME-4670s",
236                 .ai_nchan       = 32,
237                 .can_do_diff_ai = 1,
238                 .can_do_sh_ai   = 1,
239                 .ex_trig_analog = 1,
240                 .has_ao         = 1,
241                 .has_counter    = 1,
242         },
243         [BOARD_ME4670IS] = {
244                 .name           = "ME-4670is",
245                 .ai_nchan       = 32,
246                 .can_do_diff_ai = 1,
247                 .can_do_sh_ai   = 1,
248                 .ex_trig_analog = 1,
249                 .has_ao         = 1,
250                 .has_counter    = 1,
251         },
252         [BOARD_ME4680] = {
253                 .name           = "ME-4680",
254                 .ai_nchan       = 32,
255                 .can_do_diff_ai = 1,
256                 .ex_trig_analog = 1,
257                 .has_ao         = 1,
258                 .has_ao_fifo    = 1,
259                 .has_counter    = 1,
260         },
261         [BOARD_ME4680I] = {
262                 .name           = "ME-4680i",
263                 .ai_nchan       = 32,
264                 .can_do_diff_ai = 1,
265                 .ex_trig_analog = 1,
266                 .has_ao         = 1,
267                 .has_ao_fifo    = 1,
268                 .has_counter    = 1,
269         },
270         [BOARD_ME4680S] = {
271                 .name           = "ME-4680s",
272                 .ai_nchan       = 32,
273                 .can_do_diff_ai = 1,
274                 .can_do_sh_ai   = 1,
275                 .ex_trig_analog = 1,
276                 .has_ao         = 1,
277                 .has_ao_fifo    = 1,
278                 .has_counter    = 1,
279         },
280         [BOARD_ME4680IS] = {
281                 .name           = "ME-4680is",
282                 .ai_nchan       = 32,
283                 .can_do_diff_ai = 1,
284                 .can_do_sh_ai   = 1,
285                 .ex_trig_analog = 1,
286                 .has_ao         = 1,
287                 .has_ao_fifo    = 1,
288                 .has_counter    = 1,
289         },
290 };
291
292 /*
293  * NOTE: the ranges here are inverted compared to the values
294  * written to the ME4000_AI_CHANNEL_LIST_REG,
295  *
296  * The ME4000_AI_LIST_RANGE() macro handles the inversion.
297  */
298 static const struct comedi_lrange me4000_ai_range = {
299         4, {
300                 UNI_RANGE(2.5),
301                 UNI_RANGE(10),
302                 BIP_RANGE(2.5),
303                 BIP_RANGE(10)
304         }
305 };
306
307 static int me4000_xilinx_download(struct comedi_device *dev,
308                                   const u8 *data, size_t size,
309                                   unsigned long context)
310 {
311         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
312         struct me4000_private *devpriv = dev->private;
313         unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
314         unsigned int file_length;
315         unsigned int val;
316         unsigned int i;
317
318         if (!xilinx_iobase)
319                 return -ENODEV;
320
321         /*
322          * Set PLX local interrupt 2 polarity to high.
323          * Interrupt is thrown by init pin of xilinx.
324          */
325         outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR);
326
327         /* Set /CS and /WRITE of the Xilinx */
328         val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
329         val |= PLX9052_CNTRL_UIO2_DATA;
330         outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
331
332         /* Init Xilinx with CS1 */
333         inb(xilinx_iobase + 0xC8);
334
335         /* Wait until /INIT pin is set */
336         usleep_range(20, 1000);
337         val = inl(devpriv->plx_regbase + PLX9052_INTCSR);
338         if (!(val & PLX9052_INTCSR_LI2STAT)) {
339                 dev_err(dev->class_dev, "Can't init Xilinx\n");
340                 return -EIO;
341         }
342
343         /* Reset /CS and /WRITE of the Xilinx */
344         val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
345         val &= ~PLX9052_CNTRL_UIO2_DATA;
346         outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
347
348         /* Download Xilinx firmware */
349         file_length = (((unsigned int)data[0] & 0xff) << 24) +
350                       (((unsigned int)data[1] & 0xff) << 16) +
351                       (((unsigned int)data[2] & 0xff) << 8) +
352                       ((unsigned int)data[3] & 0xff);
353         usleep_range(10, 1000);
354
355         for (i = 0; i < file_length; i++) {
356                 outb(data[16 + i], xilinx_iobase);
357                 usleep_range(10, 1000);
358
359                 /* Check if BUSY flag is low */
360                 val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
361                 if (val & PLX9052_CNTRL_UIO1_DATA) {
362                         dev_err(dev->class_dev,
363                                 "Xilinx is still busy (i = %d)\n", i);
364                         return -EIO;
365                 }
366         }
367
368         /* If done flag is high download was successful */
369         val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
370         if (!(val & PLX9052_CNTRL_UIO0_DATA)) {
371                 dev_err(dev->class_dev, "DONE flag is not set\n");
372                 dev_err(dev->class_dev, "Download not successful\n");
373                 return -EIO;
374         }
375
376         /* Set /CS and /WRITE */
377         val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
378         val |= PLX9052_CNTRL_UIO2_DATA;
379         outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
380
381         return 0;
382 }
383
384 static void me4000_ai_reset(struct comedi_device *dev)
385 {
386         unsigned int ctrl;
387
388         /* Stop any running conversion */
389         ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG);
390         ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP;
391         outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
392
393         /* Clear the control register */
394         outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
395 }
396
397 static void me4000_reset(struct comedi_device *dev)
398 {
399         struct me4000_private *devpriv = dev->private;
400         unsigned int val;
401         int chan;
402
403         /* Disable interrupts on the PLX */
404         outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
405
406         /* Software reset the PLX */
407         val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
408         val |= PLX9052_CNTRL_PCI_RESET;
409         outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
410         val &= ~PLX9052_CNTRL_PCI_RESET;
411         outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
412
413         /* 0x8000 to the DACs means an output voltage of 0V */
414         for (chan = 0; chan < 4; chan++)
415                 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
416
417         me4000_ai_reset(dev);
418
419         /* Set both stop bits in the analog output control register */
420         val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP;
421         for (chan = 0; chan < 4; chan++)
422                 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
423
424         /* Set the adustment register for AO demux */
425         outl(ME4000_AO_DEMUX_ADJUST_VALUE,
426              dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
427
428         /*
429          * Set digital I/O direction for port 0
430          * to output on isolated versions
431          */
432         if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
433                 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
434 }
435
436 static unsigned int me4000_ai_get_sample(struct comedi_device *dev,
437                                          struct comedi_subdevice *s)
438 {
439         unsigned int val;
440
441         /* read two's complement value and munge to offset binary */
442         val = inl(dev->iobase + ME4000_AI_DATA_REG);
443         return comedi_offset_munge(s, val);
444 }
445
446 static int me4000_ai_eoc(struct comedi_device *dev,
447                          struct comedi_subdevice *s,
448                          struct comedi_insn *insn,
449                          unsigned long context)
450 {
451         unsigned int status;
452
453         status = inl(dev->iobase + ME4000_AI_STATUS_REG);
454         if (status & ME4000_AI_STATUS_EF_DATA)
455                 return 0;
456         return -EBUSY;
457 }
458
459 static int me4000_ai_insn_read(struct comedi_device *dev,
460                                struct comedi_subdevice *s,
461                                struct comedi_insn *insn,
462                                unsigned int *data)
463 {
464         unsigned int chan = CR_CHAN(insn->chanspec);
465         unsigned int range = CR_RANGE(insn->chanspec);
466         unsigned int aref = CR_AREF(insn->chanspec);
467         unsigned int entry;
468         int ret = 0;
469         int i;
470
471         entry = chan | ME4000_AI_LIST_RANGE(range);
472         if (aref == AREF_DIFF) {
473                 if (!(s->subdev_flags & SDF_DIFF)) {
474                         dev_err(dev->class_dev,
475                                 "Differential inputs are not available\n");
476                         return -EINVAL;
477                 }
478
479                 if (!comedi_range_is_bipolar(s, range)) {
480                         dev_err(dev->class_dev,
481                                 "Range must be bipolar when aref = diff\n");
482                         return -EINVAL;
483                 }
484
485                 if (chan >= (s->n_chan / 2)) {
486                         dev_err(dev->class_dev,
487                                 "Analog input is not available\n");
488                         return -EINVAL;
489                 }
490                 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
491         }
492
493         entry |= ME4000_AI_LIST_LAST_ENTRY;
494
495         /* Enable channel list and data fifo for single acquisition mode */
496         outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO,
497              dev->iobase + ME4000_AI_CTRL_REG);
498
499         /* Generate channel list entry */
500         outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
501
502         /* Set the timer to maximum sample rate */
503         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
504         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
505
506         for (i = 0; i < insn->n; i++) {
507                 unsigned int val;
508
509                 /* start conversion by dummy read */
510                 inl(dev->iobase + ME4000_AI_START_REG);
511
512                 ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0);
513                 if (ret)
514                         break;
515
516                 val = me4000_ai_get_sample(dev, s);
517                 data[i] = comedi_offset_munge(s, val);
518         }
519
520         me4000_ai_reset(dev);
521
522         return ret ? ret : insn->n;
523 }
524
525 static int me4000_ai_cancel(struct comedi_device *dev,
526                             struct comedi_subdevice *s)
527 {
528         me4000_ai_reset(dev);
529
530         return 0;
531 }
532
533 static int me4000_ai_check_chanlist(struct comedi_device *dev,
534                                     struct comedi_subdevice *s,
535                                     struct comedi_cmd *cmd)
536 {
537         unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
538         int i;
539
540         for (i = 0; i < cmd->chanlist_len; i++) {
541                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
542                 unsigned int range = CR_RANGE(cmd->chanlist[i]);
543                 unsigned int aref = CR_AREF(cmd->chanlist[i]);
544
545                 if (aref != aref0) {
546                         dev_dbg(dev->class_dev,
547                                 "Mode is not equal for all entries\n");
548                         return -EINVAL;
549                 }
550
551                 if (aref == AREF_DIFF) {
552                         if (!(s->subdev_flags & SDF_DIFF)) {
553                                 dev_err(dev->class_dev,
554                                         "Differential inputs are not available\n");
555                                 return -EINVAL;
556                         }
557
558                         if (chan >= (s->n_chan / 2)) {
559                                 dev_dbg(dev->class_dev,
560                                         "Channel number to high\n");
561                                 return -EINVAL;
562                         }
563
564                         if (!comedi_range_is_bipolar(s, range)) {
565                                 dev_dbg(dev->class_dev,
566                                         "Bipolar is not selected in differential mode\n");
567                                 return -EINVAL;
568                         }
569                 }
570         }
571
572         return 0;
573 }
574
575 static void me4000_ai_round_cmd_args(struct comedi_device *dev,
576                                      struct comedi_subdevice *s,
577                                      struct comedi_cmd *cmd)
578 {
579         struct me4000_private *devpriv = dev->private;
580         int rest;
581
582         devpriv->ai_init_ticks = 0;
583         devpriv->ai_scan_ticks = 0;
584         devpriv->ai_chan_ticks = 0;
585
586         if (cmd->start_arg) {
587                 devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000;
588                 rest = (cmd->start_arg * 33) % 1000;
589
590                 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
591                         if (rest > 33)
592                                 devpriv->ai_init_ticks++;
593                 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
594                         if (rest)
595                                 devpriv->ai_init_ticks++;
596                 }
597         }
598
599         if (cmd->scan_begin_arg) {
600                 devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
601                 rest = (cmd->scan_begin_arg * 33) % 1000;
602
603                 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
604                         if (rest > 33)
605                                 devpriv->ai_scan_ticks++;
606                 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
607                         if (rest)
608                                 devpriv->ai_scan_ticks++;
609                 }
610         }
611
612         if (cmd->convert_arg) {
613                 devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000;
614                 rest = (cmd->convert_arg * 33) % 1000;
615
616                 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
617                         if (rest > 33)
618                                 devpriv->ai_chan_ticks++;
619                 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
620                         if (rest)
621                                 devpriv->ai_chan_ticks++;
622                 }
623         }
624 }
625
626 static void me4000_ai_write_chanlist(struct comedi_device *dev,
627                                      struct comedi_subdevice *s,
628                                      struct comedi_cmd *cmd)
629 {
630         int i;
631
632         for (i = 0; i < cmd->chanlist_len; i++) {
633                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
634                 unsigned int range = CR_RANGE(cmd->chanlist[i]);
635                 unsigned int aref = CR_AREF(cmd->chanlist[i]);
636                 unsigned int entry;
637
638                 entry = chan | ME4000_AI_LIST_RANGE(range);
639
640                 if (aref == AREF_DIFF)
641                         entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
642
643                 if (i == (cmd->chanlist_len - 1))
644                         entry |= ME4000_AI_LIST_LAST_ENTRY;
645
646                 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
647         }
648 }
649
650 static int me4000_ai_do_cmd(struct comedi_device *dev,
651                             struct comedi_subdevice *s)
652 {
653         struct me4000_private *devpriv = dev->private;
654         struct comedi_cmd *cmd = &s->async->cmd;
655         unsigned int ctrl;
656
657         /* Write timer arguments */
658         outl(devpriv->ai_init_ticks - 1,
659              dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
660         outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
661
662         if (devpriv->ai_scan_ticks) {
663                 outl(devpriv->ai_scan_ticks - 1,
664                      dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
665                 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
666         }
667
668         outl(devpriv->ai_chan_ticks - 1,
669              dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
670         outl(devpriv->ai_chan_ticks - 1,
671              dev->iobase + ME4000_AI_CHAN_TIMER_REG);
672
673         /* Start sources */
674         ctrl = devpriv->ai_ctrl_mode |
675                ME4000_AI_CTRL_CHANNEL_FIFO |
676                ME4000_AI_CTRL_DATA_FIFO;
677
678         /* Stop triggers */
679         if (cmd->stop_src == TRIG_COUNT) {
680                 outl(cmd->chanlist_len * cmd->stop_arg,
681                      dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
682                 ctrl |= ME4000_AI_CTRL_SC_IRQ;
683         } else if (cmd->stop_src == TRIG_NONE &&
684                    cmd->scan_end_src == TRIG_COUNT) {
685                 outl(cmd->scan_end_arg,
686                      dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
687                 ctrl |= ME4000_AI_CTRL_SC_IRQ;
688         }
689         ctrl |= ME4000_AI_CTRL_HF_IRQ;
690
691         /* Write the setup to the control register */
692         outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
693
694         /* Write the channel list */
695         me4000_ai_write_chanlist(dev, s, cmd);
696
697         /* Start acquistion by dummy read */
698         inl(dev->iobase + ME4000_AI_START_REG);
699
700         return 0;
701 }
702
703 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
704                                  struct comedi_subdevice *s,
705                                  struct comedi_cmd *cmd)
706 {
707         struct me4000_private *devpriv = dev->private;
708         int err = 0;
709
710         /* Step 1 : check if triggers are trivially valid */
711
712         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
713         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
714                                         TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
715         err |= comedi_check_trigger_src(&cmd->convert_src,
716                                         TRIG_TIMER | TRIG_EXT);
717         err |= comedi_check_trigger_src(&cmd->scan_end_src,
718                                         TRIG_NONE | TRIG_COUNT);
719         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
720
721         if (err)
722                 return 1;
723
724         /* Step 2a : make sure trigger sources are unique */
725
726         err |= comedi_check_trigger_is_unique(cmd->start_src);
727         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
728         err |= comedi_check_trigger_is_unique(cmd->convert_src);
729         err |= comedi_check_trigger_is_unique(cmd->scan_end_src);
730         err |= comedi_check_trigger_is_unique(cmd->stop_src);
731
732         /* Step 2b : and mutually compatible */
733
734         if (cmd->start_src == TRIG_NOW &&
735             cmd->scan_begin_src == TRIG_TIMER &&
736             cmd->convert_src == TRIG_TIMER) {
737                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
738         } else if (cmd->start_src == TRIG_NOW &&
739                    cmd->scan_begin_src == TRIG_FOLLOW &&
740                    cmd->convert_src == TRIG_TIMER) {
741                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
742         } else if (cmd->start_src == TRIG_EXT &&
743                    cmd->scan_begin_src == TRIG_TIMER &&
744                    cmd->convert_src == TRIG_TIMER) {
745                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
746         } else if (cmd->start_src == TRIG_EXT &&
747                    cmd->scan_begin_src == TRIG_FOLLOW &&
748                    cmd->convert_src == TRIG_TIMER) {
749                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
750         } else if (cmd->start_src == TRIG_EXT &&
751                    cmd->scan_begin_src == TRIG_EXT &&
752                    cmd->convert_src == TRIG_TIMER) {
753                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2;
754         } else if (cmd->start_src == TRIG_EXT &&
755                    cmd->scan_begin_src == TRIG_EXT &&
756                    cmd->convert_src == TRIG_EXT) {
757                 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 |
758                                         ME4000_AI_CTRL_MODE_1;
759         } else {
760                 err |= -EINVAL;
761         }
762
763         if (err)
764                 return 2;
765
766         /* Step 3: check if arguments are trivially valid */
767
768         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
769
770         if (cmd->chanlist_len < 1) {
771                 cmd->chanlist_len = 1;
772                 err |= -EINVAL;
773         }
774
775         /* Round the timer arguments */
776         me4000_ai_round_cmd_args(dev, s, cmd);
777
778         if (devpriv->ai_init_ticks < 66) {
779                 cmd->start_arg = 2000;
780                 err |= -EINVAL;
781         }
782         if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) {
783                 cmd->scan_begin_arg = 2031;
784                 err |= -EINVAL;
785         }
786         if (devpriv->ai_chan_ticks < 66) {
787                 cmd->convert_arg = 2000;
788                 err |= -EINVAL;
789         }
790
791         if (cmd->stop_src == TRIG_COUNT)
792                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
793         else    /* TRIG_NONE */
794                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
795
796         if (err)
797                 return 3;
798
799         /*
800          * Stage 4. Check for argument conflicts.
801          */
802         if (cmd->start_src == TRIG_NOW &&
803             cmd->scan_begin_src == TRIG_TIMER &&
804             cmd->convert_src == TRIG_TIMER) {
805                 /* Check timer arguments */
806                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
807                         dev_err(dev->class_dev, "Invalid start arg\n");
808                         cmd->start_arg = 2000;  /*  66 ticks at least */
809                         err++;
810                 }
811                 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
812                         dev_err(dev->class_dev, "Invalid convert arg\n");
813                         cmd->convert_arg = 2000;        /*  66 ticks at least */
814                         err++;
815                 }
816                 if (devpriv->ai_scan_ticks <=
817                     cmd->chanlist_len * devpriv->ai_chan_ticks) {
818                         dev_err(dev->class_dev, "Invalid scan end arg\n");
819
820                         /*  At least one tick more */
821                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
822                         err++;
823                 }
824         } else if (cmd->start_src == TRIG_NOW &&
825                    cmd->scan_begin_src == TRIG_FOLLOW &&
826                    cmd->convert_src == TRIG_TIMER) {
827                 /* Check timer arguments */
828                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
829                         dev_err(dev->class_dev, "Invalid start arg\n");
830                         cmd->start_arg = 2000;  /*  66 ticks at least */
831                         err++;
832                 }
833                 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
834                         dev_err(dev->class_dev, "Invalid convert arg\n");
835                         cmd->convert_arg = 2000;        /*  66 ticks at least */
836                         err++;
837                 }
838         } else if (cmd->start_src == TRIG_EXT &&
839                    cmd->scan_begin_src == TRIG_TIMER &&
840                    cmd->convert_src == TRIG_TIMER) {
841                 /* Check timer arguments */
842                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
843                         dev_err(dev->class_dev, "Invalid start arg\n");
844                         cmd->start_arg = 2000;  /*  66 ticks at least */
845                         err++;
846                 }
847                 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
848                         dev_err(dev->class_dev, "Invalid convert arg\n");
849                         cmd->convert_arg = 2000;        /*  66 ticks at least */
850                         err++;
851                 }
852                 if (devpriv->ai_scan_ticks <=
853                     cmd->chanlist_len * devpriv->ai_chan_ticks) {
854                         dev_err(dev->class_dev, "Invalid scan end arg\n");
855
856                         /*  At least one tick more */
857                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
858                         err++;
859                 }
860         } else if (cmd->start_src == TRIG_EXT &&
861                    cmd->scan_begin_src == TRIG_FOLLOW &&
862                    cmd->convert_src == TRIG_TIMER) {
863                 /* Check timer arguments */
864                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
865                         dev_err(dev->class_dev, "Invalid start arg\n");
866                         cmd->start_arg = 2000;  /*  66 ticks at least */
867                         err++;
868                 }
869                 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
870                         dev_err(dev->class_dev, "Invalid convert arg\n");
871                         cmd->convert_arg = 2000;        /*  66 ticks at least */
872                         err++;
873                 }
874         } else if (cmd->start_src == TRIG_EXT &&
875                    cmd->scan_begin_src == TRIG_EXT &&
876                    cmd->convert_src == TRIG_TIMER) {
877                 /* Check timer arguments */
878                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
879                         dev_err(dev->class_dev, "Invalid start arg\n");
880                         cmd->start_arg = 2000;  /*  66 ticks at least */
881                         err++;
882                 }
883                 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
884                         dev_err(dev->class_dev, "Invalid convert arg\n");
885                         cmd->convert_arg = 2000;        /*  66 ticks at least */
886                         err++;
887                 }
888         } else if (cmd->start_src == TRIG_EXT &&
889                    cmd->scan_begin_src == TRIG_EXT &&
890                    cmd->convert_src == TRIG_EXT) {
891                 /* Check timer arguments */
892                 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
893                         dev_err(dev->class_dev, "Invalid start arg\n");
894                         cmd->start_arg = 2000;  /*  66 ticks at least */
895                         err++;
896                 }
897         }
898         if (cmd->scan_end_src == TRIG_COUNT) {
899                 if (cmd->scan_end_arg == 0) {
900                         dev_err(dev->class_dev, "Invalid scan end arg\n");
901                         cmd->scan_end_arg = 1;
902                         err++;
903                 }
904         }
905
906         if (err)
907                 return 4;
908
909         /* Step 5: check channel list if it exists */
910         if (cmd->chanlist && cmd->chanlist_len > 0)
911                 err |= me4000_ai_check_chanlist(dev, s, cmd);
912
913         if (err)
914                 return 5;
915
916         return 0;
917 }
918
919 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
920 {
921         unsigned int tmp;
922         struct comedi_device *dev = dev_id;
923         struct comedi_subdevice *s = dev->read_subdev;
924         int i;
925         int c = 0;
926         unsigned short lval;
927
928         if (!dev->attached)
929                 return IRQ_NONE;
930
931         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
932             ME4000_IRQ_STATUS_AI_HF) {
933                 /* Read status register to find out what happened */
934                 tmp = inl(dev->iobase + ME4000_AI_STATUS_REG);
935
936                 if (!(tmp & ME4000_AI_STATUS_FF_DATA) &&
937                     !(tmp & ME4000_AI_STATUS_HF_DATA) &&
938                     (tmp & ME4000_AI_STATUS_EF_DATA)) {
939                         dev_err(dev->class_dev, "FIFO overflow\n");
940                         s->async->events |= COMEDI_CB_ERROR;
941                         c = ME4000_AI_FIFO_COUNT;
942                 } else if ((tmp & ME4000_AI_STATUS_FF_DATA) &&
943                            !(tmp & ME4000_AI_STATUS_HF_DATA) &&
944                            (tmp & ME4000_AI_STATUS_EF_DATA)) {
945                         c = ME4000_AI_FIFO_COUNT / 2;
946                 } else {
947                         dev_err(dev->class_dev, "Undefined FIFO state\n");
948                         s->async->events |= COMEDI_CB_ERROR;
949                         c = 0;
950                 }
951
952                 for (i = 0; i < c; i++) {
953                         lval = me4000_ai_get_sample(dev, s);
954                         if (!comedi_buf_write_samples(s, &lval, 1))
955                                 break;
956                 }
957
958                 /* Work is done, so reset the interrupt */
959                 tmp |= ME4000_AI_CTRL_HF_IRQ_RESET;
960                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
961                 tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET;
962                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
963         }
964
965         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
966             ME4000_IRQ_STATUS_SC) {
967                 /* Acquisition is complete */
968                 s->async->events |= COMEDI_CB_EOA;
969
970                 /* Poll data until fifo empty */
971                 while (inl(dev->iobase + ME4000_AI_STATUS_REG) &
972                        ME4000_AI_STATUS_EF_DATA) {
973                         lval = me4000_ai_get_sample(dev, s);
974                         if (!comedi_buf_write_samples(s, &lval, 1))
975                                 break;
976                 }
977
978                 /* Work is done, so reset the interrupt */
979                 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
980                 tmp |= ME4000_AI_CTRL_SC_IRQ_RESET;
981                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
982                 tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET;
983                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
984         }
985
986         comedi_handle_events(dev, s);
987
988         return IRQ_HANDLED;
989 }
990
991 static int me4000_ao_insn_write(struct comedi_device *dev,
992                                 struct comedi_subdevice *s,
993                                 struct comedi_insn *insn,
994                                 unsigned int *data)
995 {
996         unsigned int chan = CR_CHAN(insn->chanspec);
997         unsigned int tmp;
998
999         /* Stop any running conversion */
1000         tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1001         tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP;
1002         outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1003
1004         /* Clear control register and set to single mode */
1005         outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1006
1007         /* Write data value */
1008         outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1009
1010         /* Store in the mirror */
1011         s->readback[chan] = data[0];
1012
1013         return 1;
1014 }
1015
1016 static int me4000_dio_insn_bits(struct comedi_device *dev,
1017                                 struct comedi_subdevice *s,
1018                                 struct comedi_insn *insn,
1019                                 unsigned int *data)
1020 {
1021         if (comedi_dio_update_state(s, data)) {
1022                 outl((s->state >> 0) & 0xFF,
1023                      dev->iobase + ME4000_DIO_PORT_0_REG);
1024                 outl((s->state >> 8) & 0xFF,
1025                      dev->iobase + ME4000_DIO_PORT_1_REG);
1026                 outl((s->state >> 16) & 0xFF,
1027                      dev->iobase + ME4000_DIO_PORT_2_REG);
1028                 outl((s->state >> 24) & 0xFF,
1029                      dev->iobase + ME4000_DIO_PORT_3_REG);
1030         }
1031
1032         data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1033                   ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1034                   ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1035                   ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1036
1037         return insn->n;
1038 }
1039
1040 static int me4000_dio_insn_config(struct comedi_device *dev,
1041                                   struct comedi_subdevice *s,
1042                                   struct comedi_insn *insn,
1043                                   unsigned int *data)
1044 {
1045         unsigned int chan = CR_CHAN(insn->chanspec);
1046         unsigned int mask;
1047         unsigned int tmp;
1048         int ret;
1049
1050         if (chan < 8)
1051                 mask = 0x000000ff;
1052         else if (chan < 16)
1053                 mask = 0x0000ff00;
1054         else if (chan < 24)
1055                 mask = 0x00ff0000;
1056         else
1057                 mask = 0xff000000;
1058
1059         ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1060         if (ret)
1061                 return ret;
1062
1063         tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1064         tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 |
1065                  ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 |
1066                  ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 |
1067                  ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7);
1068         if (s->io_bits & 0x000000ff)
1069                 tmp |= ME4000_DIO_CTRL_MODE_0;
1070         if (s->io_bits & 0x0000ff00)
1071                 tmp |= ME4000_DIO_CTRL_MODE_2;
1072         if (s->io_bits & 0x00ff0000)
1073                 tmp |= ME4000_DIO_CTRL_MODE_4;
1074         if (s->io_bits & 0xff000000)
1075                 tmp |= ME4000_DIO_CTRL_MODE_6;
1076
1077         /*
1078          * Check for optoisolated ME-4000 version.
1079          * If one the first port is a fixed output
1080          * port and the second is a fixed input port.
1081          */
1082         if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1083                 s->io_bits |= 0x000000ff;
1084                 s->io_bits &= ~0x0000ff00;
1085                 tmp |= ME4000_DIO_CTRL_MODE_0;
1086                 tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3);
1087         }
1088
1089         outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1090
1091         return insn->n;
1092 }
1093
1094 static int me4000_auto_attach(struct comedi_device *dev,
1095                               unsigned long context)
1096 {
1097         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1098         const struct me4000_board *board = NULL;
1099         struct me4000_private *devpriv;
1100         struct comedi_subdevice *s;
1101         int result;
1102
1103         if (context < ARRAY_SIZE(me4000_boards))
1104                 board = &me4000_boards[context];
1105         if (!board)
1106                 return -ENODEV;
1107         dev->board_ptr = board;
1108         dev->board_name = board->name;
1109
1110         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1111         if (!devpriv)
1112                 return -ENOMEM;
1113
1114         result = comedi_pci_enable(dev);
1115         if (result)
1116                 return result;
1117
1118         devpriv->plx_regbase = pci_resource_start(pcidev, 1);
1119         dev->iobase = pci_resource_start(pcidev, 2);
1120         if (!devpriv->plx_regbase || !dev->iobase)
1121                 return -ENODEV;
1122
1123         result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
1124                                       me4000_xilinx_download, 0);
1125         if (result < 0)
1126                 return result;
1127
1128         me4000_reset(dev);
1129
1130         if (pcidev->irq > 0) {
1131                 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1132                                      dev->board_name, dev);
1133                 if (result == 0) {
1134                         dev->irq = pcidev->irq;
1135
1136                         /* Enable interrupts on the PLX */
1137                         outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL |
1138                              PLX9052_INTCSR_PCIENAB,
1139                              devpriv->plx_regbase + PLX9052_INTCSR);
1140                 }
1141         }
1142
1143         result = comedi_alloc_subdevices(dev, 4);
1144         if (result)
1145                 return result;
1146
1147         /* Analog Input subdevice */
1148         s = &dev->subdevices[0];
1149         s->type         = COMEDI_SUBD_AI;
1150         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
1151         if (board->can_do_diff_ai)
1152                 s->subdev_flags |= SDF_DIFF;
1153         s->n_chan       = board->ai_nchan;
1154         s->maxdata      = 0xffff;
1155         s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1156         s->range_table  = &me4000_ai_range;
1157         s->insn_read    = me4000_ai_insn_read;
1158
1159         if (dev->irq) {
1160                 dev->read_subdev = s;
1161                 s->subdev_flags |= SDF_CMD_READ;
1162                 s->cancel       = me4000_ai_cancel;
1163                 s->do_cmdtest   = me4000_ai_do_cmd_test;
1164                 s->do_cmd       = me4000_ai_do_cmd;
1165         }
1166
1167         /* Analog Output subdevice */
1168         s = &dev->subdevices[1];
1169         if (board->has_ao) {
1170                 s->type         = COMEDI_SUBD_AO;
1171                 s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND;
1172                 s->n_chan       = 4;
1173                 s->maxdata      = 0xffff;
1174                 s->range_table  = &range_bipolar10;
1175                 s->insn_write   = me4000_ao_insn_write;
1176
1177                 result = comedi_alloc_subdev_readback(s);
1178                 if (result)
1179                         return result;
1180         } else {
1181                 s->type         = COMEDI_SUBD_UNUSED;
1182         }
1183
1184         /* Digital I/O subdevice */
1185         s = &dev->subdevices[2];
1186         s->type         = COMEDI_SUBD_DIO;
1187         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1188         s->n_chan       = 32;
1189         s->maxdata      = 1;
1190         s->range_table  = &range_digital;
1191         s->insn_bits    = me4000_dio_insn_bits;
1192         s->insn_config  = me4000_dio_insn_config;
1193
1194         /*
1195          * Check for optoisolated ME-4000 version. If one the first
1196          * port is a fixed output port and the second is a fixed input port.
1197          */
1198         if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1199                 s->io_bits |= 0xFF;
1200                 outl(ME4000_DIO_CTRL_MODE_0,
1201                      dev->iobase + ME4000_DIO_DIR_REG);
1202         }
1203
1204         /* Counter subdevice (8254) */
1205         s = &dev->subdevices[3];
1206         if (board->has_counter) {
1207                 unsigned long timer_base = pci_resource_start(pcidev, 3);
1208
1209                 if (!timer_base)
1210                         return -ENODEV;
1211
1212                 dev->pacer = comedi_8254_io_alloc(timer_base, 0, I8254_IO8, 0);
1213                 if (IS_ERR(dev->pacer))
1214                         return PTR_ERR(dev->pacer);
1215
1216                 comedi_8254_subdevice_init(s, dev->pacer);
1217         } else {
1218                 s->type = COMEDI_SUBD_UNUSED;
1219         }
1220
1221         return 0;
1222 }
1223
1224 static void me4000_detach(struct comedi_device *dev)
1225 {
1226         if (dev->irq) {
1227                 struct me4000_private *devpriv = dev->private;
1228
1229                 /* Disable interrupts on the PLX */
1230                 outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
1231         }
1232         comedi_pci_detach(dev);
1233 }
1234
1235 static struct comedi_driver me4000_driver = {
1236         .driver_name    = "me4000",
1237         .module         = THIS_MODULE,
1238         .auto_attach    = me4000_auto_attach,
1239         .detach         = me4000_detach,
1240 };
1241
1242 static int me4000_pci_probe(struct pci_dev *dev,
1243                             const struct pci_device_id *id)
1244 {
1245         return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1246 }
1247
1248 static const struct pci_device_id me4000_pci_table[] = {
1249         { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1250         { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1251         { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1252         { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1253         { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1254         { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1255         { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1256         { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1257         { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1258         { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1259         { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1260         { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1261         { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1262         { 0 }
1263 };
1264 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1265
1266 static struct pci_driver me4000_pci_driver = {
1267         .name           = "me4000",
1268         .id_table       = me4000_pci_table,
1269         .probe          = me4000_pci_probe,
1270         .remove         = comedi_pci_auto_unconfig,
1271 };
1272 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1273
1274 MODULE_AUTHOR("Comedi https://www.comedi.org");
1275 MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards");
1276 MODULE_LICENSE("GPL");
1277 /*(DEBLOBBED)*/