Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/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/pci.h>
 45 #include <linux/delay.h>
 46 #include <linux/interrupt.h>
 47 #include <linux/list.h>
 48 #include <linux/spinlock.h>
 49 
 50 #include "../comedidev.h"
 51 
 52 #include "comedi_fc.h"
 53 #include "8253.h"
 54 #include "plx9052.h"
 55 
 56 #if 0
 57 /* file removed due to GPL incompatibility */
 58 #include "me4000_fw.h"
 59 #endif
 60 
 61 /*
 62  * ME4000 Register map and bit defines
 63  */
 64 #define ME4000_AO_CHAN(x)                       ((x) * 0x18)
 65 
 66 #define ME4000_AO_CTRL_REG(x)                   (0x00 + ME4000_AO_CHAN(x))
 67 #define ME4000_AO_CTRL_BIT_MODE_0               (1 << 0)
 68 #define ME4000_AO_CTRL_BIT_MODE_1               (1 << 1)
 69 #define ME4000_AO_CTRL_MASK_MODE                (3 << 0)
 70 #define ME4000_AO_CTRL_BIT_STOP                 (1 << 2)
 71 #define ME4000_AO_CTRL_BIT_ENABLE_FIFO          (1 << 3)
 72 #define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG       (1 << 4)
 73 #define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE         (1 << 5)
 74 #define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP       (1 << 7)
 75 #define ME4000_AO_CTRL_BIT_ENABLE_DO            (1 << 8)
 76 #define ME4000_AO_CTRL_BIT_ENABLE_IRQ           (1 << 9)
 77 #define ME4000_AO_CTRL_BIT_RESET_IRQ            (1 << 10)
 78 #define ME4000_AO_STATUS_REG(x)                 (0x04 + ME4000_AO_CHAN(x))
 79 #define ME4000_AO_STATUS_BIT_FSM                (1 << 0)
 80 #define ME4000_AO_STATUS_BIT_FF                 (1 << 1)
 81 #define ME4000_AO_STATUS_BIT_HF                 (1 << 2)
 82 #define ME4000_AO_STATUS_BIT_EF                 (1 << 3)
 83 #define ME4000_AO_FIFO_REG(x)                   (0x08 + ME4000_AO_CHAN(x))
 84 #define ME4000_AO_SINGLE_REG(x)                 (0x0c + ME4000_AO_CHAN(x))
 85 #define ME4000_AO_TIMER_REG(x)                  (0x10 + ME4000_AO_CHAN(x))
 86 #define ME4000_AI_CTRL_REG                      0x74
 87 #define ME4000_AI_STATUS_REG                    0x74
 88 #define ME4000_AI_CTRL_BIT_MODE_0               (1 << 0)
 89 #define ME4000_AI_CTRL_BIT_MODE_1               (1 << 1)
 90 #define ME4000_AI_CTRL_BIT_MODE_2               (1 << 2)
 91 #define ME4000_AI_CTRL_BIT_SAMPLE_HOLD          (1 << 3)
 92 #define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP       (1 << 4)
 93 #define ME4000_AI_CTRL_BIT_STOP                 (1 << 5)
 94 #define ME4000_AI_CTRL_BIT_CHANNEL_FIFO         (1 << 6)
 95 #define ME4000_AI_CTRL_BIT_DATA_FIFO            (1 << 7)
 96 #define ME4000_AI_CTRL_BIT_FULLSCALE            (1 << 8)
 97 #define ME4000_AI_CTRL_BIT_OFFSET               (1 << 9)
 98 #define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG       (1 << 10)
 99 #define ME4000_AI_CTRL_BIT_EX_TRIG              (1 << 11)
