Staging: comedi: remove RT code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / comedi / drivers / me4000.c
blob236845871735257ca59409a9873356df9b950d73
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 <linux/interrupt.h>
55 #include "../comedidev.h"
57 #include <linux/delay.h>
58 #include <linux/list.h>
59 #include <linux/spinlock.h>
61 #include "comedi_pci.h"
62 #include "me4000.h"
63 #if 0
64 /* file removed due to GPL incompatibility */
65 #include "me4000_fw.h"
66 #endif
68 /*=============================================================================
69 PCI device table.
70 This is used by modprobe to translate PCI IDs to drivers.
71 ===========================================================================*/
73 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
74 {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
76 {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
78 {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
79 {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
81 {PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
82 {PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
84 {PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
86 {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
88 {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89 {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91 {0}
94 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
96 static const struct me4000_board me4000_boards[] = {
97 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
99 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
100 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
101 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
102 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
104 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
105 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
106 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
107 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
109 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
110 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
111 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
112 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
114 {0},
117 #define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1)
119 /*-----------------------------------------------------------------------------
120 Comedi function prototypes
121 ---------------------------------------------------------------------------*/
122 static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
123 static int me4000_detach(struct comedi_device *dev);
124 static struct comedi_driver driver_me4000 = {
125 driver_name:"me4000",
126 module : THIS_MODULE,
127 attach : me4000_attach,
128 detach : me4000_detach,
131 /*-----------------------------------------------------------------------------
132 Meilhaus function prototypes
133 ---------------------------------------------------------------------------*/
134 static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it);
135 static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
136 static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p);
137 static int init_ao_context(struct comedi_device *dev);
138 static int init_ai_context(struct comedi_device *dev);
139 static int init_dio_context(struct comedi_device *dev);
140 static int init_cnt_context(struct comedi_device *dev);
141 static int xilinx_download(struct comedi_device *dev);
142 static int reset_board(struct comedi_device *dev);
144 static int me4000_dio_insn_bits(struct comedi_device *dev,
145 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
147 static int me4000_dio_insn_config(struct comedi_device *dev,
148 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
150 static int cnt_reset(struct comedi_device *dev, unsigned int channel);
152 static int cnt_config(struct comedi_device *dev,
153 unsigned int channel, unsigned int mode);
155 static int me4000_cnt_insn_config(struct comedi_device *dev,
156 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
158 static int me4000_cnt_insn_write(struct comedi_device *dev,
159 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
161 static int me4000_cnt_insn_read(struct comedi_device *dev,
162 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
164 static int me4000_ai_insn_read(struct comedi_device *dev,
165 struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data);
167 static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
169 static int ai_check_chanlist(struct comedi_device *dev,
170 struct comedi_subdevice *s, struct comedi_cmd *cmd);
172 static int ai_round_cmd_args(struct comedi_device *dev,
173 struct comedi_subdevice *s,
174 struct comedi_cmd *cmd,
175 unsigned int *init_ticks,
176 unsigned int *scan_ticks, unsigned int *chan_ticks);
178 static int ai_prepare(struct comedi_device *dev,
179 struct comedi_subdevice *s,
180 struct comedi_cmd *cmd,
181 unsigned int init_ticks,
182 unsigned int scan_ticks, unsigned int chan_ticks);
184 static int ai_write_chanlist(struct comedi_device *dev,
185 struct comedi_subdevice *s, struct comedi_cmd *cmd);
187 static irqreturn_t me4000_ai_isr(int irq, void *dev_id);
189 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
190 struct comedi_subdevice *s, struct comedi_cmd *cmd);
192 static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
194 static int me4000_ao_insn_write(struct comedi_device *dev,
195 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
197 static int me4000_ao_insn_read(struct comedi_device *dev,
198 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
200 /*-----------------------------------------------------------------------------
201 Meilhaus inline functions
202 ---------------------------------------------------------------------------*/
204 static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
205 unsigned long port)
207 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
208 outb(value, port);
211 static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
212 unsigned long port)
214 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
215 outl(value, port);
218 static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long port)
220 unsigned long value;
221 value = inl(port);
222 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
223 return value;
226 static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long port)
228 unsigned char value;
229 value = inb(port);
230 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
231 return value;
234 static const struct comedi_lrange me4000_ai_range = {
237 UNI_RANGE(2.5),
238 UNI_RANGE(10),
239 BIP_RANGE(2.5),
240 BIP_RANGE(10),
244 static const struct comedi_lrange me4000_ao_range = {
247 BIP_RANGE(10),
251 static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
253 struct comedi_subdevice *s;
254 int result;
256 CALL_PDEBUG("In me4000_attach()\n");
258 result = me4000_probe(dev, it);
259 if (result)
260 return result;
263 * Allocate the subdevice structures. alloc_subdevice() is a
264 * convenient macro defined in comedidev.h. It relies on
265 * n_subdevices being set correctly.
267 if (alloc_subdevices(dev, 4) < 0)
268 return -ENOMEM;
270 /*=========================================================================
271 Analog input subdevice
272 ========================================================================*/
274 s = dev->subdevices + 0;
276 if (thisboard->ai.count) {
277 s->type = COMEDI_SUBD_AI;
278 s->subdev_flags =
279 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
280 s->n_chan = thisboard->ai.count;
281 s->maxdata = 0xFFFF; /* 16 bit ADC */
282 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
283 s->range_table = &me4000_ai_range;
284 s->insn_read = me4000_ai_insn_read;
286 if (info->irq > 0) {
287 if (request_irq(info->irq, me4000_ai_isr,
288 IRQF_SHARED, "ME-4000", dev)) {
289 printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
290 } else {
291 dev->read_subdev = s;
292 s->subdev_flags |= SDF_CMD_READ;
293 s->cancel = me4000_ai_cancel;
294 s->do_cmdtest = me4000_ai_do_cmd_test;
295 s->do_cmd = me4000_ai_do_cmd;
297 } else {
298 printk(KERN_WARNING
299 "comedi%d: me4000: me4000_attach(): No interrupt available\n",
300 dev->minor);
302 } else {
303 s->type = COMEDI_SUBD_UNUSED;
306 /*=========================================================================
307 Analog output subdevice
308 ========================================================================*/
310 s = dev->subdevices + 1;
312 if (thisboard->ao.count) {
313 s->type = COMEDI_SUBD_AO;
314 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
315 s->n_chan = thisboard->ao.count;
316 s->maxdata = 0xFFFF; /* 16 bit DAC */
317 s->range_table = &me4000_ao_range;
318 s->insn_write = me4000_ao_insn_write;
319 s->insn_read = me4000_ao_insn_read;
320 } else {
321 s->type = COMEDI_SUBD_UNUSED;
324 /*=========================================================================
325 Digital I/O subdevice
326 ========================================================================*/
328 s = dev->subdevices + 2;
330 if (thisboard->dio.count) {
331 s->type = COMEDI_SUBD_DIO;
332 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
333 s->n_chan = thisboard->dio.count * 8;
334 s->maxdata = 1;
335 s->range_table = &range_digital;
336 s->insn_bits = me4000_dio_insn_bits;
337 s->insn_config = me4000_dio_insn_config;
338 } else {
339 s->type = COMEDI_SUBD_UNUSED;
343 * Check for optoisolated ME-4000 version. If one the first
344 * port is a fixed output port and the second is a fixed input port.
346 if (!me4000_inl(dev, info->dio_context.dir_reg)) {
347 s->io_bits |= 0xFF;
348 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
349 info->dio_context.dir_reg);
352 /*=========================================================================
353 Counter subdevice
354 ========================================================================*/
356 s = dev->subdevices + 3;
358 if (thisboard->cnt.count) {
359 s->type = COMEDI_SUBD_COUNTER;
360 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
361 s->n_chan = thisboard->cnt.count;
362 s->maxdata = 0xFFFF; /* 16 bit counters */
363 s->insn_read = me4000_cnt_insn_read;
364 s->insn_write = me4000_cnt_insn_write;
365 s->insn_config = me4000_cnt_insn_config;
366 } else {
367 s->type = COMEDI_SUBD_UNUSED;
370 return 0;
373 static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
375 struct pci_dev *pci_device;
376 int result, i;
377 struct me4000_board *board;
379 CALL_PDEBUG("In me4000_probe()\n");
381 /* Allocate private memory */
382 if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
383 return -ENOMEM;
386 * Probe the device to determine what device in the series it is.
388 for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
389 pci_device != NULL;
390 pci_device =
391 pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
392 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
393 for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
394 if (me4000_boards[i].device_id ==
395 pci_device->device) {
396 /* Was a particular bus/slot requested? */
397 if ((it->options[0] != 0)
398 || (it->options[1] != 0)) {
399 /* Are we on the wrong bus/slot? */
400 if (pci_device->bus->number !=
401 it->options[0]
402 || PCI_SLOT(pci_device->
403 devfn) !=
404 it->options[1]) {
405 continue;
408 dev->board_ptr = me4000_boards + i;
409 board = (struct me4000_board *) dev->
410 board_ptr;
411 info->pci_dev_p = pci_device;
412 goto found;
418 printk(KERN_ERR
419 "comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
420 dev->minor, it->options[0], it->options[1]);
421 return -ENODEV;
423 found:
425 printk(KERN_INFO
426 "comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
427 dev->minor, me4000_boards[i].name, pci_device->bus->number,
428 PCI_SLOT(pci_device->devfn));
430 /* Set data in device structure */
431 dev->board_name = board->name;
433 /* Enable PCI device and request regions */
434 result = comedi_pci_enable(pci_device, dev->board_name);
435 if (result) {
436 printk(KERN_ERR
437 "comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
438 dev->minor);
439 return result;
442 /* Get the PCI base registers */
443 result = get_registers(dev, pci_device);
444 if (result) {
445 printk(KERN_ERR
446 "comedi%d: me4000: me4000_probe(): Cannot get registers\n",
447 dev->minor);
448 return result;
450 /* Initialize board info */
451 result = init_board_info(dev, pci_device);
452 if (result) {
453 printk(KERN_ERR
454 "comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
455 dev->minor);
456 return result;
459 /* Init analog output context */
460 result = init_ao_context(dev);
461 if (result) {
462 printk(KERN_ERR
463 "comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
464 dev->minor);
465 return result;
468 /* Init analog input context */
469 result = init_ai_context(dev);
470 if (result) {
471 printk(KERN_ERR
472 "comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
473 dev->minor);
474 return result;
477 /* Init digital I/O context */
478 result = init_dio_context(dev);
479 if (result) {
480 printk(KERN_ERR
481 "comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
482 dev->minor);
483 return result;
486 /* Init counter context */
487 result = init_cnt_context(dev);
488 if (result) {
489 printk(KERN_ERR
490 "comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
491 dev->minor);
492 return result;
495 /* Download the xilinx firmware */
496 result = xilinx_download(dev);
497 if (result) {
498 printk(KERN_ERR
499 "comedi%d: me4000: me4000_probe(): Can't download firmware\n",
500 dev->minor);
501 return result;
504 /* Make a hardware reset */
505 result = reset_board(dev);
506 if (result) {
507 printk(KERN_ERR
508 "comedi%d: me4000: me4000_probe(): Can't reset board\n",
509 dev->minor);
510 return result;
513 return 0;
516 static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
519 CALL_PDEBUG("In get_registers()\n");
521 /*--------------------------- plx regbase ---------------------------------*/
523 info->plx_regbase = pci_resource_start(pci_dev_p, 1);
524 if (info->plx_regbase == 0) {
525 printk(KERN_ERR
526 "comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
527 dev->minor);
528 return -ENODEV;
530 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
537 "comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
538 dev->minor);
539 return -ENODEV;
541 info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
543 /*--------------------------- timer regbase ------------------------------*/
545 info->timer_regbase = pci_resource_start(pci_dev_p, 3);
546 if (info->timer_regbase == 0) {
547 printk(KERN_ERR
548 "comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
549 dev->minor);
550 return -ENODEV;
552 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
554 /*--------------------------- program regbase ------------------------------*/
556 info->program_regbase = pci_resource_start(pci_dev_p, 5);
557 if (info->program_regbase == 0) {
558 printk(KERN_ERR
559 "comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
560 dev->minor);
561 return -ENODEV;
563 info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
565 return 0;
568 static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
570 int result;
572 CALL_PDEBUG("In init_board_info()\n");
574 /* Init spin locks */
575 /* spin_lock_init(&info->preload_lock); */
576 /* spin_lock_init(&info->ai_ctrl_lock); */
578 /* Get the serial number */
579 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
580 if (result != PCIBIOS_SUCCESSFUL)
581 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;
588 /* Get the vendor id */
589 info->vendor_id = pci_dev_p->vendor;
591 /* Get the device id */
592 info->device_id = pci_dev_p->device;
594 /* Get the irq assigned to the board */
595 info->irq = pci_dev_p->irq;
597 return 0;
600 static int init_ao_context(struct comedi_device *dev)
602 int i;
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;
610 switch (i) {
611 case 0:
612 info->ao_context[i].ctrl_reg =
613 info->me4000_regbase + ME4000_AO_00_CTRL_REG;
614 info->ao_context[i].status_reg =
615 info->me4000_regbase + ME4000_AO_00_STATUS_REG;
616 info->ao_context[i].fifo_reg =
617 info->me4000_regbase + ME4000_AO_00_FIFO_REG;
618 info->ao_context[i].single_reg =
619 info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
620 info->ao_context[i].timer_reg =
621 info->me4000_regbase + ME4000_AO_00_TIMER_REG;
622 info->ao_context[i].irq_status_reg =
623 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
624 info->ao_context[i].preload_reg =
625 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
626 break;
627 case 1:
628 info->ao_context[i].ctrl_reg =
629 info->me4000_regbase + ME4000_AO_01_CTRL_REG;
630 info->ao_context[i].status_reg =
631 info->me4000_regbase + ME4000_AO_01_STATUS_REG;
632 info->ao_context[i].fifo_reg =
633 info->me4000_regbase + ME4000_AO_01_FIFO_REG;
634 info->ao_context[i].single_reg =
635 info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
636 info->ao_context[i].timer_reg =
637 info->me4000_regbase + ME4000_AO_01_TIMER_REG;
638 info->ao_context[i].irq_status_reg =
639 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
640 info->ao_context[i].preload_reg =
641 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
642 break;
643 case 2:
644 info->ao_context[i].ctrl_reg =
645 info->me4000_regbase + ME4000_AO_02_CTRL_REG;
646 info->ao_context[i].status_reg =
647 info->me4000_regbase + ME4000_AO_02_STATUS_REG;
648 info->ao_context[i].fifo_reg =
649 info->me4000_regbase + ME4000_AO_02_FIFO_REG;
650 info->ao_context[i].single_reg =
651 info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
652 info->ao_context[i].timer_reg =
653 info->me4000_regbase + ME4000_AO_02_TIMER_REG;
654 info->ao_context[i].irq_status_reg =
655 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
656 info->ao_context[i].preload_reg =
657 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
658 break;
659 case 3:
660 info->ao_context[i].ctrl_reg =
661 info->me4000_regbase + ME4000_AO_03_CTRL_REG;
662 info->ao_context[i].status_reg =
663 info->me4000_regbase + ME4000_AO_03_STATUS_REG;
664 info->ao_context[i].fifo_reg =
665 info->me4000_regbase + ME4000_AO_03_FIFO_REG;
666 info->ao_context[i].single_reg =
667 info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
668 info->ao_context[i].timer_reg =
669 info->me4000_regbase + ME4000_AO_03_TIMER_REG;
670 info->ao_context[i].irq_status_reg =
671 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
672 info->ao_context[i].preload_reg =
673 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
674 break;
675 default:
676 break;
680 return 0;
683 static int init_ai_context(struct comedi_device *dev)
686 CALL_PDEBUG("In init_ai_context()\n");
688 info->ai_context.irq = info->irq;
690 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
691 info->ai_context.status_reg =
692 info->me4000_regbase + ME4000_AI_STATUS_REG;
693 info->ai_context.channel_list_reg =
694 info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
695 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
696 info->ai_context.chan_timer_reg =
697 info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
698 info->ai_context.chan_pre_timer_reg =
699 info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
700 info->ai_context.scan_timer_low_reg =
701 info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
702 info->ai_context.scan_timer_high_reg =
703 info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
704 info->ai_context.scan_pre_timer_low_reg =
705 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
706 info->ai_context.scan_pre_timer_high_reg =
707 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
708 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
709 info->ai_context.irq_status_reg =
710 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
711 info->ai_context.sample_counter_reg =
712 info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
714 return 0;
717 static int init_dio_context(struct comedi_device *dev)
720 CALL_PDEBUG("In init_dio_context()\n");
722 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
723 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
724 info->dio_context.port_0_reg =
725 info->me4000_regbase + ME4000_DIO_PORT_0_REG;
726 info->dio_context.port_1_reg =
727 info->me4000_regbase + ME4000_DIO_PORT_1_REG;
728 info->dio_context.port_2_reg =
729 info->me4000_regbase + ME4000_DIO_PORT_2_REG;
730 info->dio_context.port_3_reg =
731 info->me4000_regbase + ME4000_DIO_PORT_3_REG;
733 return 0;
736 static int init_cnt_context(struct comedi_device *dev)
739 CALL_PDEBUG("In init_cnt_context()\n");
741 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
742 info->cnt_context.counter_0_reg =
743 info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
744 info->cnt_context.counter_1_reg =
745 info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
746 info->cnt_context.counter_2_reg =
747 info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
749 return 0;
752 #define FIRMWARE_NOT_AVAILABLE 1
753 #if FIRMWARE_NOT_AVAILABLE
754 extern unsigned char *xilinx_firm;
755 #endif
757 static int xilinx_download(struct comedi_device *dev)
759 u32 value = 0;
760 wait_queue_head_t queue;
761 int idx = 0;
762 int size = 0;
764 CALL_PDEBUG("In xilinx_download()\n");
766 init_waitqueue_head(&queue);
769 * Set PLX local interrupt 2 polarity to high.
770 * Interrupt is thrown by init pin of xilinx.
772 outl(0x10, info->plx_regbase + PLX_INTCSR);
774 /* Set /CS and /WRITE of the Xilinx */
775 value = inl(info->plx_regbase + PLX_ICR);
776 value |= 0x100;
777 outl(value, info->plx_regbase + PLX_ICR);
779 /* Init Xilinx with CS1 */
780 inb(info->program_regbase + 0xC8);
782 /* Wait until /INIT pin is set */
783 udelay(20);
784 if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
785 printk(KERN_ERR
786 "comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
787 dev->minor);
788 return -EIO;
791 /* Reset /CS and /WRITE of the Xilinx */
792 value = inl(info->plx_regbase + PLX_ICR);
793 value &= ~0x100;
794 outl(value, info->plx_regbase + PLX_ICR);
795 if (FIRMWARE_NOT_AVAILABLE) {
796 comedi_error(dev,
797 "xilinx firmware unavailable due to licensing, aborting");
798 return -EIO;
799 } else {
800 /* Download Xilinx firmware */
801 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
802 (xilinx_firm[2] << 8) + xilinx_firm[3];
803 udelay(10);
805 for (idx = 0; idx < size; idx++) {
806 outb(xilinx_firm[16 + idx], info->program_regbase);
807 udelay(10);
809 /* Check if BUSY flag is low */
810 if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
811 printk(KERN_ERR
812 "comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
813 dev->minor, idx);
814 return -EIO;
819 /* If done flag is high download was successful */
820 if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
821 } else {
822 printk(KERN_ERR
823 "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
824 dev->minor);
825 printk(KERN_ERR
826 "comedi%d: me4000: xilinx_download(): Download not succesful\n",
827 dev->minor);
828 return -EIO;
831 /* Set /CS and /WRITE */
832 value = inl(info->plx_regbase + PLX_ICR);
833 value |= 0x100;
834 outl(value, info->plx_regbase + PLX_ICR);
836 return 0;
839 static int reset_board(struct comedi_device *dev)
841 unsigned long icr;
843 CALL_PDEBUG("In reset_board()\n");
845 /* Make a hardware reset */
846 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
847 icr |= 0x40000000;
848 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
849 icr &= ~0x40000000;
850 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
852 /* 0x8000 to the DACs means an output voltage of 0V */
853 me4000_outl(dev, 0x8000,
854 info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
855 me4000_outl(dev, 0x8000,
856 info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
857 me4000_outl(dev, 0x8000,
858 info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
859 me4000_outl(dev, 0x8000,
860 info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
862 /* Set both stop bits in the analog input control register */
863 me4000_outl(dev,
864 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
865 info->me4000_regbase + ME4000_AI_CTRL_REG);
867 /* Set both stop bits in the analog output control register */
868 me4000_outl(dev,
869 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
870 info->me4000_regbase + ME4000_AO_00_CTRL_REG);
871 me4000_outl(dev,
872 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
873 info->me4000_regbase + ME4000_AO_01_CTRL_REG);
874 me4000_outl(dev,
875 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
876 info->me4000_regbase + ME4000_AO_02_CTRL_REG);
877 me4000_outl(dev,
878 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
879 info->me4000_regbase + ME4000_AO_03_CTRL_REG);
881 /* Enable interrupts on the PLX */
882 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
884 /* Set the adustment register for AO demux */
885 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
886 info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
888 /* Set digital I/O direction for port 0 to output on isolated versions */
889 if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
890 me4000_outl(dev, 0x1,
891 info->me4000_regbase + ME4000_DIO_CTRL_REG);
894 return 0;
897 static int me4000_detach(struct comedi_device *dev)
899 CALL_PDEBUG("In me4000_detach()\n");
901 if (info) {
902 if (info->pci_dev_p) {
903 reset_board(dev);
904 if (info->plx_regbase)
905 comedi_pci_disable(info->pci_dev_p);
906 pci_dev_put(info->pci_dev_p);
910 return 0;
913 /*=============================================================================
914 Analog input section
915 ===========================================================================*/
917 static int me4000_ai_insn_read(struct comedi_device *dev,
918 struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
921 int chan = CR_CHAN(insn->chanspec);
922 int rang = CR_RANGE(insn->chanspec);
923 int aref = CR_AREF(insn->chanspec);
925 unsigned long entry = 0;
926 unsigned long tmp;
927 long lval;
929 CALL_PDEBUG("In me4000_ai_insn_read()\n");
931 if (insn->n == 0) {
932 return 0;
933 } else if (insn->n > 1) {
934 printk(KERN_ERR
935 "comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
936 dev->minor, insn->n);
937 return -EINVAL;
940 switch (rang) {
941 case 0:
942 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
943 break;
944 case 1:
945 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
946 break;
947 case 2:
948 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
949 break;
950 case 3:
951 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
952 break;
953 default:
954 printk(KERN_ERR
955 "comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
956 dev->minor);
957 return -EINVAL;
960 switch (aref) {
961 case AREF_GROUND:
962 case AREF_COMMON:
963 if (chan >= thisboard->ai.count) {
964 printk(KERN_ERR
965 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
966 dev->minor);
967 return -EINVAL;
969 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
970 break;
972 case AREF_DIFF:
973 if (rang == 0 || rang == 1) {
974 printk(KERN_ERR
975 "comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
976 dev->minor);
977 return -EINVAL;
980 if (chan >= thisboard->ai.diff_count) {
981 printk(KERN_ERR
982 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
983 dev->minor);
984 return -EINVAL;
986 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
987 break;
988 default:
989 printk(KERN_ERR
990 "comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
991 dev->minor);
992 return -EINVAL;
995 entry |= ME4000_AI_LIST_LAST_ENTRY;
997 /* Clear channel list, data fifo and both stop bits */
998 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
999 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1000 ME4000_AI_CTRL_BIT_DATA_FIFO |
1001 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1002 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1004 /* Set the acquisition mode to single */
1005 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
1006 ME4000_AI_CTRL_BIT_MODE_2);
1007 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1009 /* Enable channel list and data fifo */
1010 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
1011 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1013 /* Generate channel list entry */
1014 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1016 /* Set the timer to maximum sample rate */
1017 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
1018 me4000_outl(dev, ME4000_AI_MIN_TICKS,
1019 info->ai_context.chan_pre_timer_reg);
1021 /* Start conversion by dummy read */
1022 me4000_inl(dev, info->ai_context.start_reg);
1024 /* Wait until ready */
1025 udelay(10);
1026 if (!(me4000_inl(dev, info->ai_context.
1027 status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) {
1028 printk(KERN_ERR
1029 "comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
1030 dev->minor);
1031 return -EIO;
1034 /* Read value from data fifo */
1035 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
1036 data[0] = lval ^ 0x8000;
1038 return 1;
1041 static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1043 unsigned long tmp;
1045 CALL_PDEBUG("In me4000_ai_cancel()\n");
1047 /* Stop any running conversion */
1048 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1049 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1050 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1052 /* Clear the control register */
1053 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1055 return 0;
1058 static int ai_check_chanlist(struct comedi_device *dev,
1059 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1061 int aref;
1062 int i;
1064 CALL_PDEBUG("In ai_check_chanlist()\n");
1066 /* Check whether a channel list is available */
1067 if (!cmd->chanlist_len) {
1068 printk(KERN_ERR
1069 "comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
1070 dev->minor);
1071 return -EINVAL;
1074 /* Check the channel list size */
1075 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
1076 printk(KERN_ERR
1077 "comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
1078 dev->minor);
1079 return -EINVAL;
1082 /* Check the pointer */
1083 if (!cmd->chanlist) {
1084 printk(KERN_ERR
1085 "comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
1086 dev->minor);
1087 return -EFAULT;
1090 /* Check whether aref is equal for all entries */
1091 aref = CR_AREF(cmd->chanlist[0]);
1092 for (i = 0; i < cmd->chanlist_len; i++) {
1093 if (CR_AREF(cmd->chanlist[i]) != aref) {
1094 printk(KERN_ERR
1095 "comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
1096 dev->minor);
1097 return -EINVAL;
1101 /* Check whether channels are available for this ending */
1102 if (aref == SDF_DIFF) {
1103 for (i = 0; i < cmd->chanlist_len; i++) {
1104 if (CR_CHAN(cmd->chanlist[i]) >=
1105 thisboard->ai.diff_count) {
1106 printk(KERN_ERR
1107 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1108 dev->minor);
1109 return -EINVAL;
1112 } else {
1113 for (i = 0; i < cmd->chanlist_len; i++) {
1114 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
1115 printk(KERN_ERR
1116 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1117 dev->minor);
1118 return -EINVAL;
1123 /* Check if bipolar is set for all entries when in differential mode */
1124 if (aref == SDF_DIFF) {
1125 for (i = 0; i < cmd->chanlist_len; i++) {
1126 if (CR_RANGE(cmd->chanlist[i]) != 1 &&
1127 CR_RANGE(cmd->chanlist[i]) != 2) {
1128 printk(KERN_ERR
1129 "comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
1130 dev->minor);
1131 return -EINVAL;
1136 return 0;
1139 static int ai_round_cmd_args(struct comedi_device *dev,
1140 struct comedi_subdevice *s,
1141 struct comedi_cmd *cmd,
1142 unsigned int *init_ticks,
1143 unsigned int *scan_ticks, unsigned int *chan_ticks)
1146 int rest;
1148 CALL_PDEBUG("In ai_round_cmd_args()\n");
1150 *init_ticks = 0;
1151 *scan_ticks = 0;
1152 *chan_ticks = 0;
1154 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1155 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1156 cmd->scan_begin_arg);
1157 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1159 if (cmd->start_arg) {
1160 *init_ticks = (cmd->start_arg * 33) / 1000;
1161 rest = (cmd->start_arg * 33) % 1000;
1163 if (cmd->flags & TRIG_ROUND_NEAREST) {
1164 if (rest > 33)
1165 (*init_ticks)++;
1166 } else if (cmd->flags & TRIG_ROUND_UP) {
1167 if (rest)
1168 (*init_ticks)++;
1172 if (cmd->scan_begin_arg) {
1173 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1174 rest = (cmd->scan_begin_arg * 33) % 1000;
1176 if (cmd->flags & TRIG_ROUND_NEAREST) {
1177 if (rest > 33)
1178 (*scan_ticks)++;
1179 } else if (cmd->flags & TRIG_ROUND_UP) {
1180 if (rest)
1181 (*scan_ticks)++;
1185 if (cmd->convert_arg) {
1186 *chan_ticks = (cmd->convert_arg * 33) / 1000;
1187 rest = (cmd->convert_arg * 33) % 1000;
1189 if (cmd->flags & TRIG_ROUND_NEAREST) {
1190 if (rest > 33)
1191 (*chan_ticks)++;
1192 } else if (cmd->flags & TRIG_ROUND_UP) {
1193 if (rest)
1194 (*chan_ticks)++;
1198 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1199 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1200 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1202 return 0;
1205 static void ai_write_timer(struct comedi_device *dev,
1206 unsigned int init_ticks,
1207 unsigned int scan_ticks, unsigned int chan_ticks)
1210 CALL_PDEBUG("In ai_write_timer()\n");
1212 me4000_outl(dev, init_ticks - 1,
1213 info->ai_context.scan_pre_timer_low_reg);
1214 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1216 if (scan_ticks) {
1217 me4000_outl(dev, scan_ticks - 1,
1218 info->ai_context.scan_timer_low_reg);
1219 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1222 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1223 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1226 static int ai_prepare(struct comedi_device *dev,
1227 struct comedi_subdevice *s,
1228 struct comedi_cmd *cmd,
1229 unsigned int init_ticks,
1230 unsigned int scan_ticks, unsigned int chan_ticks)
1233 unsigned long tmp = 0;
1235 CALL_PDEBUG("In ai_prepare()\n");
1237 /* Write timer arguments */
1238 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1240 /* Reset control register */
1241 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1243 /* Start sources */
1244 if ((cmd->start_src == TRIG_EXT &&
1245 cmd->scan_begin_src == TRIG_TIMER &&
1246 cmd->convert_src == TRIG_TIMER) ||
1247 (cmd->start_src == TRIG_EXT &&
1248 cmd->scan_begin_src == TRIG_FOLLOW &&
1249 cmd->convert_src == TRIG_TIMER)) {
1250 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
1251 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1252 ME4000_AI_CTRL_BIT_DATA_FIFO;
1253 } else if (cmd->start_src == TRIG_EXT &&
1254 cmd->scan_begin_src == TRIG_EXT &&
1255 cmd->convert_src == TRIG_TIMER) {
1256 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
1257 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1258 ME4000_AI_CTRL_BIT_DATA_FIFO;
1259 } else if (cmd->start_src == TRIG_EXT &&
1260 cmd->scan_begin_src == TRIG_EXT &&
1261 cmd->convert_src == TRIG_EXT) {
1262 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1263 ME4000_AI_CTRL_BIT_MODE_1 |
1264 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1265 ME4000_AI_CTRL_BIT_DATA_FIFO;
1266 } else {
1267 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1268 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1269 ME4000_AI_CTRL_BIT_DATA_FIFO;
1272 /* Stop triggers */
1273 if (cmd->stop_src == TRIG_COUNT) {
1274 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
1275 info->ai_context.sample_counter_reg);
1276 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1277 } else if (cmd->stop_src == TRIG_NONE &&
1278 cmd->scan_end_src == TRIG_COUNT) {
1279 me4000_outl(dev, cmd->scan_end_arg,
1280 info->ai_context.sample_counter_reg);
1281 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1282 } else {
1283 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1286 /* Write the setup to the control register */
1287 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1289 /* Write the channel list */
1290 ai_write_chanlist(dev, s, cmd);
1292 return 0;
1295 static int ai_write_chanlist(struct comedi_device *dev,
1296 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1298 unsigned int entry;
1299 unsigned int chan;
1300 unsigned int rang;
1301 unsigned int aref;
1302 int i;
1304 CALL_PDEBUG("In ai_write_chanlist()\n");
1306 for (i = 0; i < cmd->chanlist_len; i++) {
1307 chan = CR_CHAN(cmd->chanlist[i]);
1308 rang = CR_RANGE(cmd->chanlist[i]);
1309 aref = CR_AREF(cmd->chanlist[i]);
1311 entry = chan;
1313 if (rang == 0) {
1314 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1315 } else if (rang == 1) {
1316 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1317 } else if (rang == 2) {
1318 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1319 } else {
1320 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1323 if (aref == SDF_DIFF) {
1324 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1325 } else {
1326 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1329 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1332 return 0;
1335 static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1337 int err;
1338 unsigned int init_ticks = 0;
1339 unsigned int scan_ticks = 0;
1340 unsigned int chan_ticks = 0;
1341 struct comedi_cmd *cmd = &s->async->cmd;
1343 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1345 /* Reset the analog input */
1346 err = me4000_ai_cancel(dev, s);
1347 if (err)
1348 return err;
1350 /* Round the timer arguments */
1351 err = ai_round_cmd_args(dev,
1352 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1353 if (err)
1354 return err;
1356 /* Prepare the AI for acquisition */
1357 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
1358 if (err)
1359 return err;
1361 /* Start acquistion by dummy read */
1362 me4000_inl(dev, info->ai_context.start_reg);
1364 return 0;
1368 * me4000_ai_do_cmd_test():
1370 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1371 * - success
1372 * - invalid source
1373 * - source conflict
1374 * - invalid argument
1375 * - argument conflict
1376 * - invalid chanlist
1377 * So I tried to adopt this scheme.
1379 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
1380 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1383 unsigned int init_ticks;
1384 unsigned int chan_ticks;
1385 unsigned int scan_ticks;
1386 int err = 0;
1388 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1390 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev);
1391 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags);
1392 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n",
1393 cmd->start_src);
1394 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n",
1395 cmd->start_arg);
1396 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1397 cmd->scan_begin_src);
1398 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1399 cmd->scan_begin_arg);
1400 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n",
1401 cmd->convert_src);
1402 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n",
1403 cmd->convert_arg);
1404 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n",
1405 cmd->scan_end_src);
1406 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n",
1407 cmd->scan_end_arg);
1408 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n",
1409 cmd->stop_src);
1410 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg);
1411 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n",
1412 (unsigned int)cmd->chanlist);
1413 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n",
1414 cmd->chanlist_len);
1416 /* Only rounding flags are implemented */
1417 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1419 /* Round the timer arguments */
1420 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1423 * Stage 1. Check if the trigger sources are generally valid.
1425 switch (cmd->start_src) {
1426 case TRIG_NOW:
1427 case TRIG_EXT:
1428 break;
1429 case TRIG_ANY:
1430 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1431 err++;
1432 break;
1433 default:
1434 printk(KERN_ERR
1435 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
1436 dev->minor);
1437 cmd->start_src = TRIG_NOW;
1438 err++;
1440 switch (cmd->scan_begin_src) {
1441 case TRIG_FOLLOW:
1442 case TRIG_TIMER:
1443 case TRIG_EXT:
1444 break;
1445 case TRIG_ANY:
1446 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1447 err++;
1448 break;
1449 default:
1450 printk(KERN_ERR
1451 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
1452 dev->minor);
1453 cmd->scan_begin_src = TRIG_FOLLOW;
1454 err++;
1456 switch (cmd->convert_src) {
1457 case TRIG_TIMER:
1458 case TRIG_EXT:
1459 break;
1460 case TRIG_ANY:
1461 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1462 err++;
1463 break;
1464 default:
1465 printk(KERN_ERR
1466 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
1467 dev->minor);
1468 cmd->convert_src = TRIG_TIMER;
1469 err++;
1471 switch (cmd->scan_end_src) {
1472 case TRIG_NONE:
1473 case TRIG_COUNT:
1474 break;
1475 case TRIG_ANY:
1476 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1477 err++;
1478 break;
1479 default:
1480 printk(KERN_ERR
1481 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
1482 dev->minor);
1483 cmd->scan_end_src = TRIG_NONE;
1484 err++;
1486 switch (cmd->stop_src) {
1487 case TRIG_NONE:
1488 case TRIG_COUNT:
1489 break;
1490 case TRIG_ANY:
1491 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1492 err++;
1493 break;
1494 default:
1495 printk(KERN_ERR
1496 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
1497 dev->minor);
1498 cmd->stop_src = TRIG_NONE;
1499 err++;
1501 if (err)
1502 return 1;
1505 * Stage 2. Check for trigger source conflicts.
1507 if (cmd->start_src == TRIG_NOW &&
1508 cmd->scan_begin_src == TRIG_TIMER &&
1509 cmd->convert_src == TRIG_TIMER) {
1510 } else if (cmd->start_src == TRIG_NOW &&
1511 cmd->scan_begin_src == TRIG_FOLLOW &&
1512 cmd->convert_src == TRIG_TIMER) {
1513 } else if (cmd->start_src == TRIG_EXT &&
1514 cmd->scan_begin_src == TRIG_TIMER &&
1515 cmd->convert_src == TRIG_TIMER) {
1516 } else if (cmd->start_src == TRIG_EXT &&
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_EXT &&
1521 cmd->convert_src == TRIG_TIMER) {
1522 } else if (cmd->start_src == TRIG_EXT &&
1523 cmd->scan_begin_src == TRIG_EXT &&
1524 cmd->convert_src == TRIG_EXT) {
1525 } else {
1526 printk(KERN_ERR
1527 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
1528 dev->minor);
1529 cmd->start_src = TRIG_NOW;
1530 cmd->scan_begin_src = TRIG_FOLLOW;
1531 cmd->convert_src = TRIG_TIMER;
1532 err++;
1535 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
1536 } else if (cmd->stop_src == TRIG_COUNT &&
1537 cmd->scan_end_src == TRIG_NONE) {
1538 } else if (cmd->stop_src == TRIG_NONE &&
1539 cmd->scan_end_src == TRIG_COUNT) {
1540 } else if (cmd->stop_src == TRIG_COUNT &&
1541 cmd->scan_end_src == TRIG_COUNT) {
1542 } else {
1543 printk(KERN_ERR
1544 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
1545 dev->minor);
1546 cmd->stop_src = TRIG_NONE;
1547 cmd->scan_end_src = TRIG_NONE;
1548 err++;
1550 if (err)
1551 return 2;
1554 * Stage 3. Check if arguments are generally valid.
1556 if (cmd->chanlist_len < 1) {
1557 printk(KERN_ERR
1558 "comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
1559 dev->minor);
1560 cmd->chanlist_len = 1;
1561 err++;
1563 if (init_ticks < 66) {
1564 printk(KERN_ERR
1565 "comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
1566 dev->minor);
1567 cmd->start_arg = 2000;
1568 err++;
1570 if (scan_ticks && scan_ticks < 67) {
1571 printk(KERN_ERR
1572 "comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
1573 dev->minor);
1574 cmd->scan_begin_arg = 2031;
1575 err++;
1577 if (chan_ticks < 66) {
1578 printk(KERN_ERR
1579 "comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
1580 dev->minor);
1581 cmd->convert_arg = 2000;
1582 err++;
1585 if (err)
1586 return 3;
1589 * Stage 4. Check for argument conflicts.
1591 if (cmd->start_src == TRIG_NOW &&
1592 cmd->scan_begin_src == TRIG_TIMER &&
1593 cmd->convert_src == TRIG_TIMER) {
1595 /* Check timer arguments */
1596 if (init_ticks < ME4000_AI_MIN_TICKS) {
1597 printk(KERN_ERR
1598 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1599 dev->minor);
1600 cmd->start_arg = 2000; /* 66 ticks at least */
1601 err++;
1603 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1604 printk(KERN_ERR
1605 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1606 dev->minor);
1607 cmd->convert_arg = 2000; /* 66 ticks at least */
1608 err++;
1610 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1611 printk(KERN_ERR
1612 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1613 dev->minor);
1614 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
1615 err++;
1617 } else if (cmd->start_src == TRIG_NOW &&
1618 cmd->scan_begin_src == TRIG_FOLLOW &&
1619 cmd->convert_src == TRIG_TIMER) {
1621 /* Check timer arguments */
1622 if (init_ticks < ME4000_AI_MIN_TICKS) {
1623 printk(KERN_ERR
1624 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1625 dev->minor);
1626 cmd->start_arg = 2000; /* 66 ticks at least */
1627 err++;
1629 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1630 printk(KERN_ERR
1631 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1632 dev->minor);
1633 cmd->convert_arg = 2000; /* 66 ticks at least */
1634 err++;
1636 } else if (cmd->start_src == TRIG_EXT &&
1637 cmd->scan_begin_src == TRIG_TIMER &&
1638 cmd->convert_src == TRIG_TIMER) {
1640 /* Check timer arguments */
1641 if (init_ticks < ME4000_AI_MIN_TICKS) {
1642 printk(KERN_ERR
1643 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1644 dev->minor);
1645 cmd->start_arg = 2000; /* 66 ticks at least */
1646 err++;
1648 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1649 printk(KERN_ERR
1650 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1651 dev->minor);
1652 cmd->convert_arg = 2000; /* 66 ticks at least */
1653 err++;
1655 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1656 printk(KERN_ERR
1657 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1658 dev->minor);
1659 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
1660 err++;
1662 } else if (cmd->start_src == TRIG_EXT &&
1663 cmd->scan_begin_src == TRIG_FOLLOW &&
1664 cmd->convert_src == TRIG_TIMER) {
1666 /* Check timer arguments */
1667 if (init_ticks < ME4000_AI_MIN_TICKS) {
1668 printk(KERN_ERR
1669 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1670 dev->minor);
1671 cmd->start_arg = 2000; /* 66 ticks at least */
1672 err++;
1674 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1675 printk(KERN_ERR
1676 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1677 dev->minor);
1678 cmd->convert_arg = 2000; /* 66 ticks at least */
1679 err++;
1681 } else if (cmd->start_src == TRIG_EXT &&
1682 cmd->scan_begin_src == TRIG_EXT &&
1683 cmd->convert_src == TRIG_TIMER) {
1685 /* Check timer arguments */
1686 if (init_ticks < ME4000_AI_MIN_TICKS) {
1687 printk(KERN_ERR
1688 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1689 dev->minor);
1690 cmd->start_arg = 2000; /* 66 ticks at least */
1691 err++;
1693 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1694 printk(KERN_ERR
1695 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1696 dev->minor);
1697 cmd->convert_arg = 2000; /* 66 ticks at least */
1698 err++;
1700 } else if (cmd->start_src == TRIG_EXT &&
1701 cmd->scan_begin_src == TRIG_EXT &&
1702 cmd->convert_src == TRIG_EXT) {
1704 /* Check timer arguments */
1705 if (init_ticks < ME4000_AI_MIN_TICKS) {
1706 printk(KERN_ERR
1707 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1708 dev->minor);
1709 cmd->start_arg = 2000; /* 66 ticks at least */
1710 err++;
1713 if (cmd->stop_src == TRIG_COUNT) {
1714 if (cmd->stop_arg == 0) {
1715 printk(KERN_ERR
1716 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
1717 dev->minor);
1718 cmd->stop_arg = 1;
1719 err++;
1722 if (cmd->scan_end_src == TRIG_COUNT) {
1723 if (cmd->scan_end_arg == 0) {
1724 printk(KERN_ERR
1725 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1726 dev->minor);
1727 cmd->scan_end_arg = 1;
1728 err++;
1732 if (err)
1733 return 4;
1736 * Stage 5. Check the channel list.
1738 if (ai_check_chanlist(dev, s, cmd))
1739 return 5;
1741 return 0;
1744 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1746 unsigned int tmp;
1747 struct comedi_device *dev = dev_id;
1748 struct comedi_subdevice *s = dev->subdevices;
1749 struct me4000_ai_context *ai_context = &info->ai_context;
1750 int i;
1751 int c = 0;
1752 long lval;
1754 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1756 if (!dev->attached) {
1757 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1758 return IRQ_NONE;
1761 /* Reset all events */
1762 s->async->events = 0;
1764 /* Check if irq number is right */
1765 if (irq != ai_context->irq) {
1766 printk(KERN_ERR
1767 "comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
1768 dev->minor, irq);
1769 return IRQ_HANDLED;
1772 if (me4000_inl(dev,
1773 ai_context->
1774 irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) {
1775 ISR_PDEBUG
1776 ("me4000_ai_isr(): Fifo half full interrupt occured\n");
1778 /* Read status register to find out what happened */
1779 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1781 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1782 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1783 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1784 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1785 c = ME4000_AI_FIFO_COUNT;
1787 /* FIFO overflow, so stop conversion and disable all interrupts */
1788 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1789 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1790 ME4000_AI_CTRL_BIT_SC_IRQ);
1791 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1793 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1795 printk(KERN_ERR
1796 "comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
1797 dev->minor);
1798 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1799 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1800 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1801 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1803 s->async->events |= COMEDI_CB_BLOCK;
1805 c = ME4000_AI_FIFO_COUNT / 2;
1806 } else {
1807 printk(KERN_ERR
1808 "comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
1809 dev->minor);
1810 c = 0;
1812 /* Undefined state, so stop conversion and disable all interrupts */
1813 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1814 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1815 ME4000_AI_CTRL_BIT_SC_IRQ);
1816 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1818 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1820 printk(KERN_ERR
1821 "comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
1822 dev->minor);
1825 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1827 for (i = 0; i < c; i++) {
1828 /* Read value from data fifo */
1829 lval = inl(ai_context->data_reg) & 0xFFFF;
1830 lval ^= 0x8000;
1832 if (!comedi_buf_put(s->async, lval)) {
1833 /* Buffer overflow, so stop conversion and disable all interrupts */
1834 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1835 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1836 ME4000_AI_CTRL_BIT_SC_IRQ);
1837 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1839 s->async->events |= COMEDI_CB_OVERFLOW;
1841 printk(KERN_ERR
1842 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1843 dev->minor);
1845 break;
1849 /* Work is done, so reset the interrupt */
1850 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1851 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1852 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1853 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1854 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1857 if (me4000_inl(dev,
1858 ai_context->
1859 irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
1860 ISR_PDEBUG
1861 ("me4000_ai_isr(): Sample counter interrupt occured\n");
1863 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1865 /* Acquisition is complete, so stop conversion and disable all interrupts */
1866 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1867 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1868 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1869 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1871 /* Poll data until fifo empty */
1872 while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
1873 /* Read value from data fifo */
1874 lval = inl(ai_context->data_reg) & 0xFFFF;
1875 lval ^= 0x8000;
1877 if (!comedi_buf_put(s->async, lval)) {
1878 printk(KERN_ERR
1879 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1880 dev->minor);
1881 s->async->events |= COMEDI_CB_OVERFLOW;
1882 break;
1886 /* Work is done, so reset the interrupt */
1887 ISR_PDEBUG
1888 ("me4000_ai_isr(): Reset interrupt from sample counter\n");
1889 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1890 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1891 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1892 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1895 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1897 if (s->async->events)
1898 comedi_event(dev, s);
1900 return IRQ_HANDLED;
1903 /*=============================================================================
1904 Analog output section
1905 ===========================================================================*/
1907 static int me4000_ao_insn_write(struct comedi_device *dev,
1908 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1911 int chan = CR_CHAN(insn->chanspec);
1912 int rang = CR_RANGE(insn->chanspec);
1913 int aref = CR_AREF(insn->chanspec);
1914 unsigned long tmp;
1916 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1918 if (insn->n == 0) {
1919 return 0;
1920 } else if (insn->n > 1) {
1921 printk(KERN_ERR
1922 "comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
1923 dev->minor, insn->n);
1924 return -EINVAL;
1927 if (chan >= thisboard->ao.count) {
1928 printk(KERN_ERR
1929 "comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
1930 dev->minor, insn->n);
1931 return -EINVAL;
1934 if (rang != 0) {
1935 printk(KERN_ERR
1936 "comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
1937 dev->minor, insn->n);
1938 return -EINVAL;
1941 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1942 printk(KERN_ERR
1943 "comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
1944 dev->minor, insn->n);
1945 return -EINVAL;
1948 /* Stop any running conversion */
1949 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
1950 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1951 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
1953 /* Clear control register and set to single mode */
1954 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
1956 /* Write data value */
1957 me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
1959 /* Store in the mirror */
1960 info->ao_context[chan].mirror = data[0];
1962 return 1;
1965 static int me4000_ao_insn_read(struct comedi_device *dev,
1966 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1968 int chan = CR_CHAN(insn->chanspec);
1970 if (insn->n == 0) {
1971 return 0;
1972 } else if (insn->n > 1) {
1973 printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
1974 return -EINVAL;
1977 data[0] = info->ao_context[chan].mirror;
1979 return 1;
1982 /*=============================================================================
1983 Digital I/O section
1984 ===========================================================================*/
1986 static int me4000_dio_insn_bits(struct comedi_device *dev,
1987 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1990 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
1992 /* Length of data must be 2 (mask and new data, see below) */
1993 if (insn->n == 0)
1994 return 0;
1996 if (insn->n != 2) {
1997 printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
1998 return -EINVAL;
2002 * The insn data consists of a mask in data[0] and the new data
2003 * in data[1]. The mask defines which bits we are concerning about.
2004 * The new data must be anded with the mask.
2005 * Each channel corresponds to a bit.
2007 if (data[0]) {
2008 /* Check if requested ports are configured for output */
2009 if ((s->io_bits & data[0]) != data[0])
2010 return -EIO;
2012 s->state &= ~data[0];
2013 s->state |= data[0] & data[1];
2015 /* Write out the new digital output lines */
2016 me4000_outl(dev, (s->state >> 0) & 0xFF,
2017 info->dio_context.port_0_reg);
2018 me4000_outl(dev, (s->state >> 8) & 0xFF,
2019 info->dio_context.port_1_reg);
2020 me4000_outl(dev, (s->state >> 16) & 0xFF,
2021 info->dio_context.port_2_reg);
2022 me4000_outl(dev, (s->state >> 24) & 0xFF,
2023 info->dio_context.port_3_reg);
2026 /* On return, data[1] contains the value of
2027 the digital input and output lines. */
2028 data[1] =
2029 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
2030 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
2031 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
2032 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
2034 return 2;
2037 static int me4000_dio_insn_config(struct comedi_device *dev,
2038 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2040 unsigned long tmp;
2041 int chan = CR_CHAN(insn->chanspec);
2043 CALL_PDEBUG("In me4000_dio_insn_config()\n");
2045 if (data[0] == INSN_CONFIG_DIO_QUERY) {
2046 data[1] =
2047 (s->
2048 io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2049 return insn->n;
2053 * The input or output configuration of each digital line is
2054 * configured by a special insn_config instruction. chanspec
2055 * contains the channel to be changed, and data[0] contains the
2056 * value COMEDI_INPUT or COMEDI_OUTPUT.
2057 * On the ME-4000 it is only possible to switch port wise (8 bit)
2060 tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
2062 if (data[0] == COMEDI_OUTPUT) {
2063 if (chan < 8) {
2064 s->io_bits |= 0xFF;
2065 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2066 ME4000_DIO_CTRL_BIT_MODE_1);
2067 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
2068 } else if (chan < 16) {
2070 * Chech for optoisolated ME-4000 version. If one the first
2071 * port is a fixed output port and the second is a fixed input port.
2073 if (!me4000_inl(dev, info->dio_context.dir_reg))
2074 return -ENODEV;
2076 s->io_bits |= 0xFF00;
2077 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2078 ME4000_DIO_CTRL_BIT_MODE_3);
2079 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
2080 } else if (chan < 24) {
2081 s->io_bits |= 0xFF0000;
2082 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2083 ME4000_DIO_CTRL_BIT_MODE_5);
2084 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2085 } else if (chan < 32) {
2086 s->io_bits |= 0xFF000000;
2087 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2088 ME4000_DIO_CTRL_BIT_MODE_7);
2089 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2090 } else {
2091 return -EINVAL;
2093 } else {
2094 if (chan < 8) {
2096 * Chech for optoisolated ME-4000 version. If one the first
2097 * port is a fixed output port and the second is a fixed input port.
2099 if (!me4000_inl(dev, info->dio_context.dir_reg))
2100 return -ENODEV;
2102 s->io_bits &= ~0xFF;
2103 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2104 ME4000_DIO_CTRL_BIT_MODE_1);
2105 } else if (chan < 16) {
2106 s->io_bits &= ~0xFF00;
2107 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2108 ME4000_DIO_CTRL_BIT_MODE_3);
2109 } else if (chan < 24) {
2110 s->io_bits &= ~0xFF0000;
2111 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2112 ME4000_DIO_CTRL_BIT_MODE_5);
2113 } else if (chan < 32) {
2114 s->io_bits &= ~0xFF000000;
2115 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2116 ME4000_DIO_CTRL_BIT_MODE_7);
2117 } else {
2118 return -EINVAL;
2122 me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2124 return 1;
2127 /*=============================================================================
2128 Counter section
2129 ===========================================================================*/
2131 static int cnt_reset(struct comedi_device *dev, unsigned int channel)
2134 CALL_PDEBUG("In cnt_reset()\n");
2136 switch (channel) {
2137 case 0:
2138 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2139 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2140 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2141 break;
2142 case 1:
2143 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2144 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2145 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2146 break;
2147 case 2:
2148 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2149 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2150 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2151 break;
2152 default:
2153 printk(KERN_ERR
2154 "comedi%d: me4000: cnt_reset(): Invalid channel\n",
2155 dev->minor);
2156 return -EINVAL;
2159 return 0;
2162 static int cnt_config(struct comedi_device *dev, unsigned int channel,
2163 unsigned int mode)
2165 int tmp = 0;
2167 CALL_PDEBUG("In cnt_config()\n");
2169 switch (channel) {
2170 case 0:
2171 tmp |= ME4000_CNT_COUNTER_0;
2172 break;
2173 case 1:
2174 tmp |= ME4000_CNT_COUNTER_1;
2175 break;
2176 case 2:
2177 tmp |= ME4000_CNT_COUNTER_2;
2178 break;
2179 default:
2180 printk(KERN_ERR
2181 "comedi%d: me4000: cnt_config(): Invalid channel\n",
2182 dev->minor);
2183 return -EINVAL;
2186 switch (mode) {
2187 case 0:
2188 tmp |= ME4000_CNT_MODE_0;
2189 break;
2190 case 1:
2191 tmp |= ME4000_CNT_MODE_1;
2192 break;
2193 case 2:
2194 tmp |= ME4000_CNT_MODE_2;
2195 break;
2196 case 3:
2197 tmp |= ME4000_CNT_MODE_3;
2198 break;
2199 case 4:
2200 tmp |= ME4000_CNT_MODE_4;
2201 break;
2202 case 5:
2203 tmp |= ME4000_CNT_MODE_5;
2204 break;
2205 default:
2206 printk(KERN_ERR
2207 "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2208 dev->minor);
2209 return -EINVAL;
2212 /* Write the control word */
2213 tmp |= 0x30;
2214 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2216 return 0;
2219 static int me4000_cnt_insn_config(struct comedi_device *dev,
2220 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2223 int err;
2225 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2227 switch (data[0]) {
2228 case GPCT_RESET:
2229 if (insn->n != 1) {
2230 printk(KERN_ERR
2231 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2232 dev->minor, insn->n);
2233 return -EINVAL;
2236 err = cnt_reset(dev, insn->chanspec);
2237 if (err)
2238 return err;
2239 break;
2240 case GPCT_SET_OPERATION:
2241 if (insn->n != 2) {
2242 printk(KERN_ERR
2243 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2244 dev->minor, insn->n);
2245 return -EINVAL;
2248 err = cnt_config(dev, insn->chanspec, data[1]);
2249 if (err)
2250 return err;
2251 break;
2252 default:
2253 printk(KERN_ERR
2254 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
2255 dev->minor);
2256 return -EINVAL;
2259 return 2;
2262 static int me4000_cnt_insn_read(struct comedi_device *dev,
2263 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2266 unsigned short tmp;
2268 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2270 if (insn->n == 0)
2271 return 0;
2273 if (insn->n > 1) {
2274 printk(KERN_ERR
2275 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
2276 dev->minor, insn->n);
2277 return -EINVAL;
2280 switch (insn->chanspec) {
2281 case 0:
2282 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2283 data[0] = tmp;
2284 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2285 data[0] |= tmp << 8;
2286 break;
2287 case 1:
2288 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2289 data[0] = tmp;
2290 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2291 data[0] |= tmp << 8;
2292 break;
2293 case 2:
2294 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2295 data[0] = tmp;
2296 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2297 data[0] |= tmp << 8;
2298 break;
2299 default:
2300 printk(KERN_ERR
2301 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
2302 dev->minor, insn->chanspec);
2303 return -EINVAL;
2306 return 1;
2309 static int me4000_cnt_insn_write(struct comedi_device *dev,
2310 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2313 unsigned short tmp;
2315 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2317 if (insn->n == 0) {
2318 return 0;
2319 } else if (insn->n > 1) {
2320 printk(KERN_ERR
2321 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
2322 dev->minor, insn->n);
2323 return -EINVAL;
2326 switch (insn->chanspec) {
2327 case 0:
2328 tmp = data[0] & 0xFF;
2329 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2330 tmp = (data[0] >> 8) & 0xFF;
2331 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2332 break;
2333 case 1:
2334 tmp = data[0] & 0xFF;
2335 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2336 tmp = (data[0] >> 8) & 0xFF;
2337 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2338 break;
2339 case 2:
2340 tmp = data[0] & 0xFF;
2341 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2342 tmp = (data[0] >> 8) & 0xFF;
2343 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2344 break;
2345 default:
2346 printk(KERN_ERR
2347 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
2348 dev->minor, insn->chanspec);
2349 return -EINVAL;
2352 return 1;
2355 COMEDI_PCI_INITCLEANUP(driver_me4000, me4000_pci_table);