Version:  2.0.40 2.2.26 2.4.37 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 3.16 3.17 3.18

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

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