added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / staging / comedi / drivers / me4000.c
blobb432aa7d7644041bf2ae9b37cbd38bf8b07081e3
1 /*
2 comedi/drivers/me4000.c
3 Source code for the Meilhaus ME-4000 board family.
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
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.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 Driver: me4000
25 Description: Meilhaus ME-4000 series boards
26 Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
27 Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
28 Updated: Mon, 18 Mar 2002 15:34:01 -0800
29 Status: broken (no support for loading firmware)
31 Supports:
33 - Analog Input
34 - Analog Output
35 - Digital I/O
36 - Counter
38 Configuration Options:
40 [0] - PCI bus number (optional)
41 [1] - PCI slot number (optional)
43 If bus/slot is not specified, the first available PCI
44 device will be used.
46 The firmware required by these boards is available in the
47 comedi_nonfree_firmware tarball available from
48 http://www.comedi.org. However, the driver's support for
49 loading the firmware through comedi_config is currently
50 broken.
54 #include "../comedidev.h"
56 #include <linux/delay.h>
57 #include <linux/list.h>
58 #include <linux/spinlock.h>
60 #include "comedi_pci.h"
61 #include "me4000.h"
62 #if 0
63 /* file removed due to GPL incompatibility */
64 #include "me4000_fw.h"
65 #endif
67 /*=============================================================================
68 PCI device table.
69 This is used by modprobe to translate PCI IDs to drivers.
70 ===========================================================================*/
72 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
73 {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
75 {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
76 {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
78 {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
80 {PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
81 {PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
82 {PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85 {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
86 {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
88 {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
90 {0}
93 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
95 static const me4000_board_t me4000_boards[] = {
96 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
98 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
99 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
100 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
101 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
103 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
104 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
105 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
106 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
108 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
109 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
110 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
111 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
113 {0},
116 #define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
118 /*-----------------------------------------------------------------------------
119 Comedi function prototypes
120 ---------------------------------------------------------------------------*/
121 static int me4000_attach(comedi_device * dev, comedi_devconfig * it);
122 static int me4000_detach(comedi_device * dev);
123 static comedi_driver driver_me4000 = {
124 driver_name:"me4000",
125 module:THIS_MODULE,
126 attach:me4000_attach,
127 detach:me4000_detach,
130 /*-----------------------------------------------------------------------------
131 Meilhaus function prototypes
132 ---------------------------------------------------------------------------*/
133 static int me4000_probe(comedi_device * dev, comedi_devconfig * it);
134 static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p);
135 static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p);
136 static int init_ao_context(comedi_device * dev);
137 static int init_ai_context(comedi_device * dev);
138 static int init_dio_context(comedi_device * dev);
139 static int init_cnt_context(comedi_device * dev);
140 static int xilinx_download(comedi_device * dev);
141 static int reset_board(comedi_device * dev);
143 static int me4000_dio_insn_bits(comedi_device * dev,
144 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
146 static int me4000_dio_insn_config(comedi_device * dev,
147 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
149 static int cnt_reset(comedi_device * dev, unsigned int channel);
151 static int cnt_config(comedi_device * dev,
152 unsigned int channel, unsigned int mode);
154 static int me4000_cnt_insn_config(comedi_device * dev,
155 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
157 static int me4000_cnt_insn_write(comedi_device * dev,
158 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
160 static int me4000_cnt_insn_read(comedi_device * dev,
161 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
163 static int me4000_ai_insn_read(comedi_device * dev,
164 comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data);
166 static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s);
168 static int ai_check_chanlist(comedi_device * dev,
169 comedi_subdevice * s, comedi_cmd * cmd);
171 static int ai_round_cmd_args(comedi_device * dev,
172 comedi_subdevice * s,
173 comedi_cmd * cmd,
174 unsigned int *init_ticks,
175 unsigned int *scan_ticks, unsigned int *chan_ticks);
177 static int ai_prepare(comedi_device * dev,
178 comedi_subdevice * s,
179 comedi_cmd * cmd,
180 unsigned int init_ticks,
181 unsigned int scan_ticks, unsigned int chan_ticks);
183 static int ai_write_chanlist(comedi_device * dev,
184 comedi_subdevice * s, comedi_cmd * cmd);
186 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
188 static int me4000_ai_do_cmd_test(comedi_device * dev,
189 comedi_subdevice * s, comedi_cmd * cmd);
191 static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s);
193 static int me4000_ao_insn_write(comedi_device * dev,
194 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
196 static int me4000_ao_insn_read(comedi_device * dev,
197 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
199 /*-----------------------------------------------------------------------------
200 Meilhaus inline functions
201 ---------------------------------------------------------------------------*/
203 static inline void me4000_outb(comedi_device * dev, unsigned char value,
204 unsigned long port)
206 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
207 outb(value, port);
210 static inline void me4000_outl(comedi_device * dev, unsigned long value,
211 unsigned long port)
213 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
214 outl(value, port);
217 static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
219 unsigned long value;
220 value = inl(port);
221 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
222 return value;
225 static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
227 unsigned char value;
228 value = inb(port);
229 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
230 return value;
233 static const comedi_lrange me4000_ai_range = {
236 UNI_RANGE(2.5),
237 UNI_RANGE(10),
238 BIP_RANGE(2.5),
239 BIP_RANGE(10),
243 static const comedi_lrange me4000_ao_range = {
246 BIP_RANGE(10),
250 static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
252 comedi_subdevice *s;
253 int result;
255 CALL_PDEBUG("In me4000_attach()\n");
257 result = me4000_probe(dev, it);
258 if (result)
259 return result;
262 * Allocate the subdevice structures. alloc_subdevice() is a
263 * convenient macro defined in comedidev.h. It relies on
264 * n_subdevices being set correctly.
266 if (alloc_subdevices(dev, 4) < 0)
267 return -ENOMEM;
269 /*=========================================================================
270 Analog input subdevice
271 ========================================================================*/
273 s = dev->subdevices + 0;
275 if (thisboard->ai.count) {
276 s->type = COMEDI_SUBD_AI;
277 s->subdev_flags =
278 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
279 s->n_chan = thisboard->ai.count;
280 s->maxdata = 0xFFFF; // 16 bit ADC
281 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
282 s->range_table = &me4000_ai_range;
283 s->insn_read = me4000_ai_insn_read;
285 if (info->irq > 0) {
286 if (comedi_request_irq(info->irq, me4000_ai_isr,
287 IRQF_SHARED, "ME-4000", dev)) {
288 printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
289 } else {
290 dev->read_subdev = s;
291 s->subdev_flags |= SDF_CMD_READ;
292 s->cancel = me4000_ai_cancel;
293 s->do_cmdtest = me4000_ai_do_cmd_test;
294 s->do_cmd = me4000_ai_do_cmd;
296 } else {
297 printk(KERN_WARNING
298 "comedi%d: me4000: me4000_attach(): No interrupt available\n",
299 dev->minor);
301 } else {
302 s->type = COMEDI_SUBD_UNUSED;
305 /*=========================================================================
306 Analog output subdevice
307 ========================================================================*/
309 s = dev->subdevices + 1;
311 if (thisboard->ao.count) {
312 s->type = COMEDI_SUBD_AO;
313 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
314 s->n_chan = thisboard->ao.count;
315 s->maxdata = 0xFFFF; // 16 bit DAC
316 s->range_table = &me4000_ao_range;
317 s->insn_write = me4000_ao_insn_write;
318 s->insn_read = me4000_ao_insn_read;
319 } else {
320 s->type = COMEDI_SUBD_UNUSED;
323 /*=========================================================================
324 Digital I/O subdevice
325 ========================================================================*/
327 s = dev->subdevices + 2;
329 if (thisboard->dio.count) {
330 s->type = COMEDI_SUBD_DIO;
331 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
332 s->n_chan = thisboard->dio.count * 8;
333 s->maxdata = 1;
334 s->range_table = &range_digital;
335 s->insn_bits = me4000_dio_insn_bits;
336 s->insn_config = me4000_dio_insn_config;
337 } else {
338 s->type = COMEDI_SUBD_UNUSED;
342 * Check for optoisolated ME-4000 version. If one the first
343 * port is a fixed output port and the second is a fixed input port.
345 if (!me4000_inl(dev, info->dio_context.dir_reg)) {
346 s->io_bits |= 0xFF;
347 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
348 info->dio_context.dir_reg);
351 /*=========================================================================
352 Counter subdevice
353 ========================================================================*/
355 s = dev->subdevices + 3;
357 if (thisboard->cnt.count) {
358 s->type = COMEDI_SUBD_COUNTER;
359 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
360 s->n_chan = thisboard->cnt.count;
361 s->maxdata = 0xFFFF; // 16 bit counters
362 s->insn_read = me4000_cnt_insn_read;
363 s->insn_write = me4000_cnt_insn_write;
364 s->insn_config = me4000_cnt_insn_config;
365 } else {
366 s->type = COMEDI_SUBD_UNUSED;
369 return 0;
372 static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
374 struct pci_dev *pci_device;
375 int result, i;
376 me4000_board_t *board;
378 CALL_PDEBUG("In me4000_probe()\n");
380 /* Allocate private memory */
381 if (alloc_private(dev, sizeof(me4000_info_t)) < 0) {
382 return -ENOMEM;
385 * Probe the device to determine what device in the series it is.
387 for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
388 pci_device != NULL;
389 pci_device =
390 pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
391 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
392 for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
393 if (me4000_boards[i].device_id ==
394 pci_device->device) {
395 /* Was a particular bus/slot requested? */
396 if ((it->options[0] != 0)
397 || (it->options[1] != 0)) {
398 /* Are we on the wrong bus/slot? */
399 if (pci_device->bus->number !=
400 it->options[0]
401 || PCI_SLOT(pci_device->
402 devfn) !=
403 it->options[1]) {
404 continue;
407 dev->board_ptr = me4000_boards + i;
408 board = (me4000_board_t *) dev->
409 board_ptr;
410 info->pci_dev_p = pci_device;
411 goto found;
417 printk(KERN_ERR
418 "comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
419 dev->minor, it->options[0], it->options[1]);
420 return -ENODEV;
422 found:
424 printk(KERN_INFO
425 "comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
426 dev->minor, me4000_boards[i].name, pci_device->bus->number,
427 PCI_SLOT(pci_device->devfn));
429 /* Set data in device structure */
430 dev->board_name = board->name;
432 /* Enable PCI device and request regions */
433 result = comedi_pci_enable(pci_device, dev->board_name);
434 if (result) {
435 printk(KERN_ERR
436 "comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
437 dev->minor);
438 return result;
441 /* Get the PCI base registers */
442 result = get_registers(dev, pci_device);
443 if (result) {
444 printk(KERN_ERR
445 "comedi%d: me4000: me4000_probe(): Cannot get registers\n",
446 dev->minor);
447 return result;
449 /* Initialize board info */
450 result = init_board_info(dev, pci_device);
451 if (result) {
452 printk(KERN_ERR
453 "comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
454 dev->minor);
455 return result;
458 /* Init analog output context */
459 result = init_ao_context(dev);
460 if (result) {
461 printk(KERN_ERR
462 "comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
463 dev->minor);
464 return result;
467 /* Init analog input context */
468 result = init_ai_context(dev);
469 if (result) {
470 printk(KERN_ERR
471 "comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
472 dev->minor);
473 return result;
476 /* Init digital I/O context */
477 result = init_dio_context(dev);
478 if (result) {
479 printk(KERN_ERR
480 "comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
481 dev->minor);
482 return result;
485 /* Init counter context */
486 result = init_cnt_context(dev);
487 if (result) {
488 printk(KERN_ERR
489 "comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
490 dev->minor);
491 return result;
494 /* Download the xilinx firmware */
495 result = xilinx_download(dev);
496 if (result) {
497 printk(KERN_ERR
498 "comedi%d: me4000: me4000_probe(): Can't download firmware\n",
499 dev->minor);
500 return result;
503 /* Make a hardware reset */
504 result = reset_board(dev);
505 if (result) {
506 printk(KERN_ERR
507 "comedi%d: me4000: me4000_probe(): Can't reset board\n",
508 dev->minor);
509 return result;
512 return 0;
515 static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
518 CALL_PDEBUG("In get_registers()\n");
520 /*--------------------------- plx regbase ---------------------------------*/
522 info->plx_regbase = pci_resource_start(pci_dev_p, 1);
523 if (info->plx_regbase == 0) {
524 printk(KERN_ERR
525 "comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
526 dev->minor);
527 return -ENODEV;
529 info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
531 /*--------------------------- me4000 regbase ------------------------------*/
533 info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
534 if (info->me4000_regbase == 0) {
535 printk(KERN_ERR
536 "comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
537 dev->minor);
538 return -ENODEV;
540 info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
542 /*--------------------------- timer regbase ------------------------------*/
544 info->timer_regbase = pci_resource_start(pci_dev_p, 3);
545 if (info->timer_regbase == 0) {
546 printk(KERN_ERR
547 "comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
548 dev->minor);
549 return -ENODEV;
551 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
553 /*--------------------------- program regbase ------------------------------*/
555 info->program_regbase = pci_resource_start(pci_dev_p, 5);
556 if (info->program_regbase == 0) {
557 printk(KERN_ERR
558 "comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
559 dev->minor);
560 return -ENODEV;
562 info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
564 return 0;
567 static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
569 int result;
571 CALL_PDEBUG("In init_board_info()\n");
573 /* Init spin locks */
574 //spin_lock_init(&info->preload_lock);
575 //spin_lock_init(&info->ai_ctrl_lock);
577 /* Get the serial number */
578 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
579 if (result != PCIBIOS_SUCCESSFUL) {
580 return result;
583 /* Get the hardware revision */
584 result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
585 if (result != PCIBIOS_SUCCESSFUL) {
586 return result;
589 /* Get the vendor id */
590 info->vendor_id = pci_dev_p->vendor;
592 /* Get the device id */
593 info->device_id = pci_dev_p->device;
595 /* Get the irq assigned to the board */
596 info->irq = pci_dev_p->irq;
598 return 0;
601 static int init_ao_context(comedi_device * dev)
603 int i;
605 CALL_PDEBUG("In init_ao_context()\n");
607 for (i = 0; i < thisboard->ao.count; i++) {
608 //spin_lock_init(&info->ao_context[i].use_lock);
609 info->ao_context[i].irq = info->irq;
611 switch (i) {
612 case 0:
613 info->ao_context[i].ctrl_reg =
614 info->me4000_regbase + ME4000_AO_00_CTRL_REG;
615 info->ao_context[i].status_reg =
616 info->me4000_regbase + ME4000_AO_00_STATUS_REG;
617 info->ao_context[i].fifo_reg =
618 info->me4000_regbase + ME4000_AO_00_FIFO_REG;
619 info->ao_context[i].single_reg =
620 info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
621 info->ao_context[i].timer_reg =
622 info->me4000_regbase + ME4000_AO_00_TIMER_REG;
623 info->ao_context[i].irq_status_reg =
624 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
625 info->ao_context[i].preload_reg =
626 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
627 break;
628 case 1:
629 info->ao_context[i].ctrl_reg =
630 info->me4000_regbase + ME4000_AO_01_CTRL_REG;
631 info->ao_context[i].status_reg =
632 info->me4000_regbase + ME4000_AO_01_STATUS_REG;
633 info->ao_context[i].fifo_reg =
634 info->me4000_regbase + ME4000_AO_01_FIFO_REG;
635 info->ao_context[i].single_reg =
636 info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
637 info->ao_context[i].timer_reg =
638 info->me4000_regbase + ME4000_AO_01_TIMER_REG;
639 info->ao_context[i].irq_status_reg =
640 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
641 info->ao_context[i].preload_reg =
642 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
643 break;
644 case 2:
645 info->ao_context[i].ctrl_reg =
646 info->me4000_regbase + ME4000_AO_02_CTRL_REG;
647 info->ao_context[i].status_reg =
648 info->me4000_regbase + ME4000_AO_02_STATUS_REG;
649 info->ao_context[i].fifo_reg =
650 info->me4000_regbase + ME4000_AO_02_FIFO_REG;
651 info->ao_context[i].single_reg =
652 info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
653 info->ao_context[i].timer_reg =
654 info->me4000_regbase + ME4000_AO_02_TIMER_REG;
655 info->ao_context[i].irq_status_reg =
656 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
657 info->ao_context[i].preload_reg =
658 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
659 break;
660 case 3:
661 info->ao_context[i].ctrl_reg =
662 info->me4000_regbase + ME4000_AO_03_CTRL_REG;
663 info->ao_context[i].status_reg =
664 info->me4000_regbase + ME4000_AO_03_STATUS_REG;
665 info->ao_context[i].fifo_reg =
666 info->me4000_regbase + ME4000_AO_03_FIFO_REG;
667 info->ao_context[i].single_reg =
668 info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
669 info->ao_context[i].timer_reg =
670 info->me4000_regbase + ME4000_AO_03_TIMER_REG;
671 info->ao_context[i].irq_status_reg =
672 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
673 info->ao_context[i].preload_reg =
674 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
675 break;
676 default:
677 break;
681 return 0;
684 static int init_ai_context(comedi_device * dev)
687 CALL_PDEBUG("In init_ai_context()\n");
689 info->ai_context.irq = info->irq;
691 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
692 info->ai_context.status_reg =
693 info->me4000_regbase + ME4000_AI_STATUS_REG;
694 info->ai_context.channel_list_reg =
695 info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
696 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
697 info->ai_context.chan_timer_reg =
698 info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
699 info->ai_context.chan_pre_timer_reg =
700 info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
701 info->ai_context.scan_timer_low_reg =
702 info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
703 info->ai_context.scan_timer_high_reg =
704 info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
705 info->ai_context.scan_pre_timer_low_reg =
706 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
707 info->ai_context.scan_pre_timer_high_reg =
708 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
709 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
710 info->ai_context.irq_status_reg =
711 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
712 info->ai_context.sample_counter_reg =
713 info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
715 return 0;
718 static int init_dio_context(comedi_device * dev)
721 CALL_PDEBUG("In init_dio_context()\n");
723 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
724 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
725 info->dio_context.port_0_reg =
726 info->me4000_regbase + ME4000_DIO_PORT_0_REG;
727 info->dio_context.port_1_reg =
728 info->me4000_regbase + ME4000_DIO_PORT_1_REG;
729 info->dio_context.port_2_reg =
730 info->me4000_regbase + ME4000_DIO_PORT_2_REG;
731 info->dio_context.port_3_reg =
732 info->me4000_regbase + ME4000_DIO_PORT_3_REG;
734 return 0;
737 static int init_cnt_context(comedi_device * dev)
740 CALL_PDEBUG("In init_cnt_context()\n");
742 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
743 info->cnt_context.counter_0_reg =
744 info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
745 info->cnt_context.counter_1_reg =
746 info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
747 info->cnt_context.counter_2_reg =
748 info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
750 return 0;
753 #define FIRMWARE_NOT_AVAILABLE 1
754 #if FIRMWARE_NOT_AVAILABLE
755 extern unsigned char *xilinx_firm;
756 #endif
758 static int xilinx_download(comedi_device * dev)
760 u32 value = 0;
761 wait_queue_head_t queue;
762 int idx = 0;
763 int size = 0;
765 CALL_PDEBUG("In xilinx_download()\n");
767 init_waitqueue_head(&queue);
770 * Set PLX local interrupt 2 polarity to high.
771 * Interrupt is thrown by init pin of xilinx.
773 outl(0x10, info->plx_regbase + PLX_INTCSR);
775 /* Set /CS and /WRITE of the Xilinx */
776 value = inl(info->plx_regbase + PLX_ICR);
777 value |= 0x100;
778 outl(value, info->plx_regbase + PLX_ICR);
780 /* Init Xilinx with CS1 */
781 inb(info->program_regbase + 0xC8);
783 /* Wait until /INIT pin is set */
784 udelay(20);
785 if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
786 printk(KERN_ERR
787 "comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
788 dev->minor);
789 return -EIO;
792 /* Reset /CS and /WRITE of the Xilinx */
793 value = inl(info->plx_regbase + PLX_ICR);
794 value &= ~0x100;
795 outl(value, info->plx_regbase + PLX_ICR);
796 if (FIRMWARE_NOT_AVAILABLE) {
797 comedi_error(dev,
798 "xilinx firmware unavailable due to licensing, aborting");
799 return -EIO;
800 } else {
801 /* Download Xilinx firmware */
802 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
803 (xilinx_firm[2] << 8) + xilinx_firm[3];
804 udelay(10);
806 for (idx = 0; idx < size; idx++) {
807 outb(xilinx_firm[16 + idx], info->program_regbase);
808 udelay(10);
810 /* Check if BUSY flag is low */
811 if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
812 printk(KERN_ERR
813 "comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
814 dev->minor, idx);
815 return -EIO;
820 /* If done flag is high download was successful */
821 if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
822 } else {
823 printk(KERN_ERR
824 "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
825 dev->minor);
826 printk(KERN_ERR
827 "comedi%d: me4000: xilinx_download(): Download not succesful\n",
828 dev->minor);
829 return -EIO;
832 /* Set /CS and /WRITE */
833 value = inl(info->plx_regbase + PLX_ICR);
834 value |= 0x100;
835 outl(value, info->plx_regbase + PLX_ICR);
837 return 0;
840 static int reset_board(comedi_device * dev)
842 unsigned long icr;
844 CALL_PDEBUG("In reset_board()\n");
846 /* Make a hardware reset */
847 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
848 icr |= 0x40000000;
849 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
850 icr &= ~0x40000000;
851 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
853 /* 0x8000 to the DACs means an output voltage of 0V */
854 me4000_outl(dev, 0x8000,
855 info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
856 me4000_outl(dev, 0x8000,
857 info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
858 me4000_outl(dev, 0x8000,
859 info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
860 me4000_outl(dev, 0x8000,
861 info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
863 /* Set both stop bits in the analog input control register */
864 me4000_outl(dev,
865 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
866 info->me4000_regbase + ME4000_AI_CTRL_REG);
868 /* Set both stop bits in the analog output control register */
869 me4000_outl(dev,
870 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
871 info->me4000_regbase + ME4000_AO_00_CTRL_REG);
872 me4000_outl(dev,
873 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
874 info->me4000_regbase + ME4000_AO_01_CTRL_REG);
875 me4000_outl(dev,
876 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
877 info->me4000_regbase + ME4000_AO_02_CTRL_REG);
878 me4000_outl(dev,
879 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
880 info->me4000_regbase + ME4000_AO_03_CTRL_REG);
882 /* Enable interrupts on the PLX */
883 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
885 /* Set the adustment register for AO demux */
886 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
887 info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
889 /* Set digital I/O direction for port 0 to output on isolated versions */
890 if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
891 me4000_outl(dev, 0x1,
892 info->me4000_regbase + ME4000_DIO_CTRL_REG);
895 return 0;
898 static int me4000_detach(comedi_device * dev)
900 CALL_PDEBUG("In me4000_detach()\n");
902 if (info) {
903 if (info->pci_dev_p) {
904 reset_board(dev);
905 if (info->plx_regbase) {
906 comedi_pci_disable(info->pci_dev_p);
908 pci_dev_put(info->pci_dev_p);
912 return 0;
915 /*=============================================================================
916 Analog input section
917 ===========================================================================*/
919 static int me4000_ai_insn_read(comedi_device * dev,
920 comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data)
923 int chan = CR_CHAN(insn->chanspec);
924 int rang = CR_RANGE(insn->chanspec);
925 int aref = CR_AREF(insn->chanspec);
927 unsigned long entry = 0;
928 unsigned long tmp;
929 long lval;
931 CALL_PDEBUG("In me4000_ai_insn_read()\n");
933 if (insn->n == 0) {
934 return 0;
935 } else if (insn->n > 1) {
936 printk(KERN_ERR
937 "comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
938 dev->minor, insn->n);
939 return -EINVAL;
942 switch (rang) {
943 case 0:
944 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
945 break;
946 case 1:
947 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
948 break;
949 case 2:
950 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
951 break;
952 case 3:
953 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
954 break;
955 default:
956 printk(KERN_ERR
957 "comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
958 dev->minor);
959 return -EINVAL;
962 switch (aref) {
963 case AREF_GROUND:
964 case AREF_COMMON:
965 if (chan >= thisboard->ai.count) {
966 printk(KERN_ERR
967 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
968 dev->minor);
969 return -EINVAL;
971 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
972 break;
974 case AREF_DIFF:
975 if (rang == 0 || rang == 1) {
976 printk(KERN_ERR
977 "comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
978 dev->minor);
979 return -EINVAL;
982 if (chan >= thisboard->ai.diff_count) {
983 printk(KERN_ERR
984 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
985 dev->minor);
986 return -EINVAL;
988 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
989 break;
990 default:
991 printk(KERN_ERR
992 "comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
993 dev->minor);
994 return -EINVAL;
997 entry |= ME4000_AI_LIST_LAST_ENTRY;
999 /* Clear channel list, data fifo and both stop bits */
1000 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1001 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1002 ME4000_AI_CTRL_BIT_DATA_FIFO |
1003 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1004 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1006 /* Set the acquisition mode to single */
1007 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
1008 ME4000_AI_CTRL_BIT_MODE_2);
1009 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1011 /* Enable channel list and data fifo */
1012 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
1013 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1015 /* Generate channel list entry */
1016 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1018 /* Set the timer to maximum sample rate */
1019 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
1020 me4000_outl(dev, ME4000_AI_MIN_TICKS,
1021 info->ai_context.chan_pre_timer_reg);
1023 /* Start conversion by dummy read */
1024 me4000_inl(dev, info->ai_context.start_reg);
1026 /* Wait until ready */
1027 udelay(10);
1028 if (!(me4000_inl(dev, info->ai_context.
1029 status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) {
1030 printk(KERN_ERR
1031 "comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
1032 dev->minor);
1033 return -EIO;
1036 /* Read value from data fifo */
1037 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
1038 data[0] = lval ^ 0x8000;
1040 return 1;
1043 static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
1045 unsigned long tmp;
1047 CALL_PDEBUG("In me4000_ai_cancel()\n");
1049 /* Stop any running conversion */
1050 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1051 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1052 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1054 /* Clear the control register */
1055 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1057 return 0;
1060 static int ai_check_chanlist(comedi_device * dev,
1061 comedi_subdevice * s, comedi_cmd * cmd)
1063 int aref;
1064 int i;
1066 CALL_PDEBUG("In ai_check_chanlist()\n");
1068 /* Check whether a channel list is available */
1069 if (!cmd->chanlist_len) {
1070 printk(KERN_ERR
1071 "comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
1072 dev->minor);
1073 return -EINVAL;
1076 /* Check the channel list size */
1077 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
1078 printk(KERN_ERR
1079 "comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
1080 dev->minor);
1081 return -EINVAL;
1084 /* Check the pointer */
1085 if (!cmd->chanlist) {
1086 printk(KERN_ERR
1087 "comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
1088 dev->minor);
1089 return -EFAULT;
1092 /* Check whether aref is equal for all entries */
1093 aref = CR_AREF(cmd->chanlist[0]);
1094 for (i = 0; i < cmd->chanlist_len; i++) {
1095 if (CR_AREF(cmd->chanlist[i]) != aref) {
1096 printk(KERN_ERR
1097 "comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
1098 dev->minor);
1099 return -EINVAL;
1103 /* Check whether channels are available for this ending */
1104 if (aref == SDF_DIFF) {
1105 for (i = 0; i < cmd->chanlist_len; i++) {
1106 if (CR_CHAN(cmd->chanlist[i]) >=
1107 thisboard->ai.diff_count) {
1108 printk(KERN_ERR
1109 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1110 dev->minor);
1111 return -EINVAL;
1114 } else {
1115 for (i = 0; i < cmd->chanlist_len; i++) {
1116 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
1117 printk(KERN_ERR
1118 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1119 dev->minor);
1120 return -EINVAL;
1125 /* Check if bipolar is set for all entries when in differential mode */
1126 if (aref == SDF_DIFF) {
1127 for (i = 0; i < cmd->chanlist_len; i++) {
1128 if (CR_RANGE(cmd->chanlist[i]) != 1 &&
1129 CR_RANGE(cmd->chanlist[i]) != 2) {
1130 printk(KERN_ERR
1131 "comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
1132 dev->minor);
1133 return -EINVAL;
1138 return 0;
1141 static int ai_round_cmd_args(comedi_device * dev,
1142 comedi_subdevice * s,
1143 comedi_cmd * cmd,
1144 unsigned int *init_ticks,
1145 unsigned int *scan_ticks, unsigned int *chan_ticks)
1148 int rest;
1150 CALL_PDEBUG("In ai_round_cmd_args()\n");
1152 *init_ticks = 0;
1153 *scan_ticks = 0;
1154 *chan_ticks = 0;
1156 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1157 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1158 cmd->scan_begin_arg);
1159 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1161 if (cmd->start_arg) {
1162 *init_ticks = (cmd->start_arg * 33) / 1000;
1163 rest = (cmd->start_arg * 33) % 1000;
1165 if (cmd->flags & TRIG_ROUND_NEAREST) {
1166 if (rest > 33) {
1167 (*init_ticks)++;
1169 } else if (cmd->flags & TRIG_ROUND_UP) {
1170 if (rest)
1171 (*init_ticks)++;
1175 if (cmd->scan_begin_arg) {
1176 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1177 rest = (cmd->scan_begin_arg * 33) % 1000;
1179 if (cmd->flags & TRIG_ROUND_NEAREST) {
1180 if (rest > 33) {
1181 (*scan_ticks)++;
1183 } else if (cmd->flags & TRIG_ROUND_UP) {
1184 if (rest)
1185 (*scan_ticks)++;
1189 if (cmd->convert_arg) {
1190 *chan_ticks = (cmd->convert_arg * 33) / 1000;
1191 rest = (cmd->convert_arg * 33) % 1000;
1193 if (cmd->flags & TRIG_ROUND_NEAREST) {
1194 if (rest > 33) {
1195 (*chan_ticks)++;
1197 } else if (cmd->flags & TRIG_ROUND_UP) {
1198 if (rest)
1199 (*chan_ticks)++;
1203 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1204 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1205 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1207 return 0;
1210 static void ai_write_timer(comedi_device * dev,
1211 unsigned int init_ticks,
1212 unsigned int scan_ticks, unsigned int chan_ticks)
1215 CALL_PDEBUG("In ai_write_timer()\n");
1217 me4000_outl(dev, init_ticks - 1,
1218 info->ai_context.scan_pre_timer_low_reg);
1219 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1221 if (scan_ticks) {
1222 me4000_outl(dev, scan_ticks - 1,
1223 info->ai_context.scan_timer_low_reg);
1224 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1227 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1228 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1231 static int ai_prepare(comedi_device * dev,
1232 comedi_subdevice * s,
1233 comedi_cmd * cmd,
1234 unsigned int init_ticks,
1235 unsigned int scan_ticks, unsigned int chan_ticks)
1238 unsigned long tmp = 0;
1240 CALL_PDEBUG("In ai_prepare()\n");
1242 /* Write timer arguments */
1243 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1245 /* Reset control register */
1246 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1248 /* Start sources */
1249 if ((cmd->start_src == TRIG_EXT &&
1250 cmd->scan_begin_src == TRIG_TIMER &&
1251 cmd->convert_src == TRIG_TIMER) ||
1252 (cmd->start_src == TRIG_EXT &&
1253 cmd->scan_begin_src == TRIG_FOLLOW &&
1254 cmd->convert_src == TRIG_TIMER)) {
1255 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
1256 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1257 ME4000_AI_CTRL_BIT_DATA_FIFO;
1258 } else if (cmd->start_src == TRIG_EXT &&
1259 cmd->scan_begin_src == TRIG_EXT &&
1260 cmd->convert_src == TRIG_TIMER) {
1261 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
1262 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1263 ME4000_AI_CTRL_BIT_DATA_FIFO;
1264 } else if (cmd->start_src == TRIG_EXT &&
1265 cmd->scan_begin_src == TRIG_EXT &&
1266 cmd->convert_src == TRIG_EXT) {
1267 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1268 ME4000_AI_CTRL_BIT_MODE_1 |
1269 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1270 ME4000_AI_CTRL_BIT_DATA_FIFO;
1271 } else {
1272 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1273 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1274 ME4000_AI_CTRL_BIT_DATA_FIFO;
1277 /* Stop triggers */
1278 if (cmd->stop_src == TRIG_COUNT) {
1279 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
1280 info->ai_context.sample_counter_reg);
1281 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1282 } else if (cmd->stop_src == TRIG_NONE &&
1283 cmd->scan_end_src == TRIG_COUNT) {
1284 me4000_outl(dev, cmd->scan_end_arg,
1285 info->ai_context.sample_counter_reg);
1286 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1287 } else {
1288 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1291 /* Write the setup to the control register */
1292 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1294 /* Write the channel list */
1295 ai_write_chanlist(dev, s, cmd);
1297 return 0;
1300 static int ai_write_chanlist(comedi_device * dev,
1301 comedi_subdevice * s, comedi_cmd * cmd)
1303 unsigned int entry;
1304 unsigned int chan;
1305 unsigned int rang;
1306 unsigned int aref;
1307 int i;
1309 CALL_PDEBUG("In ai_write_chanlist()\n");
1311 for (i = 0; i < cmd->chanlist_len; i++) {
1312 chan = CR_CHAN(cmd->chanlist[i]);
1313 rang = CR_RANGE(cmd->chanlist[i]);
1314 aref = CR_AREF(cmd->chanlist[i]);
1316 entry = chan;
1318 if (rang == 0) {
1319 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1320 } else if (rang == 1) {
1321 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1322 } else if (rang == 2) {
1323 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1324 } else {
1325 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1328 if (aref == SDF_DIFF) {
1329 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1330 } else {
1331 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1334 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1337 return 0;
1340 static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
1342 int err;
1343 unsigned int init_ticks = 0;
1344 unsigned int scan_ticks = 0;
1345 unsigned int chan_ticks = 0;
1346 comedi_cmd *cmd = &s->async->cmd;
1348 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1350 /* Reset the analog input */
1351 err = me4000_ai_cancel(dev, s);
1352 if (err)
1353 return err;
1355 /* Round the timer arguments */
1356 err = ai_round_cmd_args(dev,
1357 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1358 if (err)
1359 return err;
1361 /* Prepare the AI for acquisition */
1362 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
1363 if (err)
1364 return err;
1366 /* Start acquistion by dummy read */
1367 me4000_inl(dev, info->ai_context.start_reg);
1369 return 0;
1373 * me4000_ai_do_cmd_test():
1375 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1376 * - success
1377 * - invalid source
1378 * - source conflict
1379 * - invalid argument
1380 * - argument conflict
1381 * - invalid chanlist
1382 * So I tried to adopt this scheme.
1384 static int me4000_ai_do_cmd_test(comedi_device * dev,
1385 comedi_subdevice * s, comedi_cmd * cmd)
1388 unsigned int init_ticks;
1389 unsigned int chan_ticks;
1390 unsigned int scan_ticks;
1391 int err = 0;
1393 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1395 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev);
1396 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags);
1397 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n",
1398 cmd->start_src);
1399 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n",
1400 cmd->start_arg);
1401 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1402 cmd->scan_begin_src);
1403 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1404 cmd->scan_begin_arg);
1405 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n",
1406 cmd->convert_src);
1407 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n",
1408 cmd->convert_arg);
1409 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n",
1410 cmd->scan_end_src);
1411 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n",
1412 cmd->scan_end_arg);
1413 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n",
1414 cmd->stop_src);
1415 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg);
1416 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n",
1417 (unsigned int)cmd->chanlist);
1418 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n",
1419 cmd->chanlist_len);
1421 /* Only rounding flags are implemented */
1422 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1424 /* Round the timer arguments */
1425 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1428 * Stage 1. Check if the trigger sources are generally valid.
1430 switch (cmd->start_src) {
1431 case TRIG_NOW:
1432 case TRIG_EXT:
1433 break;
1434 case TRIG_ANY:
1435 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1436 err++;
1437 break;
1438 default:
1439 printk(KERN_ERR
1440 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
1441 dev->minor);
1442 cmd->start_src = TRIG_NOW;
1443 err++;
1445 switch (cmd->scan_begin_src) {
1446 case TRIG_FOLLOW:
1447 case TRIG_TIMER:
1448 case TRIG_EXT:
1449 break;
1450 case TRIG_ANY:
1451 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1452 err++;
1453 break;
1454 default:
1455 printk(KERN_ERR
1456 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
1457 dev->minor);
1458 cmd->scan_begin_src = TRIG_FOLLOW;
1459 err++;
1461 switch (cmd->convert_src) {
1462 case TRIG_TIMER:
1463 case TRIG_EXT:
1464 break;
1465 case TRIG_ANY:
1466 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1467 err++;
1468 break;
1469 default:
1470 printk(KERN_ERR
1471 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
1472 dev->minor);
1473 cmd->convert_src = TRIG_TIMER;
1474 err++;
1476 switch (cmd->scan_end_src) {
1477 case TRIG_NONE:
1478 case TRIG_COUNT:
1479 break;
1480 case TRIG_ANY:
1481 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1482 err++;
1483 break;
1484 default:
1485 printk(KERN_ERR
1486 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
1487 dev->minor);
1488 cmd->scan_end_src = TRIG_NONE;
1489 err++;
1491 switch (cmd->stop_src) {
1492 case TRIG_NONE:
1493 case TRIG_COUNT:
1494 break;
1495 case TRIG_ANY:
1496 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1497 err++;
1498 break;
1499 default:
1500 printk(KERN_ERR
1501 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
1502 dev->minor);
1503 cmd->stop_src = TRIG_NONE;
1504 err++;
1506 if (err) {
1507 return 1;
1511 * Stage 2. Check for trigger source conflicts.
1513 if (cmd->start_src == TRIG_NOW &&
1514 cmd->scan_begin_src == TRIG_TIMER &&
1515 cmd->convert_src == TRIG_TIMER) {
1516 } else if (cmd->start_src == TRIG_NOW &&
1517 cmd->scan_begin_src == TRIG_FOLLOW &&
1518 cmd->convert_src == TRIG_TIMER) {
1519 } else if (cmd->start_src == TRIG_EXT &&
1520 cmd->scan_begin_src == TRIG_TIMER &&
1521 cmd->convert_src == TRIG_TIMER) {
1522 } else if (cmd->start_src == TRIG_EXT &&
1523 cmd->scan_begin_src == TRIG_FOLLOW &&
1524 cmd->convert_src == TRIG_TIMER) {
1525 } else if (cmd->start_src == TRIG_EXT &&
1526 cmd->scan_begin_src == TRIG_EXT &&
1527 cmd->convert_src == TRIG_TIMER) {
1528 } else if (cmd->start_src == TRIG_EXT &&
1529 cmd->scan_begin_src == TRIG_EXT &&
1530 cmd->convert_src == TRIG_EXT) {
1531 } else {
1532 printk(KERN_ERR
1533 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
1534 dev->minor);
1535 cmd->start_src = TRIG_NOW;
1536 cmd->scan_begin_src = TRIG_FOLLOW;
1537 cmd->convert_src = TRIG_TIMER;
1538 err++;
1541 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
1542 } else if (cmd->stop_src == TRIG_COUNT &&
1543 cmd->scan_end_src == TRIG_NONE) {
1544 } else if (cmd->stop_src == TRIG_NONE &&
1545 cmd->scan_end_src == TRIG_COUNT) {
1546 } else if (cmd->stop_src == TRIG_COUNT &&
1547 cmd->scan_end_src == TRIG_COUNT) {
1548 } else {
1549 printk(KERN_ERR
1550 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
1551 dev->minor);
1552 cmd->stop_src = TRIG_NONE;
1553 cmd->scan_end_src = TRIG_NONE;
1554 err++;
1556 if (err) {
1557 return 2;
1561 * Stage 3. Check if arguments are generally valid.
1563 if (cmd->chanlist_len < 1) {
1564 printk(KERN_ERR
1565 "comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
1566 dev->minor);
1567 cmd->chanlist_len = 1;
1568 err++;
1570 if (init_ticks < 66) {
1571 printk(KERN_ERR
1572 "comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
1573 dev->minor);
1574 cmd->start_arg = 2000;
1575 err++;
1577 if (scan_ticks && scan_ticks < 67) {
1578 printk(KERN_ERR
1579 "comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
1580 dev->minor);
1581 cmd->scan_begin_arg = 2031;
1582 err++;
1584 if (chan_ticks < 66) {
1585 printk(KERN_ERR
1586 "comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
1587 dev->minor);
1588 cmd->convert_arg = 2000;
1589 err++;
1591 if (err) {
1592 return 3;
1596 * Stage 4. Check for argument conflicts.
1598 if (cmd->start_src == TRIG_NOW &&
1599 cmd->scan_begin_src == TRIG_TIMER &&
1600 cmd->convert_src == TRIG_TIMER) {
1602 /* Check timer arguments */
1603 if (init_ticks < ME4000_AI_MIN_TICKS) {
1604 printk(KERN_ERR
1605 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1606 dev->minor);
1607 cmd->start_arg = 2000; // 66 ticks at least
1608 err++;
1610 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1611 printk(KERN_ERR
1612 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1613 dev->minor);
1614 cmd->convert_arg = 2000; // 66 ticks at least
1615 err++;
1617 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1618 printk(KERN_ERR
1619 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1620 dev->minor);
1621 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
1622 err++;
1624 } else if (cmd->start_src == TRIG_NOW &&
1625 cmd->scan_begin_src == TRIG_FOLLOW &&
1626 cmd->convert_src == TRIG_TIMER) {
1628 /* Check timer arguments */
1629 if (init_ticks < ME4000_AI_MIN_TICKS) {
1630 printk(KERN_ERR
1631 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1632 dev->minor);
1633 cmd->start_arg = 2000; // 66 ticks at least
1634 err++;
1636 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1637 printk(KERN_ERR
1638 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1639 dev->minor);
1640 cmd->convert_arg = 2000; // 66 ticks at least
1641 err++;
1643 } else if (cmd->start_src == TRIG_EXT &&
1644 cmd->scan_begin_src == TRIG_TIMER &&
1645 cmd->convert_src == TRIG_TIMER) {
1647 /* Check timer arguments */
1648 if (init_ticks < ME4000_AI_MIN_TICKS) {
1649 printk(KERN_ERR
1650 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1651 dev->minor);
1652 cmd->start_arg = 2000; // 66 ticks at least
1653 err++;
1655 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1656 printk(KERN_ERR
1657 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1658 dev->minor);
1659 cmd->convert_arg = 2000; // 66 ticks at least
1660 err++;
1662 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1663 printk(KERN_ERR
1664 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1665 dev->minor);
1666 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
1667 err++;
1669 } else if (cmd->start_src == TRIG_EXT &&
1670 cmd->scan_begin_src == TRIG_FOLLOW &&
1671 cmd->convert_src == TRIG_TIMER) {
1673 /* Check timer arguments */
1674 if (init_ticks < ME4000_AI_MIN_TICKS) {
1675 printk(KERN_ERR
1676 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1677 dev->minor);
1678 cmd->start_arg = 2000; // 66 ticks at least
1679 err++;
1681 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1682 printk(KERN_ERR
1683 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1684 dev->minor);
1685 cmd->convert_arg = 2000; // 66 ticks at least
1686 err++;
1688 } else if (cmd->start_src == TRIG_EXT &&
1689 cmd->scan_begin_src == TRIG_EXT &&
1690 cmd->convert_src == TRIG_TIMER) {
1692 /* Check timer arguments */
1693 if (init_ticks < ME4000_AI_MIN_TICKS) {
1694 printk(KERN_ERR
1695 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1696 dev->minor);
1697 cmd->start_arg = 2000; // 66 ticks at least
1698 err++;
1700 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1701 printk(KERN_ERR
1702 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1703 dev->minor);
1704 cmd->convert_arg = 2000; // 66 ticks at least
1705 err++;
1707 } else if (cmd->start_src == TRIG_EXT &&
1708 cmd->scan_begin_src == TRIG_EXT &&
1709 cmd->convert_src == TRIG_EXT) {
1711 /* Check timer arguments */
1712 if (init_ticks < ME4000_AI_MIN_TICKS) {
1713 printk(KERN_ERR
1714 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1715 dev->minor);
1716 cmd->start_arg = 2000; // 66 ticks at least
1717 err++;
1720 if (cmd->stop_src == TRIG_COUNT) {
1721 if (cmd->stop_arg == 0) {
1722 printk(KERN_ERR
1723 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
1724 dev->minor);
1725 cmd->stop_arg = 1;
1726 err++;
1729 if (cmd->scan_end_src == TRIG_COUNT) {
1730 if (cmd->scan_end_arg == 0) {
1731 printk(KERN_ERR
1732 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1733 dev->minor);
1734 cmd->scan_end_arg = 1;
1735 err++;
1738 if (err) {
1739 return 4;
1743 * Stage 5. Check the channel list.
1745 if (ai_check_chanlist(dev, s, cmd))
1746 return 5;
1748 return 0;
1751 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
1753 unsigned int tmp;
1754 comedi_device *dev = dev_id;
1755 comedi_subdevice *s = dev->subdevices;
1756 me4000_ai_context_t *ai_context = &info->ai_context;
1757 int i;
1758 int c = 0;
1759 long lval;
1761 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1763 if (!dev->attached) {
1764 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1765 return IRQ_NONE;
1768 /* Reset all events */
1769 s->async->events = 0;
1771 /* Check if irq number is right */
1772 if (irq != ai_context->irq) {
1773 printk(KERN_ERR
1774 "comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
1775 dev->minor, irq);
1776 return IRQ_HANDLED;
1779 if (me4000_inl(dev,
1780 ai_context->
1781 irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) {
1782 ISR_PDEBUG
1783 ("me4000_ai_isr(): Fifo half full interrupt occured\n");
1785 /* Read status register to find out what happened */
1786 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1788 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1789 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1790 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1791 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1792 c = ME4000_AI_FIFO_COUNT;
1794 /* FIFO overflow, so stop conversion and disable all interrupts */
1795 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1796 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1797 ME4000_AI_CTRL_BIT_SC_IRQ);
1798 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1800 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1802 printk(KERN_ERR
1803 "comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
1804 dev->minor);
1805 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1806 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1807 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1808 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1810 s->async->events |= COMEDI_CB_BLOCK;
1812 c = ME4000_AI_FIFO_COUNT / 2;
1813 } else {
1814 printk(KERN_ERR
1815 "comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
1816 dev->minor);
1817 c = 0;
1819 /* Undefined state, so stop conversion and disable all interrupts */
1820 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1821 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1822 ME4000_AI_CTRL_BIT_SC_IRQ);
1823 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1825 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1827 printk(KERN_ERR
1828 "comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
1829 dev->minor);
1832 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1834 for (i = 0; i < c; i++) {
1835 /* Read value from data fifo */
1836 lval = inl(ai_context->data_reg) & 0xFFFF;
1837 lval ^= 0x8000;
1839 if (!comedi_buf_put(s->async, lval)) {
1840 /* Buffer overflow, so stop conversion and disable all interrupts */
1841 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1842 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1843 ME4000_AI_CTRL_BIT_SC_IRQ);
1844 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1846 s->async->events |= COMEDI_CB_OVERFLOW;
1848 printk(KERN_ERR
1849 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1850 dev->minor);
1852 break;
1856 /* Work is done, so reset the interrupt */
1857 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1858 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1859 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1860 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1861 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1864 if (me4000_inl(dev,
1865 ai_context->
1866 irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
1867 ISR_PDEBUG
1868 ("me4000_ai_isr(): Sample counter interrupt occured\n");
1870 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1872 /* Acquisition is complete, so stop conversion and disable all interrupts */
1873 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1874 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1875 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1876 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1878 /* Poll data until fifo empty */
1879 while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
1880 /* Read value from data fifo */
1881 lval = inl(ai_context->data_reg) & 0xFFFF;
1882 lval ^= 0x8000;
1884 if (!comedi_buf_put(s->async, lval)) {
1885 printk(KERN_ERR
1886 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1887 dev->minor);
1888 s->async->events |= COMEDI_CB_OVERFLOW;
1889 break;
1893 /* Work is done, so reset the interrupt */
1894 ISR_PDEBUG
1895 ("me4000_ai_isr(): Reset interrupt from sample counter\n");
1896 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1897 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1898 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1899 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1902 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1904 if (s->async->events)
1905 comedi_event(dev, s);
1907 return IRQ_HANDLED;
1910 /*=============================================================================
1911 Analog output section
1912 ===========================================================================*/
1914 static int me4000_ao_insn_write(comedi_device * dev,
1915 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
1918 int chan = CR_CHAN(insn->chanspec);
1919 int rang = CR_RANGE(insn->chanspec);
1920 int aref = CR_AREF(insn->chanspec);
1921 unsigned long tmp;
1923 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1925 if (insn->n == 0) {
1926 return 0;
1927 } else if (insn->n > 1) {
1928 printk(KERN_ERR
1929 "comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
1930 dev->minor, insn->n);
1931 return -EINVAL;
1934 if (chan >= thisboard->ao.count) {
1935 printk(KERN_ERR
1936 "comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
1937 dev->minor, insn->n);
1938 return -EINVAL;
1941 if (rang != 0) {
1942 printk(KERN_ERR
1943 "comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
1944 dev->minor, insn->n);
1945 return -EINVAL;
1948 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1949 printk(KERN_ERR
1950 "comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
1951 dev->minor, insn->n);
1952 return -EINVAL;
1955 /* Stop any running conversion */
1956 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
1957 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1958 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
1960 /* Clear control register and set to single mode */
1961 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
1963 /* Write data value */
1964 me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
1966 /* Store in the mirror */
1967 info->ao_context[chan].mirror = data[0];
1969 return 1;
1972 static int me4000_ao_insn_read(comedi_device * dev,
1973 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
1975 int chan = CR_CHAN(insn->chanspec);
1977 if (insn->n == 0) {
1978 return 0;
1979 } else if (insn->n > 1) {
1980 printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
1981 return -EINVAL;
1984 data[0] = info->ao_context[chan].mirror;
1986 return 1;
1989 /*=============================================================================
1990 Digital I/O section
1991 ===========================================================================*/
1993 static int me4000_dio_insn_bits(comedi_device * dev,
1994 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
1997 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
1999 /* Length of data must be 2 (mask and new data, see below) */
2000 if (insn->n == 0) {
2001 return 0;
2003 if (insn->n != 2) {
2004 printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
2005 return -EINVAL;
2009 * The insn data consists of a mask in data[0] and the new data
2010 * in data[1]. The mask defines which bits we are concerning about.
2011 * The new data must be anded with the mask.
2012 * Each channel corresponds to a bit.
2014 if (data[0]) {
2015 /* Check if requested ports are configured for output */
2016 if ((s->io_bits & data[0]) != data[0])
2017 return -EIO;
2019 s->state &= ~data[0];
2020 s->state |= data[0] & data[1];
2022 /* Write out the new digital output lines */
2023 me4000_outl(dev, (s->state >> 0) & 0xFF,
2024 info->dio_context.port_0_reg);
2025 me4000_outl(dev, (s->state >> 8) & 0xFF,
2026 info->dio_context.port_1_reg);
2027 me4000_outl(dev, (s->state >> 16) & 0xFF,
2028 info->dio_context.port_2_reg);
2029 me4000_outl(dev, (s->state >> 24) & 0xFF,
2030 info->dio_context.port_3_reg);
2033 /* On return, data[1] contains the value of
2034 the digital input and output lines. */
2035 data[1] =
2036 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
2037 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
2038 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
2039 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
2041 return 2;
2044 static int me4000_dio_insn_config(comedi_device * dev,
2045 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
2047 unsigned long tmp;
2048 int chan = CR_CHAN(insn->chanspec);
2050 CALL_PDEBUG("In me4000_dio_insn_config()\n");
2052 if (data[0] == INSN_CONFIG_DIO_QUERY) {
2053 data[1] =
2054 (s->
2055 io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2056 return insn->n;
2060 * The input or output configuration of each digital line is
2061 * configured by a special insn_config instruction. chanspec
2062 * contains the channel to be changed, and data[0] contains the
2063 * value COMEDI_INPUT or COMEDI_OUTPUT.
2064 * On the ME-4000 it is only possible to switch port wise (8 bit)
2067 tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
2069 if (data[0] == COMEDI_OUTPUT) {
2070 if (chan < 8) {
2071 s->io_bits |= 0xFF;
2072 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2073 ME4000_DIO_CTRL_BIT_MODE_1);
2074 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
2075 } else if (chan < 16) {
2077 * Chech for optoisolated ME-4000 version. If one the first
2078 * port is a fixed output port and the second is a fixed input port.
2080 if (!me4000_inl(dev, info->dio_context.dir_reg))
2081 return -ENODEV;
2083 s->io_bits |= 0xFF00;
2084 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2085 ME4000_DIO_CTRL_BIT_MODE_3);
2086 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
2087 } else if (chan < 24) {
2088 s->io_bits |= 0xFF0000;
2089 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2090 ME4000_DIO_CTRL_BIT_MODE_5);
2091 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2092 } else if (chan < 32) {
2093 s->io_bits |= 0xFF000000;
2094 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2095 ME4000_DIO_CTRL_BIT_MODE_7);
2096 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2097 } else {
2098 return -EINVAL;
2100 } else {
2101 if (chan < 8) {
2103 * Chech for optoisolated ME-4000 version. If one the first
2104 * port is a fixed output port and the second is a fixed input port.
2106 if (!me4000_inl(dev, info->dio_context.dir_reg))
2107 return -ENODEV;
2109 s->io_bits &= ~0xFF;
2110 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2111 ME4000_DIO_CTRL_BIT_MODE_1);
2112 } else if (chan < 16) {
2113 s->io_bits &= ~0xFF00;
2114 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2115 ME4000_DIO_CTRL_BIT_MODE_3);
2116 } else if (chan < 24) {
2117 s->io_bits &= ~0xFF0000;
2118 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2119 ME4000_DIO_CTRL_BIT_MODE_5);
2120 } else if (chan < 32) {
2121 s->io_bits &= ~0xFF000000;
2122 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2123 ME4000_DIO_CTRL_BIT_MODE_7);
2124 } else {
2125 return -EINVAL;
2129 me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2131 return 1;
2134 /*=============================================================================
2135 Counter section
2136 ===========================================================================*/
2138 static int cnt_reset(comedi_device * dev, unsigned int channel)
2141 CALL_PDEBUG("In cnt_reset()\n");
2143 switch (channel) {
2144 case 0:
2145 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2146 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2147 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2148 break;
2149 case 1:
2150 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2151 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2152 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2153 break;
2154 case 2:
2155 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2156 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2157 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2158 break;
2159 default:
2160 printk(KERN_ERR
2161 "comedi%d: me4000: cnt_reset(): Invalid channel\n",
2162 dev->minor);
2163 return -EINVAL;
2166 return 0;
2169 static int cnt_config(comedi_device * dev, unsigned int channel,
2170 unsigned int mode)
2172 int tmp = 0;
2174 CALL_PDEBUG("In cnt_config()\n");
2176 switch (channel) {
2177 case 0:
2178 tmp |= ME4000_CNT_COUNTER_0;
2179 break;
2180 case 1:
2181 tmp |= ME4000_CNT_COUNTER_1;
2182 break;
2183 case 2:
2184 tmp |= ME4000_CNT_COUNTER_2;
2185 break;
2186 default:
2187 printk(KERN_ERR
2188 "comedi%d: me4000: cnt_config(): Invalid channel\n",
2189 dev->minor);
2190 return -EINVAL;
2193 switch (mode) {
2194 case 0:
2195 tmp |= ME4000_CNT_MODE_0;
2196 break;
2197 case 1:
2198 tmp |= ME4000_CNT_MODE_1;
2199 break;
2200 case 2:
2201 tmp |= ME4000_CNT_MODE_2;
2202 break;
2203 case 3:
2204 tmp |= ME4000_CNT_MODE_3;
2205 break;
2206 case 4:
2207 tmp |= ME4000_CNT_MODE_4;
2208 break;
2209 case 5:
2210 tmp |= ME4000_CNT_MODE_5;
2211 break;
2212 default:
2213 printk(KERN_ERR
2214 "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2215 dev->minor);
2216 return -EINVAL;
2219 /* Write the control word */
2220 tmp |= 0x30;
2221 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2223 return 0;
2226 static int me4000_cnt_insn_config(comedi_device * dev,
2227 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
2230 int err;
2232 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2234 switch (data[0]) {
2235 case GPCT_RESET:
2236 if (insn->n != 1) {
2237 printk(KERN_ERR
2238 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2239 dev->minor, insn->n);
2240 return -EINVAL;
2243 err = cnt_reset(dev, insn->chanspec);
2244 if (err)
2245 return err;
2246 break;
2247 case GPCT_SET_OPERATION:
2248 if (insn->n != 2) {
2249 printk(KERN_ERR
2250 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2251 dev->minor, insn->n);
2252 return -EINVAL;
2255 err = cnt_config(dev, insn->chanspec, data[1]);
2256 if (err)
2257 return err;
2258 break;
2259 default:
2260 printk(KERN_ERR
2261 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
2262 dev->minor);
2263 return -EINVAL;
2266 return 2;
2269 static int me4000_cnt_insn_read(comedi_device * dev,
2270 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
2273 unsigned short tmp;
2275 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2277 if (insn->n == 0) {
2278 return 0;
2280 if (insn->n > 1) {
2281 printk(KERN_ERR
2282 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
2283 dev->minor, insn->n);
2284 return -EINVAL;
2287 switch (insn->chanspec) {
2288 case 0:
2289 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2290 data[0] = tmp;
2291 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2292 data[0] |= tmp << 8;
2293 break;
2294 case 1:
2295 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2296 data[0] = tmp;
2297 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2298 data[0] |= tmp << 8;
2299 break;
2300 case 2:
2301 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2302 data[0] = tmp;
2303 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2304 data[0] |= tmp << 8;
2305 break;
2306 default:
2307 printk(KERN_ERR
2308 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
2309 dev->minor, insn->chanspec);
2310 return -EINVAL;
2313 return 1;
2316 static int me4000_cnt_insn_write(comedi_device * dev,
2317 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
2320 unsigned short tmp;
2322 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2324 if (insn->n == 0) {
2325 return 0;
2326 } else if (insn->n > 1) {
2327 printk(KERN_ERR
2328 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
2329 dev->minor, insn->n);
2330 return -EINVAL;
2333 switch (insn->chanspec) {
2334 case 0:
2335 tmp = data[0] & 0xFF;
2336 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2337 tmp = (data[0] >> 8) & 0xFF;
2338 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2339 break;
2340 case 1:
2341 tmp = data[0] & 0xFF;
2342 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2343 tmp = (data[0] >> 8) & 0xFF;
2344 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2345 break;
2346 case 2:
2347 tmp = data[0] & 0xFF;
2348 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2349 tmp = (data[0] >> 8) & 0xFF;
2350 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2351 break;
2352 default:
2353 printk(KERN_ERR
2354 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
2355 dev->minor, insn->chanspec);
2356 return -EINVAL;
2359 return 1;
2362 COMEDI_PCI_INITCLEANUP(driver_me4000, me4000_pci_table);