100 #define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING      (1 << 12)
101 #define ME4000_AI_CTRL_BIT_EX_IRQ               (1 << 13)
102 #define ME4000_AI_CTRL_BIT_EX_IRQ_RESET         (1 << 14)
103 #define ME4000_AI_CTRL_BIT_LE_IRQ               (1 << 15)
104 #define ME4000_AI_CTRL_BIT_LE_IRQ_RESET         (1 << 16)
105 #define ME4000_AI_CTRL_BIT_HF_IRQ               (1 << 17)
106 #define ME4000_AI_CTRL_BIT_HF_IRQ_RESET         (1 << 18)
107 #define ME4000_AI_CTRL_BIT_SC_IRQ               (1 << 19)
108 #define ME4000_AI_CTRL_BIT_SC_IRQ_RESET         (1 << 20)
109 #define ME4000_AI_CTRL_BIT_SC_RELOAD            (1 << 21)
110 #define ME4000_AI_STATUS_BIT_EF_CHANNEL         (1 << 22)
111 #define ME4000_AI_STATUS_BIT_HF_CHANNEL         (1 << 23)
112 #define ME4000_AI_STATUS_BIT_FF_CHANNEL         (1 << 24)
113 #define ME4000_AI_STATUS_BIT_EF_DATA            (1 << 25)
114 #define ME4000_AI_STATUS_BIT_HF_DATA            (1 << 26)
115 #define ME4000_AI_STATUS_BIT_FF_DATA            (1 << 27)
116 #define ME4000_AI_STATUS_BIT_LE                 (1 << 28)
117 #define ME4000_AI_STATUS_BIT_FSM                (1 << 29)
118 #define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH         (1 << 31)
119 #define ME4000_AI_CHANNEL_LIST_REG              0x78
120 #define ME4000_AI_LIST_INPUT_SINGLE_ENDED       (0 << 5)
121 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL       (1 << 5)
122 #define ME4000_AI_LIST_RANGE_BIPOLAR_10         (0 << 6)
123 #define ME4000_AI_LIST_RANGE_BIPOLAR_2_5        (1 << 6)
124 #define ME4000_AI_LIST_RANGE_UNIPOLAR_10        (2 << 6)
125 #define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5       (3 << 6)
126 #define ME4000_AI_LIST_LAST_ENTRY               (1 << 8)
127 #define ME4000_AI_DATA_REG                      0x7c
128 #define ME4000_AI_CHAN_TIMER_REG                0x80
129 #define ME4000_AI_CHAN_PRE_TIMER_REG            0x84
130 #define ME4000_AI_SCAN_TIMER_LOW_REG            0x88
131 #define ME4000_AI_SCAN_TIMER_HIGH_REG           0x8c
132 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG        0x90
133 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG       0x94
134 #define ME4000_AI_START_REG                     0x98
135 #define ME4000_IRQ_STATUS_REG                   0x9c
136 #define ME4000_IRQ_STATUS_BIT_EX                (1 << 0)
137 #define ME4000_IRQ_STATUS_BIT_LE                (1 << 1)
138 #define ME4000_IRQ_STATUS_BIT_AI_HF             (1 << 2)
139 #define ME4000_IRQ_STATUS_BIT_AO_0_HF           (1 << 3)
140 #define ME4000_IRQ_STATUS_BIT_AO_1_HF           (1 << 4)
141 #define ME4000_IRQ_STATUS_BIT_AO_2_HF           (1 << 5)
142 #define ME4000_IRQ_STATUS_BIT_AO_3_HF           (1 << 6)
143 #define ME4000_IRQ_STATUS_BIT_SC                (1 << 7)
144 #define ME4000_DIO_PORT_0_REG                   0xa0
145 #define ME4000_DIO_PORT_1_REG                   0xa4
146 #define ME4000_DIO_PORT_2_REG                   0xa8
147 #define ME4000_DIO_PORT_3_REG                   0xac
148 #define ME4000_DIO_DIR_REG                      0xb0
149 #define ME4000_AO_LOADSETREG_XX                 0xb4
150 #define ME4000_DIO_CTRL_REG                     0xb8
151 #define ME4000_DIO_CTRL_BIT_MODE_0              (1 << 0)
152 #define ME4000_DIO_CTRL_BIT_MODE_1              (1 << 1)
153 #define ME4000_DIO_CTRL_BIT_MODE_2              (1 << 2)
154 #define ME4000_DIO_CTRL_BIT_MODE_3              (1 << 3)
155 #define ME4000_DIO_CTRL_BIT_MODE_4              (1 << 4)
156 #define ME4000_DIO_CTRL_BIT_MODE_5              (1 << 5)
157 #define ME4000_DIO_CTRL_BIT_MODE_6              (1 << 6)
158 #define ME4000_DIO_CTRL_BIT_MODE_7              (1 << 7)
159 #define ME4000_DIO_CTRL_BIT_FUNCTION_0          (1 << 8)
160 #define ME4000_DIO_CTRL_BIT_FUNCTION_1          (1 << 9)
161 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0         (1 << 10)
162 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1         (1 << 11)
163 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2         (1 << 12)
164 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3         (1 << 13)
165 #define ME4000_AO_DEMUX_ADJUST_REG              0xbc
166 #define ME4000_AO_DEMUX_ADJUST_VALUE            0x4c
167 #define ME4000_AI_SAMPLE_COUNTER_REG            0xc0
168 
169 #define ME4000_AI_FIFO_COUNT                    2048
170 
171 #define ME4000_AI_MIN_TICKS                     66
172 #define ME4000_AI_MIN_SAMPLE_TIME               2000
173 #define ME4000_AI_BASE_FREQUENCY                (unsigned int) 33E6
174 
175 #define ME4000_AI_CHANNEL_LIST_COUNT            1024
176 
177 struct me4000_info {
178         unsigned long plx_regbase;
179         unsigned long timer_regbase;
180 
181         unsigned int ao_readback[4];
182 };
183 
184 enum me4000_boardid {
185         BOARD_ME4650,
186         BOARD_ME4660,
187         BOARD_ME4660I,
188         BOARD_ME4660S,
189         BOARD_ME4660IS,
190         BOARD_ME4670,
191         BOARD_ME4670I,
192         BOARD_ME4670S,
193         BOARD_ME4670IS,
194         BOARD_ME4680,
195         BOARD_ME4680I,
196         BOARD_ME4680S,
197         BOARD_ME4680IS,
198 };
199 
200 struct me4000_board {
201         const char *name;
202         int ao_nchan;
203         int ao_fifo;
204         int ai_nchan;
205         int ai_diff_nchan;
206         int ai_sh_nchan;
207         int ex_trig_analog;
208         int dio_nchan;
209         int has_counter;
210 };
211 
212 static const struct me4000_board me4000_boards[] = {
213         [BOARD_ME4650] = {
214                 .name           = "ME-4650",
215                 .ai_nchan       = 16,
216                 .dio_nchan      = 32,
217         },
218         [BOARD_ME4660] = {
219                 .name           = "ME-4660",
220                 .ai_nchan       = 32,
221                 .ai_diff_nchan  = 16,
222                 .dio_nchan      = 32,
223                 .has_counter    = 1,
224         },
225         [BOARD_ME4660I] = {
226                 .name           = "ME-4660i",
227                 .ai_nchan       = 32,
228                 .ai_diff_nchan  = 16,
229                 .dio_nchan      = 32,
230                 .has_counter    = 1,
231         },
232         [BOARD_ME4660S] = {
233                 .name           = "ME-4660s",
234                 .ai_nchan       = 32,
235                 .ai_diff_nchan  = 16,
236                 .ai_sh_nchan    = 8,
237                 .dio_nchan      = 32,
238                 .has_counter    = 1,
239         },
240         [BOARD_ME4660IS] = {
241                 .name           = "ME-4660is",
242                 .ai_nchan       = 32,
243                 .ai_diff_nchan  = 16,
244                 .ai_sh_nchan    = 8,
245                 .dio_nchan      = 32,
246                 .has_counter    = 1,
247         },
248         [BOARD_ME4670] = {
249                 .name           = "ME-4670",
250                 .ao_nchan       = 4,
251                 .ai_nchan       = 32,
252                 .ai_diff_nchan  = 16,
253                 .ex_trig_analog = 1,
254                 .dio_nchan      = 32,
255                 .has_counter    = 1,
256         },
257         [BOARD_ME4670I] = {
258                 .name           = "ME-4670i",
259                 .ao_nchan       = 4,
260                 .ai_nchan       = 32,
261                 .ai_diff_nchan  = 16,
262                 .ex_trig_analog = 1,
263                 .dio_nchan      = 32,
264                 .has_counter    = 1,
265         },
266         [BOARD_ME4670S] = {
267                 .name           = "ME-4670s",
268                 .ao_nchan       = 4,
269                 .ai_nchan       = 32,
270                 .ai_diff_nchan  = 16,
271                 .ai_sh_nchan    = 8,
272                 .ex_trig_analog = 1,
273                 .dio_nchan      = 32,
274                 .has_counter    = 1,
275         },
276         [BOARD_ME4670IS] = {
277                 .name           = "ME-4670is",
278                 .ao_nchan       = 4,
279                 .ai_nchan       = 32,
280                 .ai_diff_nchan  = 16,
281                 .ai_sh_nchan    = 8,
282                 .ex_trig_analog = 1,
283                 .dio_nchan      = 32,
284                 .has_counter    = 1,
285         },
286         [BOARD_ME4680] = {
287                 .name           = "ME-4680",
288                 .ao_nchan       = 4,
289                 .ao_fifo        = 4,
290                 .ai_nchan       = 32,
291                 .ai_diff_nchan  = 16,
292                 .ex_trig_analog = 1,
293                 .dio_nchan      = 32,
294                 .has_counter    = 1,
295         },
296         [BOARD_ME4680I] = {
297                 .name           = "ME-4680i",
298                 .ao_nchan       = 4,
299                 .ao_fifo        = 4,
300                 .ai_nchan       = 32,
301                 .ai_diff_nchan  = 16,
302                 .ex_trig_analog = 1,
303                 .dio_nchan      = 32,
304                 .has_counter    = 1,
305         },
306         [BOARD_ME4680S] = {
307                 .name           = "ME-4680s",
308                 .ao_nchan       = 4,
309                 .ao_fifo        = 4,
310                 .ai_nchan       = 32,
311                 .ai_diff_nchan  = 16,
312                 .ai_sh_nchan    = 8,
313                 .ex_trig_analog = 1,
314                 .dio_nchan      = 32,
315                 .has_counter    = 1,
316         },
317         [BOARD_ME4680IS] = {
318                 .name           = "ME-4680is",
319                 .ao_nchan       = 4,
320                 .ao_fifo        = 4,
321                 .ai_nchan       = 32,
322                 .ai_diff_nchan  = 16,
323                 .ai_sh_nchan    = 8,
324                 .ex_trig_analog = 1,
325                 .dio_nchan      = 32,
326                 .has_counter    = 1,
327         },
328 };
329 
330 static const struct comedi_lrange me4000_ai_range = {
331         4, {
332                 UNI_RANGE(2.5),
333                 UNI_RANGE(10),
334                 BIP_RANGE(2.5),
335                 BIP_RANGE(10)
336         }
337 };
338 
339 #define FIRMWARE_NOT_AVAILABLE 1
340 #if FIRMWARE_NOT_AVAILABLE
341 extern unsigned char *xilinx_firm;
342 #endif
343 
344 static int xilinx_download(struct comedi_device *dev)
345 {
346         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
347         struct me4000_info *info = dev->private;
348         unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
349         u32 value = 0;
350         wait_queue_head_t queue;
351         int idx = 0;
352         int size = 0;
353         unsigned int intcsr;
354 
355         if (!xilinx_iobase)
356                 return -ENODEV;
357 
358         init_waitqueue_head(&queue);
359 
360         /*
361          * Set PLX local interrupt 2 polarity to high.
362          * Interrupt is thrown by init pin of xilinx.
363          */
364         outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
365 
366         /* Set /CS and /WRITE of the Xilinx */
367         value = inl(info->plx_regbase + PLX9052_CNTRL);
368         value |= PLX9052_CNTRL_UIO2_DATA;
369         outl(value, info->plx_regbase + PLX9052_CNTRL);
370 
371         /* Init Xilinx with CS1 */
372         inb(xilinx_iobase + 0xC8);
373 
374         /* Wait until /INIT pin is set */
375         udelay(20);
376         intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
377         if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
378                 dev_err(dev->class_dev, "Can't init Xilinx\n");
379                 return -EIO;
380         }
381 
382         /* Reset /CS and /WRITE of the Xilinx */
383         value = inl(info->plx_regbase + PLX9052_CNTRL);
384         value &= ~PLX9052_CNTRL_UIO2_DATA;
385         outl(value, info->plx_regbase + PLX9052_CNTRL);
386         if (FIRMWARE_NOT_AVAILABLE) {
387                 dev_err(dev->class_dev,
388                         "xilinx firmware unavailable due to licensing, aborting");
389                 return -EIO;
390         } else {
391                 /* Download Xilinx firmware */
392                 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
393                     (xilinx_firm[2] << 8) + xilinx_firm[3];
394                 udelay(10);
395 
396                 for (idx = 0; idx < size; idx++) {
397                         outb(xilinx_firm[16 + idx], xilinx_iobase);
398                         udelay(10);
399 
400                         /* Check if BUSY flag is low */
401                         if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
402                                 dev_err(dev->class_dev,
403                                         "Xilinx is still busy (idx = %d)\n",
404                                         idx);
405                                 return -EIO;
406                         }
407                 }
408         }
409 
410         /* If done flag is high download was successful */
411         if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
412         } else {
413                 dev_err(dev->class_dev, "DONE flag is not set\n");
414                 dev_err(dev->class_dev, "Download not successful\n");
415                 return -EIO;
416         }
417 
418         /* Set /CS and /WRITE */
419         value = inl(info->plx_regbase + PLX9052_CNTRL);
420         value |= PLX9052_CNTRL_UIO2_DATA;
421         outl(value, info->plx_regbase + PLX9052_CNTRL);
422 
423         return 0;
424 }
425 
426 static void me4000_reset(struct comedi_device *dev)
427 {
428         struct me4000_info *info = dev->private;
429         unsigned int val;
430         int chan;
431 
432         /* Make a hardware reset */
433         val = inl(info->plx_regbase + PLX9052_CNTRL);
434         val |= PLX9052_CNTRL_PCI_RESET;
435         outl(val, info->plx_regbase + PLX9052_CNTRL);
436         val &= ~PLX9052_CNTRL_PCI_RESET;
437         outl(val , info->plx_regbase + PLX9052_CNTRL);
438 
439         /* 0x8000 to the DACs means an output voltage of 0V */
440         for (chan = 0; chan < 4; chan++)
441                 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
442 
443         /* Set both stop bits in the analog input control register */
444         outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
445                 dev->iobase + ME4000_AI_CTRL_REG);
446 
447         /* Set both stop bits in the analog output control register */
448         val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
449         for (chan = 0; chan < 4; chan++)
450                 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
451 
452         /* Enable interrupts on the PLX */
453         outl(PLX9052_INTCSR_LI1ENAB |
454              PLX9052_INTCSR_LI1POL |
455              PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
456 
457         /* Set the adustment register for AO demux */
458         outl(ME4000_AO_DEMUX_ADJUST_VALUE,
459                     dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
460 
461         /*
462          * Set digital I/O direction for port 0
463          * to output on isolated versions
464          */
465         if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
466                 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
467 }
468 
469 /*=============================================================================
470   Analog input section
471   ===========================================================================*/
472 
473 static int me4000_ai_insn_read(struct comedi_device *dev,
474                                struct comedi_subdevice *subdevice,
475                                struct comedi_insn *insn, unsigned int *data)
476 {
477         const struct me4000_board *thisboard = comedi_board(dev);
478         int chan = CR_CHAN(insn->chanspec);
479         int rang = CR_RANGE(insn->chanspec);
480         int aref = CR_AREF(insn->chanspec);
481 
482         unsigned int entry = 0;
483         unsigned int tmp;
484         unsigned int lval;
485 
486         if (insn->n == 0) {
487                 return 0;
488         } else if (insn->n > 1) {
489                 dev_err(dev->class_dev, "Invalid instruction length %d\n",
490                         insn->n);
491                 return -EINVAL;
492         }
493 
494         switch (rang) {
495         case 0:
496                 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
497                 break;
498         case 1:
499                 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
500                 break;
501         case 2:
502                 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
503                 break;
504         case 3:
505                 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
506                 break;
507         default:
508                 dev_err(dev->class_dev, "Invalid range specified\n");
509                 return -EINVAL;
510         }
511 
512         switch (aref) {
513         case AREF_GROUND:
514         case AREF_COMMON:
515                 if (chan >= thisboard->ai_nchan) {
516                         dev_err(dev->class_dev,
517                                 "Analog input is not available\n");
518                         return -EINVAL;
519                 }
520                 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
521                 break;
522 
523         case AREF_DIFF:
524                 if (rang == 0 || rang == 1) {
525                         dev_err(dev->class_dev,
526                                 "Range must be bipolar when aref = diff\n");
527                         return -EINVAL;
528                 }
529 
530                 if (chan >= thisboard->ai_diff_nchan) {
531                         dev_err(dev->class_dev,
532                                 "Analog input is not available\n");
533                         return -EINVAL;
534                 }
535                 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
536                 break;
537         default:
538                 dev_err(dev->class_dev, "Invalid aref specified\n");
539                 return -EINVAL;
540         }
541 
542         entry |= ME4000_AI_LIST_LAST_ENTRY;
543 
544         /* Clear channel list, data fifo and both stop bits */
545         tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
546         tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
547                  ME4000_AI_CTRL_BIT_DATA_FIFO |
548                  ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
549         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
550 
551         /* Set the acquisition mode to single */
552         tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
553                  ME4000_AI_CTRL_BIT_MODE_2);
554         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
555 
556         /* Enable channel list and data fifo */
557         tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
558         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
559 
560         /* Generate channel list entry */
561         outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
562 
563         /* Set the timer to maximum sample rate */
564         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
565         outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
566 
567         /* Start conversion by dummy read */
568         inl(dev->iobase + ME4000_AI_START_REG);
569 
570         /* Wait until ready */
571         udelay(10);
572         if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
573              ME4000_AI_STATUS_BIT_EF_DATA)) {
574                 dev_err(dev->class_dev, "Value not available after wait\n");
575                 return -EIO;
576         }
577 
578         /* Read value from data fifo */
579         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
580         data[0] = lval ^ 0x8000;
581 
582         return 1;
583 }
584 
585 static int me4000_ai_cancel(struct comedi_device *dev,
586                             struct comedi_subdevice *s)
587 {
588         unsigned int tmp;
589 
590         /* Stop any running conversion */
591         tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
592         tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
593         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
594 
595         /* Clear the control register */
596         outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
597 
598         return 0;
599 }
600 
601 static int ai_check_chanlist(struct comedi_device *dev,
602                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
603 {
604         const struct me4000_board *thisboard = comedi_board(dev);
605         int aref;
606         int i;
607 
608         /* Check whether a channel list is available */
609         if (!cmd->chanlist_len) {
610                 dev_err(dev->class_dev, "No channel list available\n");
611                 return -EINVAL;
612         }
613 
614         /* Check the channel list size */
615         if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
616                 dev_err(dev->class_dev, "Channel list is to large\n");
617                 return -EINVAL;
618         }
619 
620         /* Check the pointer */
621         if (!cmd->chanlist) {
622                 dev_err(dev->class_dev, "NULL pointer to channel list\n");
623                 return -EFAULT;
624         }
625 
626         /* Check whether aref is equal for all entries */
627         aref = CR_AREF(cmd->chanlist[0]);
628         for (i = 0; i < cmd->chanlist_len; i++) {
629                 if (CR_AREF(cmd->chanlist[i]) != aref) {
630                         dev_err(dev->class_dev,
631                                 "Mode is not equal for all entries\n");
632                         return -EINVAL;
633                 }
634         }
635 
636         /* Check whether channels are available for this ending */
637         if (aref == SDF_DIFF) {
638                 for (i = 0; i < cmd->chanlist_len; i++) {
639                         if (CR_CHAN(cmd->chanlist[i]) >=
640                             thisboard->ai_diff_nchan) {
641                                 dev_err(dev->class_dev,
642                                         "Channel number to high\n");
643                                 return -EINVAL;
644                         }
645                 }
646         } else {
647                 for (i = 0; i < cmd->chanlist_len; i++) {
648                         if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
649                                 dev_err(dev->class_dev,
650                                         "Channel number to high\n");
651                                 return -EINVAL;
652                         }
653                 }
654         }
655 
656         /* Check if bipolar is set for all entries when in differential mode */
657         if (aref == SDF_DIFF) {
658                 for (i = 0; i < cmd->chanlist_len; i++) {
659                         if (CR_RANGE(cmd->chanlist[i]) != 1 &&
660                             CR_RANGE(cmd->chanlist[i]) != 2) {
661                                 dev_err(dev->class_dev,
662                                        "Bipolar is not selected in differential mode\n");
663                                 return -EINVAL;
664                         }
665                 }
666         }
667 
668         return 0;
669 }
670 
671 static int ai_round_cmd_args(struct comedi_device *dev,
672                              struct comedi_subdevice *s,
673                              struct comedi_cmd *cmd,
674                              unsigned int *init_ticks,
675                              unsigned int *scan_ticks, unsigned int *chan_ticks)
676 {
677 
678         int rest;
679 
680         *init_ticks = 0;
681         *scan_ticks = 0;
682         *chan_ticks = 0;
683 
684         if (cmd->start_arg) {
685                 *init_ticks = (cmd->start_arg * 33) / 1000;
686                 rest = (cmd->start_arg * 33) % 1000;
687 
688                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
689                         if (rest > 33)
690                                 (*init_ticks)++;
691                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
692                         if (rest)
693                                 (*init_ticks)++;
694                 }
695         }
696 
697         if (cmd->scan_begin_arg) {
698                 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
699                 rest = (cmd->scan_begin_arg * 33) % 1000;
700 
701                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
702                         if (rest > 33)
703                                 (*scan_ticks)++;
704                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
705                         if (rest)
706                                 (*scan_ticks)++;
707                 }
708         }
709 
710         if (cmd->convert_arg) {
711                 *chan_ticks = (cmd->convert_arg * 33) / 1000;
712                 rest = (cmd->convert_arg * 33) % 1000;
713 
714                 if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
715                         if (rest > 33)
716                                 (*chan_ticks)++;
717                 } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
718                         if (rest)
719                                 (*chan_ticks)++;
720                 }
721         }
722 
723         return 0;
724 }
725 
726 static void ai_write_timer(struct comedi_device *dev,
727                            unsigned int init_ticks,
728                            unsigned int scan_ticks, unsigned int chan_ticks)
729 {
730         outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
731         outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
732 
733         if (scan_ticks) {
734                 outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
735                 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
736         }
737 
738         outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
739         outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
740 }
741 
742 static int ai_write_chanlist(struct comedi_device *dev,
743                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
744 {
745         unsigned int entry;
746         unsigned int chan;
747         unsigned int rang;
748         unsigned int aref;
749         int i;
750 
751         for (i = 0; i < cmd->chanlist_len; i++) {
752                 chan = CR_CHAN(cmd->chanlist[i]);
753                 rang = CR_RANGE(cmd->chanlist[i]);
754                 aref = CR_AREF(cmd->chanlist[i]);
755 
756                 entry = chan;
757 
758                 if (rang == 0)
759                         entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
760                 else if (rang == 1)
761                         entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
762                 else if (rang == 2)
763                         entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
764                 else
765                         entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
766 
767                 if (aref == SDF_DIFF)
768                         entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
769                 else
770                         entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
771 
772                 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
773         }
774 
775         return 0;
776 }
777 
778 static int ai_prepare(struct comedi_device *dev,
779                       struct comedi_subdevice *s,
780                       struct comedi_cmd *cmd,
781                       unsigned int init_ticks,
782                       unsigned int scan_ticks, unsigned int chan_ticks)
783 {
784 
785         unsigned int tmp = 0;
786 
787         /* Write timer arguments */
788         ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
789 
790         /* Reset control register */
791         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
792 
793         /* Start sources */
794         if ((cmd->start_src == TRIG_EXT &&
795              cmd->scan_begin_src == TRIG_TIMER &&
796              cmd->convert_src == TRIG_TIMER) ||
797             (cmd->start_src == TRIG_EXT &&
798              cmd->scan_begin_src == TRIG_FOLLOW &&
799              cmd->convert_src == TRIG_TIMER)) {
800                 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
801                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
802                     ME4000_AI_CTRL_BIT_DATA_FIFO;
803         } else if (cmd->start_src == TRIG_EXT &&
804                    cmd->scan_begin_src == TRIG_EXT &&
805                    cmd->convert_src == TRIG_TIMER) {
806                 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
807                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
808                     ME4000_AI_CTRL_BIT_DATA_FIFO;
809         } else if (cmd->start_src == TRIG_EXT &&
810                    cmd->scan_begin_src == TRIG_EXT &&
811                    cmd->convert_src == TRIG_EXT) {
812                 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
813                     ME4000_AI_CTRL_BIT_MODE_1 |
814                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
815                     ME4000_AI_CTRL_BIT_DATA_FIFO;
816         } else {
817                 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
818                     ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
819                     ME4000_AI_CTRL_BIT_DATA_FIFO;
820         }
821 
822         /* Stop triggers */
823         if (cmd->stop_src == TRIG_COUNT) {
824                 outl(cmd->chanlist_len * cmd->stop_arg,
825                             dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
826                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
827         } else if (cmd->stop_src == TRIG_NONE &&
828                    cmd->scan_end_src == TRIG_COUNT) {
829                 outl(cmd->scan_end_arg,
830                             dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
831                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
832         } else {
833                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
834         }
835 
836         /* Write the setup to the control register */
837         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
838 
839         /* Write the channel list */
840         ai_write_chanlist(dev, s, cmd);
841 
842         return 0;
843 }
844 
845 static int me4000_ai_do_cmd(struct comedi_device *dev,
846                             struct comedi_subdevice *s)
847 {
848         int err;
849         unsigned int init_ticks = 0;
850         unsigned int scan_ticks = 0;
851         unsigned int chan_ticks = 0;
852         struct comedi_cmd *cmd = &s->async->cmd;
853 
854         /* Reset the analog input */
855         err = me4000_ai_cancel(dev, s);
856         if (err)
857                 return err;
858 
859         /* Round the timer arguments */
860         err = ai_round_cmd_args(dev,
861                                 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
862         if (err)
863                 return err;
864 
865         /* Prepare the AI for acquisition */
866         err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
867         if (err)
868                 return err;
869 
870         /* Start acquistion by dummy read */
871         inl(dev->iobase + ME4000_AI_START_REG);
872 
873         return 0;
874 }
875 
876 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
877                                  struct comedi_subdevice *s,
878                                  struct comedi_cmd *cmd)
879 {
880 
881         unsigned int init_ticks;
882         unsigned int chan_ticks;
883         unsigned int scan_ticks;
884         int err = 0;
885 
886         /* Only rounding flags are implemented */
887         cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
888 
889         /* Round the timer arguments */
890         ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
891 
892         /* Step 1 : check if triggers are trivially valid */
893 
894         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
895         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
896                                         TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
897         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
898         err |= cfc_check_trigger_src(&cmd->scan_end_src,
899                                         TRIG_NONE | TRIG_COUNT);
900         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
901 
902         if (err)
903                 return 1;
904 
905         /* Step 2a : make sure trigger sources are unique */
906 
907         err |= cfc_check_trigger_is_unique(cmd->start_src);
908         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
909         err |= cfc_check_trigger_is_unique(cmd->convert_src);
910         err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
911         err |= cfc_check_trigger_is_unique(cmd->stop_src);
912 
913         /* Step 2b : and mutually compatible */
914 
915         if (cmd->start_src == TRIG_NOW &&
916             cmd->scan_begin_src == TRIG_TIMER &&
917             cmd->convert_src == TRIG_TIMER) {
918         } else if (cmd->start_src == TRIG_NOW &&
919                    cmd->scan_begin_src == TRIG_FOLLOW &&
920                    cmd->convert_src == TRIG_TIMER) {
921         } else if (cmd->start_src == TRIG_EXT &&
922                    cmd->scan_begin_src == TRIG_TIMER &&
923                    cmd->convert_src == TRIG_TIMER) {
924         } else if (cmd->start_src == TRIG_EXT &&
925                    cmd->scan_begin_src == TRIG_FOLLOW &&
926                    cmd->convert_src == TRIG_TIMER) {
927         } else if (cmd->start_src == TRIG_EXT &&
928                    cmd->scan_begin_src == TRIG_EXT &&
929                    cmd->convert_src == TRIG_TIMER) {
930         } else if (cmd->start_src == TRIG_EXT &&
931                    cmd->scan_begin_src == TRIG_EXT &&
932                    cmd->convert_src == TRIG_EXT) {
933         } else {
934                 err |= -EINVAL;
935         }
936 
937         if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
938         } else if (cmd->stop_src == TRIG_COUNT &&
939                    cmd->scan_end_src == TRIG_NONE) {
940         } else if (cmd->stop_src == TRIG_NONE &&
941                    cmd->scan_end_src == TRIG_COUNT) {
942         } else if (cmd->stop_src == TRIG_COUNT &&
943                    cmd->scan_end_src == TRIG_COUNT) {
944         } else {
945                 err |= -EINVAL;
946         }
947 
948         if (err)
949                 return 2;
950 
951         /* Step 3: check if arguments are trivially valid */
952 
953         if (cmd->chanlist_len < 1) {
954                 cmd->chanlist_len = 1;
955                 err |= -EINVAL;
956         }
957         if (init_ticks < 66) {
958                 cmd->start_arg = 2000;
959                 err |= -EINVAL;
960         }
961         if (scan_ticks && scan_ticks < 67) {
962                 cmd->scan_begin_arg = 2031;
963                 err |= -EINVAL;
964         }
965         if (chan_ticks < 66) {
966                 cmd->convert_arg = 2000;
967                 err |= -EINVAL;
968         }
969 
970         if (err)
971                 return 3;
972 
973         /*
974          * Stage 4. Check for argument conflicts.
975          */
976         if (cmd->start_src == TRIG_NOW &&
977             cmd->scan_begin_src == TRIG_TIMER &&
978             cmd->convert_src == TRIG_TIMER) {
979 
980                 /* Check timer arguments */
981                 if (init_ticks < ME4000_AI_MIN_TICKS) {
982                         dev_err(dev->class_dev, "Invalid start arg\n");
983                         cmd->start_arg = 2000;  /*  66 ticks at least */
984                         err++;
985                 }
986                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
987                         dev_err(dev->class_dev, "Invalid convert arg\n");
988                         cmd->convert_arg = 2000;        /*  66 ticks at least */
989                         err++;
990                 }
991                 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
992                         dev_err(dev->class_dev, "Invalid scan end arg\n");
993 
994                         /*  At least one tick more */
995                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
996                         err++;
997                 }
998         } else if (cmd->start_src == TRIG_NOW &&
999                    cmd->scan_begin_src == TRIG_FOLLOW &&
1000                    cmd->convert_src == TRIG_TIMER) {
1001 
1002                 /* Check timer arguments */
1003                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1004                         dev_err(dev->class_dev, "Invalid start arg\n");
1005                         cmd->start_arg = 2000;  /*  66 ticks at least */
1006                         err++;
1007                 }
1008                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1009                         dev_err(dev->class_dev, "Invalid convert arg\n");
1010                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1011                         err++;
1012                 }
1013         } else if (cmd->start_src == TRIG_EXT &&
1014                    cmd->scan_begin_src == TRIG_TIMER &&
1015                    cmd->convert_src == TRIG_TIMER) {
1016 
1017                 /* Check timer arguments */
1018                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1019                         dev_err(dev->class_dev, "Invalid start arg\n");
1020                         cmd->start_arg = 2000;  /*  66 ticks at least */
1021                         err++;
1022                 }
1023                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1024                         dev_err(dev->class_dev, "Invalid convert arg\n");
1025                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1026                         err++;
1027                 }
1028                 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1029                         dev_err(dev->class_dev, "Invalid scan end arg\n");
1030 
1031                         /*  At least one tick more */
1032                         cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1033                         err++;
1034                 }
1035         } else if (cmd->start_src == TRIG_EXT &&
1036                    cmd->scan_begin_src == TRIG_FOLLOW &&
1037                    cmd->convert_src == TRIG_TIMER) {
1038 
1039                 /* Check timer arguments */
1040                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1041                         dev_err(dev->class_dev, "Invalid start arg\n");
1042                         cmd->start_arg = 2000;  /*  66 ticks at least */
1043                         err++;
1044                 }
1045                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1046                         dev_err(dev->class_dev, "Invalid convert arg\n");
1047                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1048                         err++;
1049                 }
1050         } else if (cmd->start_src == TRIG_EXT &&
1051                    cmd->scan_begin_src == TRIG_EXT &&
1052                    cmd->convert_src == TRIG_TIMER) {
1053 
1054                 /* Check timer arguments */
1055                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1056                         dev_err(dev->class_dev, "Invalid start arg\n");
1057                         cmd->start_arg = 2000;  /*  66 ticks at least */
1058                         err++;
1059                 }
1060                 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1061                         dev_err(dev->class_dev, "Invalid convert arg\n");
1062                         cmd->convert_arg = 2000;        /*  66 ticks at least */
1063                         err++;
1064                 }
1065         } else if (cmd->start_src == TRIG_EXT &&
1066                    cmd->scan_begin_src == TRIG_EXT &&
1067                    cmd->convert_src == TRIG_EXT) {
1068 
1069                 /* Check timer arguments */
1070                 if (init_ticks < ME4000_AI_MIN_TICKS) {
1071                         dev_err(dev->class_dev, "Invalid start arg\n");
1072                         cmd->start_arg = 2000;  /*  66 ticks at least */
1073                         err++;
1074                 }
1075         }
1076         if (cmd->stop_src == TRIG_COUNT) {
1077                 if (cmd->stop_arg == 0) {
1078                         dev_err(dev->class_dev, "Invalid stop arg\n");
1079                         cmd->stop_arg = 1;
1080                         err++;
1081                 }
1082         }
1083         if (cmd->scan_end_src == TRIG_COUNT) {
1084                 if (cmd->scan_end_arg == 0) {
1085                         dev_err(dev->class_dev, "Invalid scan end arg\n");
1086                         cmd->scan_end_arg = 1;
1087                         err++;
1088                 }
1089         }
1090 
1091         if (err)
1092                 return 4;
1093 
1094         /*
1095          * Stage 5. Check the channel list.
1096          */
1097         if (ai_check_chanlist(dev, s, cmd))
1098                 return 5;
1099 
1100         return 0;
1101 }
1102 
1103 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1104 {
1105         unsigned int tmp;
1106         struct comedi_device *dev = dev_id;
1107         struct comedi_subdevice *s = dev->read_subdev;
1108         int i;
1109         int c = 0;
1110         unsigned int lval;
1111 
1112         if (!dev->attached)
1113                 return IRQ_NONE;
1114 
1115         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1116             ME4000_IRQ_STATUS_BIT_AI_HF) {
1117                 /* Read status register to find out what happened */
1118                 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1119 
1120                 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1121                     !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1122                     (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1123                         c = ME4000_AI_FIFO_COUNT;
1124 
1125                         /*
1126                          * FIFO overflow, so stop conversion
1127                          * and disable all interrupts
1128                          */
1129                         tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1130                         tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1131                                  ME4000_AI_CTRL_BIT_SC_IRQ);
1132                         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1133 
1134                         s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1135 
1136                         dev_err(dev->class_dev, "FIFO overflow\n");
1137                 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1138                            && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1139                            && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1140                         s->async->events |= COMEDI_CB_BLOCK;
1141 
1142                         c = ME4000_AI_FIFO_COUNT / 2;
1143                 } else {
1144                         dev_err(dev->class_dev,
1145                                 "Can't determine state of fifo\n");
1146                         c = 0;
1147 
1148                         /*
1149                          * Undefined state, so stop conversion
1150                          * and disable all interrupts
1151                          */
1152                         tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1153                         tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1154                                  ME4000_AI_CTRL_BIT_SC_IRQ);
1155                         outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1156 
1157                         s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1158 
1159                         dev_err(dev->class_dev, "Undefined FIFO state\n");
1160                 }
1161 
1162                 for (i = 0; i < c; i++) {
1163                         /* Read value from data fifo */
1164                         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1165                         lval ^= 0x8000;
1166 
1167                         if (!comedi_buf_put(s->async, lval)) {
1168                                 /*
1169                                  * Buffer overflow, so stop conversion
1170                                  * and disable all interrupts
1171                                  */
1172                                 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1173                                 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1174                                          ME4000_AI_CTRL_BIT_SC_IRQ);
1175                                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1176 
1177                                 s->async->events |= COMEDI_CB_OVERFLOW;
1178 
1179                                 dev_err(dev->class_dev, "Buffer overflow\n");
1180 
1181                                 break;
1182                         }
1183                 }
1184 
1185                 /* Work is done, so reset the interrupt */
1186                 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1187                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1188                 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1189                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1190         }
1191 
1192         if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1193             ME4000_IRQ_STATUS_BIT_SC) {
1194                 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1195 
1196                 /*
1197                  * Acquisition is complete, so stop
1198                  * conversion and disable all interrupts
1199                  */
1200                 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1201                 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1202                 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1203                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1204 
1205                 /* Poll data until fifo empty */
1206                 while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1207                        ME4000_AI_STATUS_BIT_EF_DATA) {
1208                         /* Read value from data fifo */
1209                         lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1210                         lval ^= 0x8000;
1211 
1212                         if (!comedi_buf_put(s->async, lval)) {
1213                                 dev_err(dev->class_dev, "Buffer overflow\n");
1214                                 s->async->events |= COMEDI_CB_OVERFLOW;
1215                                 break;
1216                         }
1217                 }
1218 
1219                 /* Work is done, so reset the interrupt */
1220                 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1221                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1222                 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1223                 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1224         }
1225 
1226         if (s->async->events)
1227                 comedi_event(dev, s);
1228 
1229         return IRQ_HANDLED;
1230 }
1231 
1232 /*=============================================================================
1233   Analog output section
1234   ===========================================================================*/
1235 
1236 static int me4000_ao_insn_write(struct comedi_device *dev,
1237                                 struct comedi_subdevice *s,
1238                                 struct comedi_insn *insn, unsigned int *data)
1239 {
1240         const struct me4000_board *thisboard = comedi_board(dev);
1241         struct me4000_info *info = dev->private;
1242         int chan = CR_CHAN(insn->chanspec);
1243         int rang = CR_RANGE(insn->chanspec);
1244         int aref = CR_AREF(insn->chanspec);
1245         unsigned int tmp;
1246 
1247         if (insn->n == 0) {
1248                 return 0;
1249         } else if (insn->n > 1) {
1250                 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1251                         insn->n);
1252                 return -EINVAL;
1253         }
1254 
1255         if (chan >= thisboard->ao_nchan) {
1256                 dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
1257                 return -EINVAL;
1258         }
1259 
1260         if (rang != 0) {
1261                 dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
1262                 return -EINVAL;
1263         }
1264 
1265         if (aref != AREF_GROUND && aref != AREF_COMMON) {
1266                 dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
1267                 return -EINVAL;
1268         }
1269 
1270         /* Stop any running conversion */
1271         tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1272         tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1273         outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1274 
1275         /* Clear control register and set to single mode */
1276         outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1277 
1278         /* Write data value */
1279         outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1280 
1281         /* Store in the mirror */
1282         info->ao_readback[chan] = data[0];
1283 
1284         return 1;
1285 }
1286 
1287 static int me4000_ao_insn_read(struct comedi_device *dev,
1288                                struct comedi_subdevice *s,
1289                                struct comedi_insn *insn, unsigned int *data)
1290 {
1291         struct me4000_info *info = dev->private;
1292         int chan = CR_CHAN(insn->chanspec);
1293 
1294         if (insn->n == 0) {
1295                 return 0;
1296         } else if (insn->n > 1) {
1297                 dev_err(dev->class_dev, "Invalid instruction length\n");
1298                 return -EINVAL;
1299         }
1300 
1301         data[0] = info->ao_readback[chan];
1302 
1303         return 1;
1304 }
1305 
1306 static int me4000_dio_insn_bits(struct comedi_device *dev,
1307                                 struct comedi_subdevice *s,
1308                                 struct comedi_insn *insn,
1309                                 unsigned int *data)
1310 {
1311         if (comedi_dio_update_state(s, data)) {
1312                 outl((s->state >> 0) & 0xFF,
1313                             dev->iobase + ME4000_DIO_PORT_0_REG);
1314                 outl((s->state >> 8) & 0xFF,
1315                             dev->iobase + ME4000_DIO_PORT_1_REG);
1316                 outl((s->state >> 16) & 0xFF,
1317                             dev->iobase + ME4000_DIO_PORT_2_REG);
1318                 outl((s->state >> 24) & 0xFF,
1319                             dev->iobase + ME4000_DIO_PORT_3_REG);
1320         }
1321 
1322         data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1323                   ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1324                   ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1325                   ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1326 
1327         return insn->n;
1328 }
1329 
1330 static int me4000_dio_insn_config(struct comedi_device *dev,
1331                                   struct comedi_subdevice *s,
1332                                   struct comedi_insn *insn,
1333                                   unsigned int *data)
1334 {
1335         unsigned int chan = CR_CHAN(insn->chanspec);
1336         unsigned int mask;
1337         unsigned int tmp;
1338         int ret;
1339 
1340         if (chan < 8)
1341                 mask = 0x000000ff;
1342         else if (chan < 16)
1343                 mask = 0x0000ff00;
1344         else if (chan < 24)
1345                 mask = 0x00ff0000;
1346         else
1347                 mask = 0xff000000;
1348 
1349         ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1350         if (ret)
1351                 return ret;
1352 
1353         tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1354         tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
1355                  ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 |
1356                  ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 |
1357                  ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
1358         if (s->io_bits & 0x000000ff)
1359                 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1360         if (s->io_bits & 0x0000ff00)
1361                 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1362         if (s->io_bits & 0x00ff0000)
1363                 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1364         if (s->io_bits & 0xff000000)
1365                 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1366 
1367         /*
1368          * Check for optoisolated ME-4000 version.
1369          * If one the first port is a fixed output
1370          * port and the second is a fixed input port.
1371          */
1372         if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1373                 s->io_bits |= 0x000000ff;
1374                 s->io_bits &= ~0x0000ff00;
1375                 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1376                 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1377                          ME4000_DIO_CTRL_BIT_MODE_3);
1378         }
1379 
1380         outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1381 
1382         return insn->n;
1383 }
1384 
1385 /*=============================================================================
1386   Counter section
1387   ===========================================================================*/
1388 
1389 static int me4000_cnt_insn_config(struct comedi_device *dev,
1390                                   struct comedi_subdevice *s,
1391                                   struct comedi_insn *insn,
1392                                   unsigned int *data)
1393 {
1394         struct me4000_info *info = dev->private;
1395         int err;
1396 
1397         switch (data[0]) {
1398         case GPCT_RESET:
1399                 if (insn->n != 1)
1400                         return -EINVAL;
1401 
1402                 err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0,
1403                                 I8254_MODE0 | I8254_BINARY);
1404                 if (err)
1405                         return err;
1406                 break;
1407         case GPCT_SET_OPERATION:
1408                 if (insn->n != 2)
1409                         return -EINVAL;
1410 
1411                 err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec,
1412                                 (data[1] << 1) | I8254_BINARY);
1413                 if (err)
1414                         return err;
1415                 break;
1416         default:
1417                 return -EINVAL;
1418         }
1419 
1420         return insn->n;
1421 }
1422 
1423 static int me4000_cnt_insn_read(struct comedi_device *dev,
1424                                 struct comedi_subdevice *s,
1425                                 struct comedi_insn *insn, unsigned int *data)
1426 {
1427         struct me4000_info *info = dev->private;
1428 
1429         if (insn->n == 0)
1430                 return 0;
1431 
1432         if (insn->n > 1) {
1433                 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1434                         insn->n);
1435                 return -EINVAL;
1436         }
1437 
1438         data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
1439 
1440         return 1;
1441 }
1442 
1443 static int me4000_cnt_insn_write(struct comedi_device *dev,
1444                                  struct comedi_subdevice *s,
1445                                  struct comedi_insn *insn, unsigned int *data)
1446 {
1447         struct me4000_info *info = dev->private;
1448 
1449         if (insn->n == 0) {
1450                 return 0;
1451         } else if (insn->n > 1) {
1452                 dev_err(dev->class_dev, "Invalid instruction length %d\n",
1453                         insn->n);
1454                 return -EINVAL;
1455         }
1456 
1457         i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
1458 
1459         return 1;
1460 }
1461 
1462 static int me4000_auto_attach(struct comedi_device *dev,
1463                               unsigned long context)
1464 {
1465         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1466         const struct me4000_board *thisboard = NULL;
1467         struct me4000_info *info;
1468         struct comedi_subdevice *s;
1469         int result;
1470 
1471         if (context < ARRAY_SIZE(me4000_boards))
1472                 thisboard = &me4000_boards[context];
1473         if (!thisboard)
1474                 return -ENODEV;
1475         dev->board_ptr = thisboard;
1476         dev->board_name = thisboard->name;
1477 
1478         info = comedi_alloc_devpriv(dev, sizeof(*info));
1479         if (!info)
1480                 return -ENOMEM;
1481 
1482         result = comedi_pci_enable(dev);
1483         if (result)
1484                 return result;
1485 
1486         info->plx_regbase = pci_resource_start(pcidev, 1);
1487         dev->iobase = pci_resource_start(pcidev, 2);
1488         info->timer_regbase = pci_resource_start(pcidev, 3);
1489         if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1490                 return -ENODEV;
1491 
1492         result = xilinx_download(dev);
1493         if (result)
1494                 return result;
1495 
1496         me4000_reset(dev);
1497 
1498         if (pcidev->irq > 0) {
1499                 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1500                                   dev->board_name, dev);
1501                 if (result == 0)
1502                         dev->irq = pcidev->irq;
1503         }
1504 
1505         result = comedi_alloc_subdevices(dev, 4);
1506         if (result)
1507                 return result;
1508 
1509     /*=========================================================================
1510       Analog input subdevice
1511       ========================================================================*/
1512 
1513         s = &dev->subdevices[0];
1514 
1515         if (thisboard->ai_nchan) {
1516                 s->type = COMEDI_SUBD_AI;
1517                 s->subdev_flags =
1518                     SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1519                 s->n_chan = thisboard->ai_nchan;
1520                 s->maxdata = 0xFFFF;    /*  16 bit ADC */
1521                 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1522                 s->range_table = &me4000_ai_range;
1523                 s->insn_read = me4000_ai_insn_read;
1524 
1525                 if (dev->irq) {
1526                         dev->read_subdev = s;
1527                         s->subdev_flags |= SDF_CMD_READ;
1528                         s->cancel = me4000_ai_cancel;
1529                         s->do_cmdtest = me4000_ai_do_cmd_test;
1530                         s->do_cmd = me4000_ai_do_cmd;
1531                 }
1532         } else {
1533                 s->type = COMEDI_SUBD_UNUSED;
1534         }
1535 
1536     /*=========================================================================
1537       Analog output subdevice
1538       ========================================================================*/
1539 
1540         s = &dev->subdevices[1];
1541 
1542         if (thisboard->ao_nchan) {
1543                 s->type = COMEDI_SUBD_AO;
1544                 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1545                 s->n_chan = thisboard->ao_nchan;
1546                 s->maxdata = 0xFFFF;    /*  16 bit DAC */
1547                 s->range_table = &range_bipolar10;
1548                 s->insn_write = me4000_ao_insn_write;
1549                 s->insn_read = me4000_ao_insn_read;
1550         } else {
1551                 s->type = COMEDI_SUBD_UNUSED;
1552         }
1553 
1554     /*=========================================================================
1555       Digital I/O subdevice
1556       ========================================================================*/
1557 
1558         s = &dev->subdevices[2];
1559 
1560         if (thisboard->dio_nchan) {
1561                 s->type = COMEDI_SUBD_DIO;
1562                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1563                 s->n_chan = thisboard->dio_nchan;
1564                 s->maxdata = 1;
1565                 s->range_table = &range_digital;
1566                 s->insn_bits = me4000_dio_insn_bits;
1567                 s->insn_config = me4000_dio_insn_config;
1568         } else {
1569                 s->type = COMEDI_SUBD_UNUSED;
1570         }
1571 
1572         /*
1573          * Check for optoisolated ME-4000 version. If one the first
1574          * port is a fixed output port and the second is a fixed input port.
1575          */
1576         if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1577                 s->io_bits |= 0xFF;
1578                 outl(ME4000_DIO_CTRL_BIT_MODE_0,
1579                         dev->iobase + ME4000_DIO_DIR_REG);
1580         }
1581 
1582     /*=========================================================================
1583       Counter subdevice
1584       ========================================================================*/
1585 
1586         s = &dev->subdevices[3];
1587 
1588         if (thisboard->has_counter) {
1589                 s->type = COMEDI_SUBD_COUNTER;
1590                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1591                 s->n_chan = 3;
1592                 s->maxdata = 0xFFFF;    /*  16 bit counters */
1593                 s->insn_read = me4000_cnt_insn_read;
1594                 s->insn_write = me4000_cnt_insn_write;
1595                 s->insn_config = me4000_cnt_insn_config;
1596         } else {
1597                 s->type = COMEDI_SUBD_UNUSED;
1598         }
1599 
1600         return 0;
1601 }
1602 
1603 static void me4000_detach(struct comedi_device *dev)
1604 {
1605         if (dev->irq)
1606                 free_irq(dev->irq, dev);
1607         if (dev->iobase)
1608                 me4000_reset(dev);
1609         comedi_pci_disable(dev);
1610 }
1611 
1612 static struct comedi_driver me4000_driver = {
1613         .driver_name    = "me4000",
1614         .module         = THIS_MODULE,
1615         .auto_attach    = me4000_auto_attach,
1616         .detach         = me4000_detach,
1617 };
1618 
1619 static int me4000_pci_probe(struct pci_dev *dev,
1620                             const struct pci_device_id *id)
1621 {
1622         return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1623 }
1624 
1625 static const struct pci_device_id me4000_pci_table[] = {
1626         { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1627         { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1628         { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1629         { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1630         { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1631         { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1632         { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1633         { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1634         { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1635         { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1636         { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1637         { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1638         { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1639         { 0 }
1640 };
1641 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1642 
1643 static struct pci_driver me4000_pci_driver = {
1644         .name           = "me4000",
1645         .id_table       = me4000_pci_table,
1646         .probe          = me4000_pci_probe,
1647         .remove         = comedi_pci_auto_unconfig,
1648 };
1649 module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1650 
1651 MODULE_AUTHOR("Comedi http://www.comedi.org");
1652 MODULE_DESCRIPTION("Comedi low-level driver");
1653 MODULE_LICENSE("GPL");
1654 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us