Version:  2.0.40 2.2.26 2.4.37 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 3.19 4.0 4.1 4.2

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

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