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

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

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