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.
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)
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
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
54 #include <linux/comedidev.h>
56 #include <linux/pci.h>
57 #include <linux/delay.h>
58 #include <linux/list.h>
59 #include <linux/spinlock.h>
63 /* file removed due to GPL incompatibility */
64 #include "me4000_fw.h"
67 me4000_board_t me4000_boards[] = {
68 { "ME-4650" , 0x4650, { 0, 0 }, { 16, 0, 0, 0 }, { 4 }, { 0 } },
70 { "ME-4660" , 0x4660, { 0, 0 }, { 32, 0, 16, 0 }, { 4 }, { 3 } },
71 { "ME-4660i" , 0x4661, { 0, 0 }, { 32, 0, 16, 0 }, { 4 }, { 3 } },
72 { "ME-4660s" , 0x4662, { 0, 0 }, { 32, 8, 16, 0 }, { 4 }, { 3 } },
73 { "ME-4660is", 0x4663, { 0, 0 }, { 32, 8, 16, 0 }, { 4 }, { 3 } },
75 { "ME-4670" , 0x4670, { 4, 0 }, { 32, 0, 16, 1 }, { 4 }, { 3 } },
76 { "ME-4670i" , 0x4671, { 4, 0 }, { 32, 0, 16, 1 }, { 4 }, { 3 } },
77 { "ME-4670s" , 0x4672, { 4, 0 }, { 32, 8, 16, 1 }, { 4 }, { 3 } },
78 { "ME-4670is", 0x4673, { 4, 0 }, { 32, 8, 16, 1 }, { 4 }, { 3 } },
80 { "ME-4680" , 0x4680, { 4, 4 }, { 32, 0, 16, 1 }, { 4 }, { 3 } },
81 { "ME-4680i" , 0x4681, { 4, 4 }, { 32, 0, 16, 1 }, { 4 }, { 3 } },
82 { "ME-4680s" , 0x4682, { 4, 4 }, { 32, 8, 16, 1 }, { 4 }, { 3 } },
83 { "ME-4680is", 0x4683, { 4, 4 }, { 32, 8, 16, 1 }, { 4 }, { 3 } },
88 #define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
92 /*-----------------------------------------------------------------------------
93 Comedi function prototypes
94 ---------------------------------------------------------------------------*/
95 static int me4000_attach(comedi_device *dev, comedi_devconfig *it);
96 static int me4000_detach(comedi_device *dev);
97 static comedi_driver driver_me4000 = {
98 driver_name: "me4000",
100 attach: me4000_attach,
101 detach: me4000_detach,
106 /*-----------------------------------------------------------------------------
107 Meilhaus function prototypes
108 ---------------------------------------------------------------------------*/
109 static int me4000_probe(comedi_device *dev, comedi_devconfig *it);
110 static int get_registers(comedi_device *dev, struct pci_dev *pci_dev_p);
111 static int init_board_info(comedi_device *dev, struct pci_dev *pci_dev_p);
112 static int init_ao_context(comedi_device *dev);
113 static int init_ai_context(comedi_device *dev);
114 static int init_dio_context(comedi_device *dev);
115 static int init_cnt_context(comedi_device *dev);
116 static int xilinx_download(comedi_device *dev);
117 static int reset_board(comedi_device *dev);
119 static int me4000_dio_insn_bits(
125 static int me4000_dio_insn_config(
131 static int cnt_reset(comedi_device *dev, unsigned int channel);
133 static int cnt_config(
135 unsigned int channel,
138 static int me4000_cnt_insn_config(
144 static int me4000_cnt_insn_write(
150 static int me4000_cnt_insn_read(
156 static int me4000_ai_insn_read(
158 comedi_subdevice *subdevice,
162 static int me4000_ai_cancel(comedi_device *dev, comedi_subdevice *s);
164 static int ai_check_chanlist(
169 static int ai_round_cmd_args(
173 unsigned int *init_ticks,
174 unsigned int *scan_ticks,
175 unsigned int *chan_ticks);
177 static int ai_prepare(
181 unsigned int init_ticks,
182 unsigned int scan_ticks,
183 unsigned int chan_ticks);
185 static int ai_write_chanlist(
190 static irqreturn_t me4000_ai_isr(
195 static int me4000_ai_do_cmd_test(
200 static int me4000_ai_do_cmd(comedi_device *dev, comedi_subdevice *s);
202 static int me4000_ao_insn_write(
208 static int me4000_ao_insn_read(
210 comedi_subdevice * s,
215 /*-----------------------------------------------------------------------------
216 Meilhaus inline functions
217 ---------------------------------------------------------------------------*/
218 static void inline me4000_outb(comedi_device *dev, unsigned char value, unsigned long port);
219 static void inline me4000_outl(comedi_device *dev, unsigned long value, unsigned long port);
220 static unsigned long inline me4000_inl(comedi_device *dev, unsigned long port);
221 static unsigned char inline me4000_inb(comedi_device *dev, unsigned long port);
224 static void me4000_outb(comedi_device *dev, unsigned char value, unsigned long port){
225 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
229 static void me4000_outl(comedi_device *dev, unsigned long value, unsigned long port){
230 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
234 static unsigned long me4000_inl(comedi_device *dev, unsigned long port){
237 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
241 static unsigned char me4000_inb(comedi_device *dev, unsigned long port){
244 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
250 static comedi_lrange me4000_ai_range=
263 static comedi_lrange me4000_ao_range=
273 static int me4000_attach(comedi_device *dev, comedi_devconfig *it){
277 CALL_PDEBUG("In me4000_attach()\n");
279 result = me4000_probe(dev, it);
280 if(result) return result;
283 * Allocate the subdevice structures. alloc_subdevice() is a
284 * convenient macro defined in comedidev.h. It relies on
285 * n_subdevices being set correctly.
287 if(alloc_subdevices(dev, 4) < 0)
290 /*=========================================================================
291 Analog input subdevice
292 ========================================================================*/
294 s = dev->subdevices + 0;
296 if(thisboard->ai.count){
297 s->type = COMEDI_SUBD_AI;
298 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
299 s->n_chan = thisboard->ai.count;
300 s->maxdata = 0xFFFF; // 16 bit ADC
301 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
302 s->range_table = &me4000_ai_range;
303 s->insn_read = me4000_ai_insn_read;
306 if(comedi_request_irq(info->irq, me4000_ai_isr, IRQF_SHARED, "ME-4000", dev)) {
307 printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
310 dev->read_subdev = s;
311 s->subdev_flags |= SDF_CMD_READ;
312 s->cancel = me4000_ai_cancel;
313 s->do_cmdtest = me4000_ai_do_cmd_test;
314 s->do_cmd = me4000_ai_do_cmd;
318 printk(KERN_WARNING"comedi%d: me4000: me4000_attach(): No interrupt available\n", dev->minor);
322 s->type = COMEDI_SUBD_UNUSED;
325 /*=========================================================================
326 Analog output subdevice
327 ========================================================================*/
329 s = dev->subdevices + 1;
331 if(thisboard->ao.count){
332 s->type = COMEDI_SUBD_AO;
333 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
334 s->n_chan = thisboard->ao.count;
335 s->maxdata = 0xFFFF; // 16 bit DAC
336 s->range_table = &me4000_ao_range;
337 s->insn_write = me4000_ao_insn_write;
338 s->insn_read = me4000_ao_insn_read;
341 s->type = COMEDI_SUBD_UNUSED;
344 /*=========================================================================
345 Digital I/O subdevice
346 ========================================================================*/
348 s = dev->subdevices + 2;
350 if(thisboard->dio.count){
351 s->type = COMEDI_SUBD_DIO;
352 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
353 s->n_chan = thisboard->dio.count * 8;
355 s->range_table = &range_digital;
356 s->insn_bits = me4000_dio_insn_bits;
357 s->insn_config = me4000_dio_insn_config;
360 s->type = COMEDI_SUBD_UNUSED;
364 * Check for optoisolated ME-4000 version. If one the first
365 * port is a fixed output port and the second is a fixed input port.
367 if(!me4000_inl(dev, info->dio_context.dir_reg)){
369 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, info->dio_context.dir_reg);
372 /*=========================================================================
374 ========================================================================*/
376 s = dev->subdevices + 3;
378 if(thisboard->cnt.count){
379 s->type = COMEDI_SUBD_COUNTER;
380 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
381 s->n_chan = thisboard->cnt.count;
382 s->maxdata = 0xFFFF; // 16 bit counters
383 s->insn_read = me4000_cnt_insn_read;
384 s->insn_write = me4000_cnt_insn_write;
385 s->insn_config = me4000_cnt_insn_config;
388 s->type = COMEDI_SUBD_UNUSED;
396 static int me4000_probe(comedi_device *dev, comedi_devconfig *it){
397 struct pci_dev* pci_device;
399 me4000_board_t *board;
401 CALL_PDEBUG("In me4000_probe()\n");
403 /* Allocate private memory */
404 if(alloc_private(dev, sizeof(me4000_info_t)) < 0){
408 * Probe the device to determine what device in the series it is.
410 for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
411 pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
412 if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS){
413 for(i = 0; i < ME4000_BOARD_VERSIONS; i++){
414 if(me4000_boards[i].device_id == pci_device->device){
415 /* Was a particular bus/slot requested? */
416 if((it->options[0] != 0) || (it->options[1] != 0)){
417 /* Are we on the wrong bus/slot? */
418 if(pci_device->bus->number != it->options[0] ||
419 PCI_SLOT(pci_device->devfn) != it->options[1]){
423 dev->board_ptr = me4000_boards + i;
424 board = (me4000_board_t *) dev->board_ptr;
425 info->pci_dev_p = pci_device;
432 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
433 dev->minor,it->options[0], it->options[1]);
438 printk(KERN_INFO"comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
439 dev->minor, me4000_boards[i].name,
440 pci_device->bus->number, PCI_SLOT(pci_device->devfn));
442 /* Set data in device structure */
443 dev->board_name = board->name;
445 /* Enable PCI device */
446 result = pci_enable_device(pci_device);
448 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot enable PCI device\n", dev->minor);
452 /* Request the PCI register regions */
453 result = pci_request_regions(pci_device, dev->board_name);
455 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot request I/O regions\n", dev->minor);
458 /* Get the PCI base registers */
459 result = get_registers(dev, pci_device);
461 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot get registers\n", dev->minor);
464 /* Initialize board info */
465 result = init_board_info(dev, pci_device);
467 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init baord info\n", dev->minor);
471 /* Init analog output context */
472 result = init_ao_context(dev);
474 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ao context\n", dev->minor);
478 /* Init analog input context */
479 result = init_ai_context(dev);
481 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ai context\n", dev->minor);
485 /* Init digital I/O context */
486 result = init_dio_context(dev);
488 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init dio context\n", dev->minor);
492 /* Init counter context */
493 result = init_cnt_context(dev);
495 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init cnt context\n", dev->minor);
499 /* Download the xilinx firmware */
500 result = xilinx_download(dev);
502 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't download firmware\n", dev->minor);
506 /* Make a hardware reset */
507 result = reset_board(dev);
509 printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't reset board\n", dev->minor);
518 static int get_registers(comedi_device *dev, struct pci_dev *pci_dev_p){
520 CALL_PDEBUG("In get_registers()\n");
522 /*--------------------------- plx regbase ---------------------------------*/
524 info->plx_regbase = pci_resource_start (pci_dev_p, 1);
525 if(info->plx_regbase == 0){
526 printk(KERN_ERR"comedi%d: me4000: get_registers(): PCI base address 1 is not available\n", dev->minor);
529 info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
532 /*--------------------------- me4000 regbase ------------------------------*/
534 info->me4000_regbase = pci_resource_start (pci_dev_p, 2);
535 if(info->me4000_regbase == 0){
536 printk(KERN_ERR"comedi%d: me4000: get_registers(): PCI base address 2 is not available\n", dev->minor);
539 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"comedi%d: me4000: get_registers(): PCI base address 3 is not available\n", dev->minor);
549 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
552 /*--------------------------- program regbase ------------------------------*/
554 info->program_regbase = pci_resource_start (pci_dev_p, 5);
555 if(info->program_regbase == 0){
556 printk(KERN_ERR"comedi%d: me4000: get_registers(): PCI base address 5 is not available\n", dev->minor);
559 info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
566 static int init_board_info(comedi_device *dev, struct pci_dev *pci_dev_p){
569 CALL_PDEBUG("In init_board_info()\n");
571 /* Init spin locks */
572 //spin_lock_init(&info->preload_lock);
573 //spin_lock_init(&info->ai_ctrl_lock);
575 /* Get the serial number */
576 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
577 if(result != PCIBIOS_SUCCESSFUL){
581 /* Get the hardware revision */
582 result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
583 if(result != PCIBIOS_SUCCESSFUL){
587 /* Get the vendor id */
588 info->vendor_id = pci_dev_p->vendor;
590 /* Get the device id */
591 info->device_id = pci_dev_p->device;
593 /* Get the irq assigned to the board */
594 info->irq = pci_dev_p->irq;
601 static int init_ao_context(comedi_device *dev){
604 CALL_PDEBUG("In init_ao_context()\n");
606 for(i = 0; i < thisboard->ao.count; i++){
607 //spin_lock_init(&info->ao_context[i].use_lock);
608 info->ao_context[i].irq = info->irq;
612 info->ao_context[i].ctrl_reg = info->me4000_regbase + ME4000_AO_00_CTRL_REG;
613 info->ao_context[i].status_reg = info->me4000_regbase + ME4000_AO_00_STATUS_REG;
614 info->ao_context[i].fifo_reg = info->me4000_regbase + ME4000_AO_00_FIFO_REG;
615 info->ao_context[i].single_reg = info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
616 info->ao_context[i].timer_reg = info->me4000_regbase + ME4000_AO_00_TIMER_REG;
617 info->ao_context[i].irq_status_reg = info->me4000_regbase + ME4000_IRQ_STATUS_REG;
618 info->ao_context[i].preload_reg = info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
621 info->ao_context[i].ctrl_reg = info->me4000_regbase + ME4000_AO_01_CTRL_REG;
622 info->ao_context[i].status_reg = info->me4000_regbase + ME4000_AO_01_STATUS_REG;
623 info->ao_context[i].fifo_reg = info->me4000_regbase + ME4000_AO_01_FIFO_REG;
624 info->ao_context[i].single_reg = info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
625 info->ao_context[i].timer_reg = info->me4000_regbase + ME4000_AO_01_TIMER_REG;
626 info->ao_context[i].irq_status_reg = info->me4000_regbase + ME4000_IRQ_STATUS_REG;
627 info->ao_context[i].preload_reg = info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
630 info->ao_context[i].ctrl_reg = info->me4000_regbase + ME4000_AO_02_CTRL_REG;
631 info->ao_context[i].status_reg = info->me4000_regbase + ME4000_AO_02_STATUS_REG;
632 info->ao_context[i].fifo_reg = info->me4000_regbase + ME4000_AO_02_FIFO_REG;
633 info->ao_context[i].single_reg = info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
634 info->ao_context[i].timer_reg = info->me4000_regbase + ME4000_AO_02_TIMER_REG;
635 info->ao_context[i].irq_status_reg = info->me4000_regbase + ME4000_IRQ_STATUS_REG;
636 info->ao_context[i].preload_reg = info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
639 info->ao_context[i].ctrl_reg = info->me4000_regbase + ME4000_AO_03_CTRL_REG;
640 info->ao_context[i].status_reg = info->me4000_regbase + ME4000_AO_03_STATUS_REG;
641 info->ao_context[i].fifo_reg = info->me4000_regbase + ME4000_AO_03_FIFO_REG;
642 info->ao_context[i].single_reg = info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
643 info->ao_context[i].timer_reg = info->me4000_regbase + ME4000_AO_03_TIMER_REG;
644 info->ao_context[i].irq_status_reg = info->me4000_regbase + ME4000_IRQ_STATUS_REG;
645 info->ao_context[i].preload_reg = info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
657 static int init_ai_context(comedi_device *dev){
659 CALL_PDEBUG("In init_ai_context()\n");
661 info->ai_context.irq = info->irq;
663 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
664 info->ai_context.status_reg = info->me4000_regbase + ME4000_AI_STATUS_REG;
665 info->ai_context.channel_list_reg = info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
666 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
667 info->ai_context.chan_timer_reg = info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
668 info->ai_context.chan_pre_timer_reg = info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
669 info->ai_context.scan_timer_low_reg = info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
670 info->ai_context.scan_timer_high_reg = info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
671 info->ai_context.scan_pre_timer_low_reg = info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
672 info->ai_context.scan_pre_timer_high_reg = info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
673 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
674 info->ai_context.irq_status_reg = info->me4000_regbase + ME4000_IRQ_STATUS_REG;
675 info->ai_context.sample_counter_reg = info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
682 static int init_dio_context(comedi_device *dev){
684 CALL_PDEBUG("In init_dio_context()\n");
686 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
687 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
688 info->dio_context.port_0_reg = info->me4000_regbase + ME4000_DIO_PORT_0_REG;
689 info->dio_context.port_1_reg = info->me4000_regbase + ME4000_DIO_PORT_1_REG;
690 info->dio_context.port_2_reg = info->me4000_regbase + ME4000_DIO_PORT_2_REG;
691 info->dio_context.port_3_reg = info->me4000_regbase + ME4000_DIO_PORT_3_REG;
698 static int init_cnt_context(comedi_device *dev){
700 CALL_PDEBUG("In init_cnt_context()\n");
702 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
703 info->cnt_context.counter_0_reg = info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
704 info->cnt_context.counter_1_reg = info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
705 info->cnt_context.counter_2_reg = info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
710 #define FIRMWARE_NOT_AVAILABLE 1
711 #if FIRMWARE_NOT_AVAILABLE
712 extern unsigned char *xilinx_firm;
715 static int xilinx_download(comedi_device *dev){
717 wait_queue_head_t queue;
721 CALL_PDEBUG("In xilinx_download()\n");
723 init_waitqueue_head(&queue);
726 * Set PLX local interrupt 2 polarity to high.
727 * Interrupt is thrown by init pin of xilinx.
729 outl(0x10, info->plx_regbase + PLX_INTCSR);
731 /* Set /CS and /WRITE of the Xilinx */
732 value = inl(info->plx_regbase + PLX_ICR);
734 outl(value, info->plx_regbase + PLX_ICR);
736 /* Init Xilinx with CS1 */
737 inb(info->program_regbase + 0xC8);
739 /* Wait until /INIT pin is set */
741 if(! inl(info->plx_regbase + PLX_INTCSR) & 0x20){
742 printk(KERN_ERR"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n", dev->minor);
746 /* Reset /CS and /WRITE of the Xilinx */
747 value = inl(info->plx_regbase + PLX_ICR);
749 outl(value, info->plx_regbase + PLX_ICR);
750 if(FIRMWARE_NOT_AVAILABLE){
751 comedi_error(dev, "xilinx firmware unavailable due to licensing, aborting");
755 /* Download Xilinx firmware */
756 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) + (xilinx_firm[2] << 8) + xilinx_firm[3];
759 for(idx = 0; idx < size; idx++){
760 outb(xilinx_firm[16+idx], info->program_regbase);
763 /* Check if BUSY flag is low */
764 if(inl(info->plx_regbase + PLX_ICR) & 0x20){
765 printk(KERN_ERR"comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n", dev->minor, idx);
771 /* If done flag is high download was successful */
772 if (inl(info->plx_regbase + PLX_ICR) & 0x4){
775 printk(KERN_ERR"comedi%d: me4000: xilinx_download(): DONE flag is not set\n", dev->minor);
776 printk(KERN_ERR"comedi%d: me4000: xilinx_download(): Download not succesful\n", dev->minor);
780 /* Set /CS and /WRITE */
781 value = inl(info->plx_regbase + PLX_ICR);
783 outl(value, info->plx_regbase + PLX_ICR);
790 static int reset_board(comedi_device *dev){
793 CALL_PDEBUG("In reset_board()\n");
795 /* Make a hardware reset */
796 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
798 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
800 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
802 /* 0x8000 to the DACs means an output voltage of 0V */
803 me4000_outl(dev, 0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
804 me4000_outl(dev, 0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
805 me4000_outl(dev, 0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
806 me4000_outl(dev, 0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
808 /* Set both stop bits in the analog input control register */
811 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
812 info->me4000_regbase + ME4000_AI_CTRL_REG);
814 /* Set both stop bits in the analog output control register */
817 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
818 info->me4000_regbase + ME4000_AO_00_CTRL_REG);
821 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
822 info->me4000_regbase + ME4000_AO_01_CTRL_REG);
825 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
826 info->me4000_regbase + ME4000_AO_02_CTRL_REG);
829 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
830 info->me4000_regbase + ME4000_AO_03_CTRL_REG);
832 /* Enable interrupts on the PLX */
833 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
835 /* Set the adustment register for AO demux */
836 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE, info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
838 /* Set digital I/O direction for port 0 to output on isolated versions */
839 if(!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)){
840 me4000_outl(dev, 0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
848 static int me4000_detach(comedi_device *dev){
849 CALL_PDEBUG("In me4000_detach()\n");
852 if(info->pci_dev_p) {
854 if(info->plx_regbase)
856 pci_release_regions(info->pci_dev_p);
857 pci_disable_device(info->pci_dev_p);
859 pci_dev_put(info->pci_dev_p);
868 /*=============================================================================
870 ===========================================================================*/
872 static int me4000_ai_insn_read(
874 comedi_subdevice *subdevice,
878 int chan = CR_CHAN(insn->chanspec);
879 int rang = CR_RANGE(insn->chanspec);
880 int aref = CR_AREF(insn->chanspec);
882 unsigned long entry = 0;
886 CALL_PDEBUG("In me4000_ai_insn_read()\n");
891 else if(insn->n > 1){
892 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
893 dev->minor, insn->n);
899 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
902 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
905 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
908 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
911 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n", dev->minor);
918 if(chan >= thisboard->ai.count){
919 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n", dev->minor);
922 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
926 if(rang == 0 || rang == 1){
927 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
932 if(chan >= thisboard->ai.diff_count){
933 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n", dev->minor);
936 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
939 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n", dev->minor);
943 entry |= ME4000_AI_LIST_LAST_ENTRY;
945 /* Clear channel list, data fifo and both stop bits */
946 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
947 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
948 ME4000_AI_CTRL_BIT_DATA_FIFO |
949 ME4000_AI_CTRL_BIT_STOP |
950 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
951 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
953 /* Set the acquisition mode to single */
954 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 | ME4000_AI_CTRL_BIT_MODE_2);
955 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
957 /* Enable channel list and data fifo */
958 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
959 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
961 /* Generate channel list entry */
962 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
964 /* Set the timer to maximum sample rate */
965 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
966 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_pre_timer_reg);
968 /* Start conversion by dummy read */
969 me4000_inl(dev, info->ai_context.start_reg);
971 /* Wait until ready */
973 if(!(me4000_inl(dev, info->ai_context.status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)){
974 printk(KERN_ERR"comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n", dev->minor);
978 /* Read value from data fifo */
979 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
980 data[0] = lval ^ 0x8000;
987 static int me4000_ai_cancel(comedi_device *dev, comedi_subdevice *s){
990 CALL_PDEBUG("In me4000_ai_cancel()\n");
992 /* Stop any running conversion */
993 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
994 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
995 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
997 /* Clear the control register */
998 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1005 static int ai_check_chanlist(
1007 comedi_subdevice *s,
1012 CALL_PDEBUG("In ai_check_chanlist()\n");
1014 /* Check whether a channel list is available */
1015 if(!cmd->chanlist_len){
1016 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): No channel list available\n", dev->minor);
1020 /* Check the channel list size */
1021 if(cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT){
1022 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n", dev->minor);
1026 /* Check the pointer */
1028 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n", dev->minor);
1032 /* Check whether aref is equal for all entries */
1033 aref = CR_AREF(cmd->chanlist[0]);
1034 for(i = 0; i < cmd->chanlist_len; i++){
1035 if(CR_AREF(cmd->chanlist[i]) != aref){
1036 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n", dev->minor);
1041 /* Check whether channels are available for this ending */
1042 if(aref == SDF_DIFF){
1043 for(i = 0; i < cmd->chanlist_len; i++){
1044 if(CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.diff_count){
1045 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n", dev->minor);
1051 for(i = 0; i < cmd->chanlist_len; i++){
1052 if(CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count){
1053 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n", dev->minor);
1059 /* Check if bipolar is set for all entries when in differential mode */
1060 if(aref == SDF_DIFF){
1061 for(i = 0; i < cmd->chanlist_len; i++){
1062 if(CR_RANGE(cmd->chanlist[i]) != 1 &&
1063 CR_RANGE(cmd->chanlist[i]) != 2){
1064 printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
1076 static int ai_round_cmd_args(
1078 comedi_subdevice *s,
1080 unsigned int *init_ticks,
1081 unsigned int *scan_ticks,
1082 unsigned int *chan_ticks){
1086 CALL_PDEBUG("In ai_round_cmd_args()\n");
1092 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1093 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n", cmd->scan_begin_arg);
1094 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1097 *init_ticks = (cmd->start_arg * 33) / 1000;
1098 rest = (cmd->start_arg * 33) % 1000;
1100 if(cmd->flags & TRIG_ROUND_NEAREST){
1105 else if(cmd->flags & TRIG_ROUND_UP){
1106 if(rest) (*init_ticks) ++;
1110 if(cmd->scan_begin_arg){
1111 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1112 rest = (cmd->scan_begin_arg * 33) % 1000;
1114 if(cmd->flags & TRIG_ROUND_NEAREST){
1119 else if(cmd->flags & TRIG_ROUND_UP){
1120 if(rest) (*scan_ticks) ++;
1124 if(cmd->convert_arg){
1125 *chan_ticks = (cmd->convert_arg * 33) / 1000;
1126 rest = (cmd->convert_arg * 33) % 1000;
1128 if(cmd->flags & TRIG_ROUND_NEAREST){
1133 else if(cmd->flags & TRIG_ROUND_UP){
1134 if(rest) (*chan_ticks) ++;
1138 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1139 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1140 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1147 static void ai_write_timer(
1149 unsigned int init_ticks,
1150 unsigned int scan_ticks,
1151 unsigned int chan_ticks){
1153 CALL_PDEBUG("In ai_write_timer()\n");
1155 me4000_outl(dev, init_ticks - 1, info->ai_context.scan_pre_timer_low_reg);
1156 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1159 me4000_outl(dev, scan_ticks - 1, info->ai_context.scan_timer_low_reg);
1160 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1163 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1164 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1169 static int ai_prepare(
1171 comedi_subdevice *s,
1173 unsigned int init_ticks,
1174 unsigned int scan_ticks,
1175 unsigned int chan_ticks){
1177 unsigned long tmp = 0;
1179 CALL_PDEBUG("In ai_prepare()\n");
1181 /* Write timer arguments */
1182 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1184 /* Reset control register */
1185 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1188 if((cmd->start_src == TRIG_EXT &&
1189 cmd->scan_begin_src == TRIG_TIMER &&
1190 cmd->convert_src == TRIG_TIMER) ||
1191 (cmd->start_src == TRIG_EXT &&
1192 cmd->scan_begin_src == TRIG_FOLLOW &&
1193 cmd->convert_src == TRIG_TIMER)){
1195 ME4000_AI_CTRL_BIT_MODE_1 |
1196 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1197 ME4000_AI_CTRL_BIT_DATA_FIFO;
1199 else if(cmd->start_src == TRIG_EXT &&
1200 cmd->scan_begin_src == TRIG_EXT &&
1201 cmd->convert_src == TRIG_TIMER){
1203 ME4000_AI_CTRL_BIT_MODE_2 |
1204 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1205 ME4000_AI_CTRL_BIT_DATA_FIFO;
1207 else if(cmd->start_src == TRIG_EXT &&
1208 cmd->scan_begin_src == TRIG_EXT &&
1209 cmd->convert_src == TRIG_EXT){
1211 ME4000_AI_CTRL_BIT_MODE_0 |
1212 ME4000_AI_CTRL_BIT_MODE_1 |
1213 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1214 ME4000_AI_CTRL_BIT_DATA_FIFO;
1218 ME4000_AI_CTRL_BIT_MODE_0 |
1219 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1220 ME4000_AI_CTRL_BIT_DATA_FIFO;
1224 if(cmd->stop_src == TRIG_COUNT){
1225 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg, info->ai_context.sample_counter_reg);
1226 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1228 else if( cmd->stop_src == TRIG_NONE &&
1229 cmd->scan_end_src == TRIG_COUNT){
1230 me4000_outl(dev, cmd->scan_end_arg, info->ai_context.sample_counter_reg);
1231 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1234 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1237 /* Write the setup to the control register */
1238 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1240 /* Write the channel list */
1241 ai_write_chanlist(dev, s, cmd);
1248 static int ai_write_chanlist(
1250 comedi_subdevice *s,
1258 CALL_PDEBUG("In ai_write_chanlist()\n");
1260 for(i = 0; i < cmd->chanlist_len; i++){
1261 chan = CR_CHAN(cmd->chanlist[i]);
1262 rang = CR_RANGE(cmd->chanlist[i]);
1263 aref = CR_AREF(cmd->chanlist[i]);
1268 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1271 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1274 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1277 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1280 if(aref == SDF_DIFF){
1281 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1284 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1287 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1295 static int me4000_ai_do_cmd(comedi_device *dev, comedi_subdevice *s){
1297 unsigned int init_ticks = 0;
1298 unsigned int scan_ticks = 0;
1299 unsigned int chan_ticks = 0;
1300 comedi_cmd *cmd= &s->async->cmd;
1302 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1304 /* Reset the analog input */
1305 err = me4000_ai_cancel(dev, s);
1308 /* Round the timer arguments */
1309 err = ai_round_cmd_args(
1318 /* Prepare the AI for acquisition */
1328 /* Start acquistion by dummy read */
1329 me4000_inl(dev, info->ai_context.start_reg);
1337 * me4000_ai_do_cmd_test():
1339 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1343 * - invalid argument
1344 * - argument conflict
1345 * - invalid chanlist
1346 * So I tried to adopt this scheme.
1348 static int me4000_ai_do_cmd_test(
1350 comedi_subdevice *s,
1353 unsigned int init_ticks;
1354 unsigned int chan_ticks;
1355 unsigned int scan_ticks;
1358 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1360 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev);
1361 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags);
1362 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n", cmd->start_src);
1363 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n", cmd->start_arg);
1364 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n", cmd->scan_begin_src);
1365 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n", cmd->scan_begin_arg);
1366 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n", cmd->convert_src);
1367 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n", cmd->convert_arg);
1368 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n", cmd->scan_end_src);
1369 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n", cmd->scan_end_arg);
1370 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n", cmd->stop_src);
1371 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg);
1372 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n", (unsigned int) cmd->chanlist);
1373 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n", cmd->chanlist_len);
1375 /* Only rounding flags are implemented */
1376 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1378 /* Round the timer arguments */
1388 * Stage 1. Check if the trigger sources are generally valid.
1390 switch(cmd->start_src){
1395 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1399 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n", dev->minor);
1400 cmd->start_src = TRIG_NOW;
1403 switch(cmd->scan_begin_src){
1409 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1413 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n", dev->minor);
1414 cmd->scan_begin_src = TRIG_FOLLOW;
1417 switch(cmd->convert_src){
1422 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1426 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n", dev->minor);
1427 cmd->convert_src = TRIG_TIMER;
1430 switch(cmd->scan_end_src){
1435 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1439 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n", dev->minor);
1440 cmd->scan_end_src = TRIG_NONE;
1443 switch(cmd->stop_src){
1448 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1452 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n", dev->minor);
1453 cmd->stop_src = TRIG_NONE;
1461 * Stage 2. Check for trigger source conflicts.
1463 if( cmd->start_src == TRIG_NOW &&
1464 cmd->scan_begin_src == TRIG_TIMER &&
1465 cmd->convert_src == TRIG_TIMER){
1467 else if(cmd->start_src == TRIG_NOW &&
1468 cmd->scan_begin_src == TRIG_FOLLOW &&
1469 cmd->convert_src == TRIG_TIMER){
1471 else if(cmd->start_src == TRIG_EXT &&
1472 cmd->scan_begin_src == TRIG_TIMER &&
1473 cmd->convert_src == TRIG_TIMER){
1475 else if(cmd->start_src == TRIG_EXT &&
1476 cmd->scan_begin_src == TRIG_FOLLOW &&
1477 cmd->convert_src == TRIG_TIMER){
1479 else if(cmd->start_src == TRIG_EXT &&
1480 cmd->scan_begin_src == TRIG_EXT &&
1481 cmd->convert_src == TRIG_TIMER){
1483 else if(cmd->start_src == TRIG_EXT &&
1484 cmd->scan_begin_src == TRIG_EXT &&
1485 cmd->convert_src == TRIG_EXT){
1488 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n", dev->minor);
1489 cmd->start_src = TRIG_NOW;
1490 cmd->scan_begin_src = TRIG_FOLLOW;
1491 cmd->convert_src = TRIG_TIMER;
1495 if( cmd->stop_src == TRIG_NONE &&
1496 cmd->scan_end_src == TRIG_NONE){
1498 else if( cmd->stop_src == TRIG_COUNT &&
1499 cmd->scan_end_src == TRIG_NONE){
1501 else if( cmd->stop_src == TRIG_NONE &&
1502 cmd->scan_end_src == TRIG_COUNT){
1504 else if( cmd->stop_src == TRIG_COUNT &&
1505 cmd->scan_end_src == TRIG_COUNT){
1508 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n", dev->minor);
1509 cmd->stop_src = TRIG_NONE;
1510 cmd->scan_end_src = TRIG_NONE;
1518 * Stage 3. Check if arguments are generally valid.
1520 if(cmd->chanlist_len < 1){
1521 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n", dev->minor);
1522 cmd->chanlist_len = 1;
1525 if(init_ticks < 66){
1526 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n", dev->minor);
1527 cmd->start_arg = 2000;
1530 if(scan_ticks && scan_ticks < 67){
1531 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n", dev->minor);
1532 cmd->scan_begin_arg = 2031;
1535 if(chan_ticks < 66){
1536 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n", dev->minor);
1537 cmd->convert_arg = 2000;
1545 * Stage 4. Check for argument conflicts.
1547 if( cmd->start_src == TRIG_NOW &&
1548 cmd->scan_begin_src == TRIG_TIMER &&
1549 cmd->convert_src == TRIG_TIMER){
1551 /* Check timer arguments */
1552 if(init_ticks < ME4000_AI_MIN_TICKS){
1553 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1554 cmd->start_arg = 2000; // 66 ticks at least
1557 if(chan_ticks < ME4000_AI_MIN_TICKS){
1558 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n", dev->minor);
1559 cmd->convert_arg = 2000; // 66 ticks at least
1562 if(scan_ticks <= cmd->chanlist_len * chan_ticks){
1563 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n", dev->minor);
1564 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
1568 else if(cmd->start_src == TRIG_NOW &&
1569 cmd->scan_begin_src == TRIG_FOLLOW &&
1570 cmd->convert_src == TRIG_TIMER){
1572 /* Check timer arguments */
1573 if(init_ticks < ME4000_AI_MIN_TICKS){
1574 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1575 cmd->start_arg = 2000; // 66 ticks at least
1578 if(chan_ticks < ME4000_AI_MIN_TICKS){
1579 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n", dev->minor);
1580 cmd->convert_arg = 2000; // 66 ticks at least
1584 else if(cmd->start_src == TRIG_EXT &&
1585 cmd->scan_begin_src == TRIG_TIMER &&
1586 cmd->convert_src == TRIG_TIMER){
1588 /* Check timer arguments */
1589 if(init_ticks < ME4000_AI_MIN_TICKS){
1590 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1591 cmd->start_arg = 2000; // 66 ticks at least
1594 if(chan_ticks < ME4000_AI_MIN_TICKS){
1595 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n", dev->minor);
1596 cmd->convert_arg = 2000; // 66 ticks at least
1599 if(scan_ticks <= cmd->chanlist_len * chan_ticks){
1600 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n", dev->minor);
1601 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
1605 else if(cmd->start_src == TRIG_EXT &&
1606 cmd->scan_begin_src == TRIG_FOLLOW &&
1607 cmd->convert_src == TRIG_TIMER){
1609 /* Check timer arguments */
1610 if(init_ticks < ME4000_AI_MIN_TICKS){
1611 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1612 cmd->start_arg = 2000; // 66 ticks at least
1615 if(chan_ticks < ME4000_AI_MIN_TICKS){
1616 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n", dev->minor);
1617 cmd->convert_arg = 2000; // 66 ticks at least
1621 else if(cmd->start_src == TRIG_EXT &&
1622 cmd->scan_begin_src == TRIG_EXT &&
1623 cmd->convert_src == TRIG_TIMER){
1625 /* Check timer arguments */
1626 if(init_ticks < ME4000_AI_MIN_TICKS){
1627 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1628 cmd->start_arg = 2000; // 66 ticks at least
1631 if(chan_ticks < ME4000_AI_MIN_TICKS){
1632 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n", dev->minor);
1633 cmd->convert_arg = 2000; // 66 ticks at least
1637 else if(cmd->start_src == TRIG_EXT &&
1638 cmd->scan_begin_src == TRIG_EXT &&
1639 cmd->convert_src == TRIG_EXT){
1641 /* Check timer arguments */
1642 if(init_ticks < ME4000_AI_MIN_TICKS){
1643 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n", dev->minor);
1644 cmd->start_arg = 2000; // 66 ticks at least
1648 if(cmd->stop_src == TRIG_COUNT){
1649 if(cmd->stop_arg == 0){
1650 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n", dev->minor);
1655 if(cmd->scan_end_src == TRIG_COUNT){
1656 if(cmd->scan_end_arg == 0){
1657 printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n", dev->minor);
1658 cmd->scan_end_arg = 1;
1667 * Stage 5. Check the channel list.
1669 if(ai_check_chanlist(dev, s, cmd))
1677 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG){
1679 comedi_device *dev = dev_id;
1680 comedi_subdevice *s = dev->subdevices;
1681 me4000_ai_context_t *ai_context = &info->ai_context;
1686 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1688 /* Reset all events */
1689 s->async->events = 0;
1691 /* Check if irq number is right */
1692 if(irq != ai_context->irq){
1693 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n", dev->minor, irq);
1697 if(me4000_inl(dev, ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF){
1698 ISR_PDEBUG("me4000_ai_isr(): Fifo half full interrupt occured\n");
1700 /* Read status register to find out what happened */
1701 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1703 if(!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1704 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1705 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)){
1706 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1707 c = ME4000_AI_FIFO_COUNT;
1709 /* FIFO overflow, so stop conversion and disable all interrupts */
1710 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1711 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1712 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1714 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1716 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n", dev->minor);
1718 else if((tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1719 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1720 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)){
1721 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1723 s->async->events |= COMEDI_CB_BLOCK;
1725 c = ME4000_AI_FIFO_COUNT/2;
1728 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n", dev->minor);
1731 /* Undefined state, so stop conversion and disable all interrupts */
1732 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1733 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1734 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1736 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1738 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n", dev->minor);
1741 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1743 for(i = 0; i < c; i++){
1744 /* Read value from data fifo */
1745 lval = inl(ai_context->data_reg) & 0xFFFF;
1748 if(!comedi_buf_put(s->async, lval)){
1749 /* Buffer overflow, so stop conversion and disable all interrupts */
1750 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1751 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1752 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1754 s->async->events |= COMEDI_CB_OVERFLOW;
1756 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n", dev->minor);
1762 /* Work is done, so reset the interrupt */
1763 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1764 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1765 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1766 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1767 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1770 if(me4000_inl(dev, ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC){
1771 ISR_PDEBUG("me4000_ai_isr(): Sample counter interrupt occured\n");
1773 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1775 /* Acquisition is complete, so stop conversion and disable all interrupts */
1776 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1777 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1778 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1779 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1781 /* Poll data until fifo empty */
1782 while(inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA){
1783 /* Read value from data fifo */
1784 lval = inl(ai_context->data_reg) & 0xFFFF;
1787 if(!comedi_buf_put(s->async, lval)){
1788 printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n", dev->minor);
1789 s->async->events |= COMEDI_CB_OVERFLOW;
1794 /* Work is done, so reset the interrupt */
1795 ISR_PDEBUG("me4000_ai_isr(): Reset interrupt from sample counter\n");
1796 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1797 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1798 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1799 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1802 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1804 if(s->async->events)
1805 comedi_event(dev, s, s->async->events);
1812 /*=============================================================================
1813 Analog output section
1814 ===========================================================================*/
1816 static int me4000_ao_insn_write(
1818 comedi_subdevice *s,
1822 int chan = CR_CHAN(insn->chanspec);
1823 int rang = CR_RANGE(insn->chanspec);
1824 int aref = CR_AREF(insn->chanspec);
1827 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1832 else if(insn->n > 1){
1833 printk(KERN_ERR"comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
1834 dev->minor, insn->n);
1838 if(chan >= thisboard->ao.count){
1839 printk(KERN_ERR"comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
1840 dev->minor, insn->n);
1845 printk(KERN_ERR"comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
1846 dev->minor, insn->n);
1850 if(aref != AREF_GROUND && aref != AREF_COMMON){
1851 printk(KERN_ERR"comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
1852 dev->minor, insn->n);
1856 /* Stop any running conversion */
1857 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
1858 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1859 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
1861 /* Clear control register and set to single mode */
1862 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
1864 /* Write data value */
1865 me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
1867 /* Store in the mirror */
1868 info->ao_context[chan].mirror = data[0];
1875 static int me4000_ao_insn_read(
1876 comedi_device * dev,
1877 comedi_subdevice * s,
1880 int chan = CR_CHAN(insn->chanspec);
1885 else if(insn->n > 1){
1886 printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
1890 data[0] = info->ao_context[chan].mirror;
1897 /*=============================================================================
1899 ===========================================================================*/
1901 static int me4000_dio_insn_bits(
1903 comedi_subdevice *s,
1907 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
1909 /* Length of data must be 2 (mask and new data, see below) */
1914 printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
1919 * The insn data consists of a mask in data[0] and the new data
1920 * in data[1]. The mask defines which bits we are concerning about.
1921 * The new data must be anded with the mask.
1922 * Each channel corresponds to a bit.
1925 /* Check if requested ports are configured for output */
1926 if((s->io_bits & data[0]) != data[0])
1929 s->state &= ~data[0];
1930 s->state |= data[0] & data[1];
1932 /* Write out the new digital output lines */
1933 me4000_outl(dev, (s->state >> 0) & 0xFF, info->dio_context.port_0_reg);
1934 me4000_outl(dev, (s->state >> 8) & 0xFF, info->dio_context.port_1_reg);
1935 me4000_outl(dev, (s->state >> 16) & 0xFF, info->dio_context.port_2_reg);
1936 me4000_outl(dev, (s->state >> 24) & 0xFF, info->dio_context.port_3_reg);
1939 /* On return, data[1] contains the value of
1940 the digital input and output lines. */
1942 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
1943 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
1944 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
1945 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
1952 static int me4000_dio_insn_config(
1954 comedi_subdevice *s,
1958 int chan = CR_CHAN(insn->chanspec);
1960 CALL_PDEBUG("In me4000_dio_insn_config()\n");
1962 if(data[0] == INSN_CONFIG_DIO_QUERY)
1964 data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1969 * The input or output configuration of each digital line is
1970 * configured by a special insn_config instruction. chanspec
1971 * contains the channel to be changed, and data[0] contains the
1972 * value COMEDI_INPUT or COMEDI_OUTPUT.
1973 * On the ME-4000 it is only possible to switch port wise (8 bit)
1976 tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
1978 if(data[0] == COMEDI_OUTPUT){
1981 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1);
1982 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1986 * Chech for optoisolated ME-4000 version. If one the first
1987 * port is a fixed output port and the second is a fixed input port.
1989 if(!me4000_inl(dev, info->dio_context.dir_reg))
1992 s->io_bits |= 0xFF00;
1993 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3);
1994 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1997 s->io_bits |= 0xFF0000;
1998 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5);
1999 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2002 s->io_bits |= 0xFF000000;
2003 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
2004 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2013 * Chech for optoisolated ME-4000 version. If one the first
2014 * port is a fixed output port and the second is a fixed input port.
2016 if(!me4000_inl(dev, info->dio_context.dir_reg))
2019 s->io_bits &= ~0xFF;
2020 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1);
2023 s->io_bits &= ~0xFF00;
2024 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3);
2027 s->io_bits &= ~0xFF0000;
2028 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5);
2031 s->io_bits &= ~0xFF000000;
2032 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
2039 me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2046 /*=============================================================================
2048 ===========================================================================*/
2050 static int cnt_reset(comedi_device *dev, unsigned int channel){
2052 CALL_PDEBUG("In cnt_reset()\n");
2056 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2057 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2058 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2061 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2062 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2063 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2066 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2067 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2068 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2071 printk(KERN_ERR"comedi%d: me4000: cnt_reset(): Invalid channel\n", dev->minor);
2080 static int cnt_config(comedi_device *dev, unsigned int channel, unsigned int mode){
2083 CALL_PDEBUG("In cnt_config()\n");
2087 tmp |= ME4000_CNT_COUNTER_0;
2090 tmp |= ME4000_CNT_COUNTER_1;
2093 tmp |= ME4000_CNT_COUNTER_2;
2096 printk(KERN_ERR"comedi%d: me4000: cnt_config(): Invalid channel\n", dev->minor);
2102 tmp |= ME4000_CNT_MODE_0;
2105 tmp |= ME4000_CNT_MODE_1;
2108 tmp |= ME4000_CNT_MODE_2;
2111 tmp |= ME4000_CNT_MODE_3;
2114 tmp |= ME4000_CNT_MODE_4;
2117 tmp |= ME4000_CNT_MODE_5;
2120 printk(KERN_ERR"comedi%d: me4000: cnt_config(): Invalid counter mode\n", dev->minor);
2124 /* Write the control word */
2126 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2133 static int me4000_cnt_insn_config(
2135 comedi_subdevice *s,
2141 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2146 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2147 dev->minor, insn->n);
2151 err = cnt_reset(dev, insn->chanspec);
2154 case GPCT_SET_OPERATION:
2156 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2157 dev->minor, insn->n);
2161 err = cnt_config(dev, insn->chanspec, data[1]);
2165 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
2175 static int me4000_cnt_insn_read(
2177 comedi_subdevice *s,
2183 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2189 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
2190 dev->minor, insn->n);
2194 switch(insn->chanspec){
2196 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2198 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2199 data[0] |= tmp << 8;
2202 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2204 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2205 data[0] |= tmp << 8;
2208 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2210 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2211 data[0] |= tmp << 8;
2214 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
2215 dev->minor, insn->chanspec);
2224 static int me4000_cnt_insn_write(
2226 comedi_subdevice *s,
2232 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2237 else if(insn->n > 1){
2238 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
2239 dev->minor, insn->n);
2243 switch(insn->chanspec){
2245 tmp = data[0] & 0xFF;
2246 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2247 tmp = (data[0] >> 8) & 0xFF;
2248 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2251 tmp = data[0] & 0xFF;
2252 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2253 tmp = (data[0] >> 8) & 0xFF;
2254 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2257 tmp = data[0] & 0xFF;
2258 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2259 tmp = (data[0] >> 8) & 0xFF;
2260 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2263 printk(KERN_ERR"comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
2264 dev->minor, insn->chanspec);
2273 COMEDI_INITCLEANUP(driver_me4000);