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