me4000.c revision 51a6c8d05823610a8a7bc0d2c8dc64531389c4b5
1/* 2 comedi/drivers/me4000.c 3 Source code for the Meilhaus ME-4000 board family. 4 5 COMEDI - Linux Control and Measurement Device Interface 6 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 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. 21 22 */ 23/* 24Driver: me4000 25Description: Meilhaus ME-4000 series boards 26Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is 27Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>) 28Updated: Mon, 18 Mar 2002 15:34:01 -0800 29Status: broken (no support for loading firmware) 30 31Supports: 32 33 - Analog Input 34 - Analog Output 35 - Digital I/O 36 - Counter 37 38Configuration Options: 39 40 [0] - PCI bus number (optional) 41 [1] - PCI slot number (optional) 42 43 If bus/slot is not specified, the first available PCI 44 device will be used. 45 46The firmware required by these boards is available in the 47comedi_nonfree_firmware tarball available from 48http://www.comedi.org. However, the driver's support for 49loading the firmware through comedi_config is currently 50broken. 51 52 */ 53 54#include <linux/interrupt.h> 55#include "../comedidev.h" 56 57#include <linux/delay.h> 58#include <linux/list.h> 59#include <linux/spinlock.h> 60 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 67 68/*============================================================================= 69 PCI device table. 70 This is used by modprobe to translate PCI IDs to drivers. 71 ===========================================================================*/ 72 73static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { 74 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, 75 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, 76 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, 77 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, 78 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, 79 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, 80 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, 81 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, 82 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, 83 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, 84 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, 85 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, 86 { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, 87 { 0 } 88}; 89 90MODULE_DEVICE_TABLE(pci, me4000_pci_table); 91 92static const struct me4000_board me4000_boards[] = { 93 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} }, 94 95 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} }, 96 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} }, 97 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} }, 98 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} }, 99 100 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} }, 101 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} }, 102 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} }, 103 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} }, 104 105 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} }, 106 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} }, 107 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, 108 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, 109 110 {0}, 111}; 112 113#define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1) 114 115/*----------------------------------------------------------------------------- 116 Comedi function prototypes 117 ---------------------------------------------------------------------------*/ 118static int me4000_attach(struct comedi_device *dev, 119 struct comedi_devconfig *it); 120static int me4000_detach(struct comedi_device *dev); 121static struct comedi_driver driver_me4000 = { 122driver_name: "me4000", 123module : THIS_MODULE, 124attach : me4000_attach, 125detach : me4000_detach, 126}; 127 128/*----------------------------------------------------------------------------- 129 Meilhaus function prototypes 130 ---------------------------------------------------------------------------*/ 131static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it); 132static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p); 133static int init_board_info(struct comedi_device *dev, 134 struct pci_dev *pci_dev_p); 135static int init_ao_context(struct comedi_device *dev); 136static int init_ai_context(struct comedi_device *dev); 137static int init_dio_context(struct comedi_device *dev); 138static int init_cnt_context(struct comedi_device *dev); 139static int xilinx_download(struct comedi_device *dev); 140static int reset_board(struct comedi_device *dev); 141 142static int me4000_dio_insn_bits(struct comedi_device *dev, 143 struct comedi_subdevice *s, 144 struct comedi_insn *insn, unsigned int *data); 145 146static int me4000_dio_insn_config(struct comedi_device *dev, 147 struct comedi_subdevice *s, 148 struct comedi_insn *insn, unsigned int *data); 149 150static int cnt_reset(struct comedi_device *dev, unsigned int channel); 151 152static int cnt_config(struct comedi_device *dev, 153 unsigned int channel, unsigned int mode); 154 155static int me4000_cnt_insn_config(struct comedi_device *dev, 156 struct comedi_subdevice *s, 157 struct comedi_insn *insn, unsigned int *data); 158 159static int me4000_cnt_insn_write(struct comedi_device *dev, 160 struct comedi_subdevice *s, 161 struct comedi_insn *insn, unsigned int *data); 162 163static int me4000_cnt_insn_read(struct comedi_device *dev, 164 struct comedi_subdevice *s, 165 struct comedi_insn *insn, unsigned int *data); 166 167static int me4000_ai_insn_read(struct comedi_device *dev, 168 struct comedi_subdevice *subdevice, 169 struct comedi_insn *insn, unsigned int *data); 170 171static int me4000_ai_cancel(struct comedi_device *dev, 172 struct comedi_subdevice *s); 173 174static int ai_check_chanlist(struct comedi_device *dev, 175 struct comedi_subdevice *s, 176 struct comedi_cmd *cmd); 177 178static int ai_round_cmd_args(struct comedi_device *dev, 179 struct comedi_subdevice *s, 180 struct comedi_cmd *cmd, 181 unsigned int *init_ticks, 182 unsigned int *scan_ticks, 183 unsigned int *chan_ticks); 184 185static int ai_prepare(struct comedi_device *dev, 186 struct comedi_subdevice *s, 187 struct comedi_cmd *cmd, 188 unsigned int init_ticks, 189 unsigned int scan_ticks, unsigned int chan_ticks); 190 191static int ai_write_chanlist(struct comedi_device *dev, 192 struct comedi_subdevice *s, 193 struct comedi_cmd *cmd); 194 195static irqreturn_t me4000_ai_isr(int irq, void *dev_id); 196 197static int me4000_ai_do_cmd_test(struct comedi_device *dev, 198 struct comedi_subdevice *s, 199 struct comedi_cmd *cmd); 200 201static int me4000_ai_do_cmd(struct comedi_device *dev, 202 struct comedi_subdevice *s); 203 204static int me4000_ao_insn_write(struct comedi_device *dev, 205 struct comedi_subdevice *s, 206 struct comedi_insn *insn, unsigned int *data); 207 208static int me4000_ao_insn_read(struct comedi_device *dev, 209 struct comedi_subdevice *s, 210 struct comedi_insn *insn, unsigned int *data); 211 212/*----------------------------------------------------------------------------- 213 Meilhaus inline functions 214 ---------------------------------------------------------------------------*/ 215 216static inline void me4000_outb(struct comedi_device *dev, unsigned char value, 217 unsigned long port) 218{ 219 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port); 220 outb(value, port); 221} 222 223static inline void me4000_outl(struct comedi_device *dev, unsigned long value, 224 unsigned long port) 225{ 226 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port); 227 outl(value, port); 228} 229 230static inline unsigned long me4000_inl(struct comedi_device *dev, 231 unsigned long port) 232{ 233 unsigned long value; 234 value = inl(port); 235 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port); 236 return value; 237} 238 239static inline unsigned char me4000_inb(struct comedi_device *dev, 240 unsigned long port) 241{ 242 unsigned char value; 243 value = inb(port); 244 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port); 245 return value; 246} 247 248static const struct comedi_lrange me4000_ai_range = { 249 4, 250 { 251 UNI_RANGE(2.5), 252 UNI_RANGE(10), 253 BIP_RANGE(2.5), 254 BIP_RANGE(10), 255 } 256}; 257 258static const struct comedi_lrange me4000_ao_range = { 259 1, 260 { 261 BIP_RANGE(10), 262 } 263}; 264 265static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) 266{ 267 struct comedi_subdevice *s; 268 int result; 269 270 CALL_PDEBUG("In me4000_attach()\n"); 271 272 result = me4000_probe(dev, it); 273 if (result) 274 return result; 275 276 /* 277 * Allocate the subdevice structures. alloc_subdevice() is a 278 * convenient macro defined in comedidev.h. It relies on 279 * n_subdevices being set correctly. 280 */ 281 if (alloc_subdevices(dev, 4) < 0) 282 return -ENOMEM; 283 284 /*========================================================================= 285 Analog input subdevice 286 ========================================================================*/ 287 288 s = dev->subdevices + 0; 289 290 if (thisboard->ai.count) { 291 s->type = COMEDI_SUBD_AI; 292 s->subdev_flags = 293 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; 294 s->n_chan = thisboard->ai.count; 295 s->maxdata = 0xFFFF; /* 16 bit ADC */ 296 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; 297 s->range_table = &me4000_ai_range; 298 s->insn_read = me4000_ai_insn_read; 299 300 if (info->irq > 0) { 301 if (request_irq(info->irq, me4000_ai_isr, 302 IRQF_SHARED, "ME-4000", dev)) { 303 printk 304 ("comedi%d: me4000: me4000_attach(): " 305 "Unable to allocate irq\n", dev->minor); 306 } else { 307 dev->read_subdev = s; 308 s->subdev_flags |= SDF_CMD_READ; 309 s->cancel = me4000_ai_cancel; 310 s->do_cmdtest = me4000_ai_do_cmd_test; 311 s->do_cmd = me4000_ai_do_cmd; 312 } 313 } else { 314 printk(KERN_WARNING 315 "comedi%d: me4000: me4000_attach(): " 316 "No interrupt available\n", dev->minor); 317 } 318 } else { 319 s->type = COMEDI_SUBD_UNUSED; 320 } 321 322 /*========================================================================= 323 Analog output subdevice 324 ========================================================================*/ 325 326 s = dev->subdevices + 1; 327 328 if (thisboard->ao.count) { 329 s->type = COMEDI_SUBD_AO; 330 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; 331 s->n_chan = thisboard->ao.count; 332 s->maxdata = 0xFFFF; /* 16 bit DAC */ 333 s->range_table = &me4000_ao_range; 334 s->insn_write = me4000_ao_insn_write; 335 s->insn_read = me4000_ao_insn_read; 336 } else { 337 s->type = COMEDI_SUBD_UNUSED; 338 } 339 340 /*========================================================================= 341 Digital I/O subdevice 342 ========================================================================*/ 343 344 s = dev->subdevices + 2; 345 346 if (thisboard->dio.count) { 347 s->type = COMEDI_SUBD_DIO; 348 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 349 s->n_chan = thisboard->dio.count * 8; 350 s->maxdata = 1; 351 s->range_table = &range_digital; 352 s->insn_bits = me4000_dio_insn_bits; 353 s->insn_config = me4000_dio_insn_config; 354 } else { 355 s->type = COMEDI_SUBD_UNUSED; 356 } 357 358 /* 359 * Check for optoisolated ME-4000 version. If one the first 360 * port is a fixed output port and the second is a fixed input port. 361 */ 362 if (!me4000_inl(dev, info->dio_context.dir_reg)) { 363 s->io_bits |= 0xFF; 364 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, 365 info->dio_context.dir_reg); 366 } 367 368 /*========================================================================= 369 Counter subdevice 370 ========================================================================*/ 371 372 s = dev->subdevices + 3; 373 374 if (thisboard->cnt.count) { 375 s->type = COMEDI_SUBD_COUNTER; 376 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 377 s->n_chan = thisboard->cnt.count; 378 s->maxdata = 0xFFFF; /* 16 bit counters */ 379 s->insn_read = me4000_cnt_insn_read; 380 s->insn_write = me4000_cnt_insn_write; 381 s->insn_config = me4000_cnt_insn_config; 382 } else { 383 s->type = COMEDI_SUBD_UNUSED; 384 } 385 386 return 0; 387} 388 389static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) 390{ 391 struct pci_dev *pci_device = NULL; 392 int result, i; 393 struct me4000_board *board; 394 395 CALL_PDEBUG("In me4000_probe()\n"); 396 397 /* Allocate private memory */ 398 if (alloc_private(dev, sizeof(struct me4000_info)) < 0) 399 return -ENOMEM; 400 401 /* 402 * Probe the device to determine what device in the series it is. 403 */ 404 for_each_pci_dev(pci_device) { 405 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) { 406 for (i = 0; i < ME4000_BOARD_VERSIONS; i++) { 407 if (me4000_boards[i].device_id == 408 pci_device->device) { 409 /* 410 * Was a particular 411 * bus/slot requested? 412 */ 413 if ((it->options[0] != 0) 414 || (it->options[1] != 0)) { 415 /* 416 * Are we on the wrong 417 * bus/slot? 418 */ 419 if (pci_device->bus->number != 420 it->options[0] 421 || 422 PCI_SLOT(pci_device->devfn) 423 != it->options[1]) { 424 continue; 425 } 426 } 427 dev->board_ptr = me4000_boards + i; 428 board = 429 (struct me4000_board *) 430 dev->board_ptr; 431 info->pci_dev_p = pci_device; 432 goto found; 433 } 434 } 435 } 436 } 437 438 printk(KERN_ERR 439 "comedi%d: me4000: me4000_probe(): " 440 "No supported board found (req. bus/slot : %d/%d)\n", 441 dev->minor, it->options[0], it->options[1]); 442 return -ENODEV; 443 444found: 445 446 printk(KERN_INFO 447 "comedi%d: me4000: me4000_probe(): " 448 "Found %s at PCI bus %d, slot %d\n", 449 dev->minor, me4000_boards[i].name, pci_device->bus->number, 450 PCI_SLOT(pci_device->devfn)); 451 452 /* Set data in device structure */ 453 dev->board_name = board->name; 454 455 /* Enable PCI device and request regions */ 456 result = comedi_pci_enable(pci_device, dev->board_name); 457 if (result) { 458 printk(KERN_ERR 459 "comedi%d: me4000: me4000_probe(): Cannot enable PCI " 460 "device and request I/O regions\n", dev->minor); 461 return result; 462 } 463 464 /* Get the PCI base registers */ 465 result = get_registers(dev, pci_device); 466 if (result) { 467 printk(KERN_ERR 468 "comedi%d: me4000: me4000_probe(): " 469 "Cannot get registers\n", dev->minor); 470 return result; 471 } 472 /* Initialize board info */ 473 result = init_board_info(dev, pci_device); 474 if (result) { 475 printk(KERN_ERR 476 "comedi%d: me4000: me4000_probe(): " 477 "Cannot init baord info\n", dev->minor); 478 return result; 479 } 480 481 /* Init analog output context */ 482 result = init_ao_context(dev); 483 if (result) { 484 printk(KERN_ERR 485 "comedi%d: me4000: me4000_probe(): " 486 "Cannot init ao context\n", dev->minor); 487 return result; 488 } 489 490 /* Init analog input context */ 491 result = init_ai_context(dev); 492 if (result) { 493 printk(KERN_ERR 494 "comedi%d: me4000: me4000_probe(): " 495 "Cannot init ai context\n", dev->minor); 496 return result; 497 } 498 499 /* Init digital I/O context */ 500 result = init_dio_context(dev); 501 if (result) { 502 printk(KERN_ERR 503 "comedi%d: me4000: me4000_probe(): " 504 "Cannot init dio context\n", dev->minor); 505 return result; 506 } 507 508 /* Init counter context */ 509 result = init_cnt_context(dev); 510 if (result) { 511 printk(KERN_ERR 512 "comedi%d: me4000: me4000_probe(): " 513 "Cannot init cnt context\n", dev->minor); 514 return result; 515 } 516 517 /* Download the xilinx firmware */ 518 result = xilinx_download(dev); 519 if (result) { 520 printk(KERN_ERR 521 "comedi%d: me4000: me4000_probe(): " 522 "Can't download firmware\n", dev->minor); 523 return result; 524 } 525 526 /* Make a hardware reset */ 527 result = reset_board(dev); 528 if (result) { 529 printk(KERN_ERR 530 "comedi%d: me4000: me4000_probe(): Can't reset board\n", 531 dev->minor); 532 return result; 533 } 534 535 return 0; 536} 537 538static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) 539{ 540 541 CALL_PDEBUG("In get_registers()\n"); 542 543 /*--------------------------- plx regbase -------------------------------*/ 544 545 info->plx_regbase = pci_resource_start(pci_dev_p, 1); 546 if (info->plx_regbase == 0) { 547 printk(KERN_ERR 548 "comedi%d: me4000: get_registers(): " 549 "PCI base address 1 is not available\n", dev->minor); 550 return -ENODEV; 551 } 552 info->plx_regbase_size = pci_resource_len(pci_dev_p, 1); 553 554 /*--------------------------- me4000 regbase ----------------------------*/ 555 556 info->me4000_regbase = pci_resource_start(pci_dev_p, 2); 557 if (info->me4000_regbase == 0) { 558 printk(KERN_ERR 559 "comedi%d: me4000: get_registers(): " 560 "PCI base address 2 is not available\n", dev->minor); 561 return -ENODEV; 562 } 563 info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2); 564 565 /*--------------------------- timer regbase ------------------------------*/ 566 567 info->timer_regbase = pci_resource_start(pci_dev_p, 3); 568 if (info->timer_regbase == 0) { 569 printk(KERN_ERR 570 "comedi%d: me4000: get_registers(): " 571 "PCI base address 3 is not available\n", dev->minor); 572 return -ENODEV; 573 } 574 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3); 575 576 /*--------------------------- program regbase ----------------------------*/ 577 578 info->program_regbase = pci_resource_start(pci_dev_p, 5); 579 if (info->program_regbase == 0) { 580 printk(KERN_ERR 581 "comedi%d: me4000: get_registers(): " 582 "PCI base address 5 is not available\n", dev->minor); 583 return -ENODEV; 584 } 585 info->program_regbase_size = pci_resource_len(pci_dev_p, 5); 586 587 return 0; 588} 589 590static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) 591{ 592 int result; 593 594 CALL_PDEBUG("In init_board_info()\n"); 595 596 /* Init spin locks */ 597 /* spin_lock_init(&info->preload_lock); */ 598 /* spin_lock_init(&info->ai_ctrl_lock); */ 599 600 /* Get the serial number */ 601 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no); 602 if (result != PCIBIOS_SUCCESSFUL) 603 return result; 604 605 /* Get the hardware revision */ 606 result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision); 607 if (result != PCIBIOS_SUCCESSFUL) 608 return result; 609 610 /* Get the vendor id */ 611 info->vendor_id = pci_dev_p->vendor; 612 613 /* Get the device id */ 614 info->device_id = pci_dev_p->device; 615 616 /* Get the irq assigned to the board */ 617 info->irq = pci_dev_p->irq; 618 619 return 0; 620} 621 622static int init_ao_context(struct comedi_device *dev) 623{ 624 int i; 625 626 CALL_PDEBUG("In init_ao_context()\n"); 627 628 for (i = 0; i < thisboard->ao.count; i++) { 629 /* spin_lock_init(&info->ao_context[i].use_lock); */ 630 info->ao_context[i].irq = info->irq; 631 632 switch (i) { 633 case 0: 634 info->ao_context[i].ctrl_reg = 635 info->me4000_regbase + ME4000_AO_00_CTRL_REG; 636 info->ao_context[i].status_reg = 637 info->me4000_regbase + ME4000_AO_00_STATUS_REG; 638 info->ao_context[i].fifo_reg = 639 info->me4000_regbase + ME4000_AO_00_FIFO_REG; 640 info->ao_context[i].single_reg = 641 info->me4000_regbase + ME4000_AO_00_SINGLE_REG; 642 info->ao_context[i].timer_reg = 643 info->me4000_regbase + ME4000_AO_00_TIMER_REG; 644 info->ao_context[i].irq_status_reg = 645 info->me4000_regbase + ME4000_IRQ_STATUS_REG; 646 info->ao_context[i].preload_reg = 647 info->me4000_regbase + ME4000_AO_LOADSETREG_XX; 648 break; 649 case 1: 650 info->ao_context[i].ctrl_reg = 651 info->me4000_regbase + ME4000_AO_01_CTRL_REG; 652 info->ao_context[i].status_reg = 653 info->me4000_regbase + ME4000_AO_01_STATUS_REG; 654 info->ao_context[i].fifo_reg = 655 info->me4000_regbase + ME4000_AO_01_FIFO_REG; 656 info->ao_context[i].single_reg = 657 info->me4000_regbase + ME4000_AO_01_SINGLE_REG; 658 info->ao_context[i].timer_reg = 659 info->me4000_regbase + ME4000_AO_01_TIMER_REG; 660 info->ao_context[i].irq_status_reg = 661 info->me4000_regbase + ME4000_IRQ_STATUS_REG; 662 info->ao_context[i].preload_reg = 663 info->me4000_regbase + ME4000_AO_LOADSETREG_XX; 664 break; 665 case 2: 666 info->ao_context[i].ctrl_reg = 667 info->me4000_regbase + ME4000_AO_02_CTRL_REG; 668 info->ao_context[i].status_reg = 669 info->me4000_regbase + ME4000_AO_02_STATUS_REG; 670 info->ao_context[i].fifo_reg = 671 info->me4000_regbase + ME4000_AO_02_FIFO_REG; 672 info->ao_context[i].single_reg = 673 info->me4000_regbase + ME4000_AO_02_SINGLE_REG; 674 info->ao_context[i].timer_reg = 675 info->me4000_regbase + ME4000_AO_02_TIMER_REG; 676 info->ao_context[i].irq_status_reg = 677 info->me4000_regbase + ME4000_IRQ_STATUS_REG; 678 info->ao_context[i].preload_reg = 679 info->me4000_regbase + ME4000_AO_LOADSETREG_XX; 680 break; 681 case 3: 682 info->ao_context[i].ctrl_reg = 683 info->me4000_regbase + ME4000_AO_03_CTRL_REG; 684 info->ao_context[i].status_reg = 685 info->me4000_regbase + ME4000_AO_03_STATUS_REG; 686 info->ao_context[i].fifo_reg = 687 info->me4000_regbase + ME4000_AO_03_FIFO_REG; 688 info->ao_context[i].single_reg = 689 info->me4000_regbase + ME4000_AO_03_SINGLE_REG; 690 info->ao_context[i].timer_reg = 691 info->me4000_regbase + ME4000_AO_03_TIMER_REG; 692 info->ao_context[i].irq_status_reg = 693 info->me4000_regbase + ME4000_IRQ_STATUS_REG; 694 info->ao_context[i].preload_reg = 695 info->me4000_regbase + ME4000_AO_LOADSETREG_XX; 696 break; 697 default: 698 break; 699 } 700 } 701 702 return 0; 703} 704 705static int init_ai_context(struct comedi_device *dev) 706{ 707 708 CALL_PDEBUG("In init_ai_context()\n"); 709 710 info->ai_context.irq = info->irq; 711 712 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG; 713 info->ai_context.status_reg = 714 info->me4000_regbase + ME4000_AI_STATUS_REG; 715 info->ai_context.channel_list_reg = 716 info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG; 717 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG; 718 info->ai_context.chan_timer_reg = 719 info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG; 720 info->ai_context.chan_pre_timer_reg = 721 info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG; 722 info->ai_context.scan_timer_low_reg = 723 info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG; 724 info->ai_context.scan_timer_high_reg = 725 info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG; 726 info->ai_context.scan_pre_timer_low_reg = 727 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG; 728 info->ai_context.scan_pre_timer_high_reg = 729 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG; 730 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG; 731 info->ai_context.irq_status_reg = 732 info->me4000_regbase + ME4000_IRQ_STATUS_REG; 733 info->ai_context.sample_counter_reg = 734 info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG; 735 736 return 0; 737} 738 739static int init_dio_context(struct comedi_device *dev) 740{ 741 742 CALL_PDEBUG("In init_dio_context()\n"); 743 744 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG; 745 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG; 746 info->dio_context.port_0_reg = 747 info->me4000_regbase + ME4000_DIO_PORT_0_REG; 748 info->dio_context.port_1_reg = 749 info->me4000_regbase + ME4000_DIO_PORT_1_REG; 750 info->dio_context.port_2_reg = 751 info->me4000_regbase + ME4000_DIO_PORT_2_REG; 752 info->dio_context.port_3_reg = 753 info->me4000_regbase + ME4000_DIO_PORT_3_REG; 754 755 return 0; 756} 757 758static int init_cnt_context(struct comedi_device *dev) 759{ 760 761 CALL_PDEBUG("In init_cnt_context()\n"); 762 763 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG; 764 info->cnt_context.counter_0_reg = 765 info->timer_regbase + ME4000_CNT_COUNTER_0_REG; 766 info->cnt_context.counter_1_reg = 767 info->timer_regbase + ME4000_CNT_COUNTER_1_REG; 768 info->cnt_context.counter_2_reg = 769 info->timer_regbase + ME4000_CNT_COUNTER_2_REG; 770 771 return 0; 772} 773 774#define FIRMWARE_NOT_AVAILABLE 1 775#if FIRMWARE_NOT_AVAILABLE 776extern unsigned char *xilinx_firm; 777#endif 778 779static int xilinx_download(struct comedi_device *dev) 780{ 781 u32 value = 0; 782 wait_queue_head_t queue; 783 int idx = 0; 784 int size = 0; 785 786 CALL_PDEBUG("In xilinx_download()\n"); 787 788 init_waitqueue_head(&queue); 789 790 /* 791 * Set PLX local interrupt 2 polarity to high. 792 * Interrupt is thrown by init pin of xilinx. 793 */ 794 outl(0x10, info->plx_regbase + PLX_INTCSR); 795 796 /* Set /CS and /WRITE of the Xilinx */ 797 value = inl(info->plx_regbase + PLX_ICR); 798 value |= 0x100; 799 outl(value, info->plx_regbase + PLX_ICR); 800 801 /* Init Xilinx with CS1 */ 802 inb(info->program_regbase + 0xC8); 803 804 /* Wait until /INIT pin is set */ 805 udelay(20); 806 if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) { 807 printk(KERN_ERR 808 "comedi%d: me4000: xilinx_download(): " 809 "Can't init Xilinx\n", dev->minor); 810 return -EIO; 811 } 812 813 /* Reset /CS and /WRITE of the Xilinx */ 814 value = inl(info->plx_regbase + PLX_ICR); 815 value &= ~0x100; 816 outl(value, info->plx_regbase + PLX_ICR); 817 if (FIRMWARE_NOT_AVAILABLE) { 818 comedi_error(dev, "xilinx firmware unavailable " 819 "due to licensing, aborting"); 820 return -EIO; 821 } else { 822 /* Download Xilinx firmware */ 823 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) + 824 (xilinx_firm[2] << 8) + xilinx_firm[3]; 825 udelay(10); 826 827 for (idx = 0; idx < size; idx++) { 828 outb(xilinx_firm[16 + idx], info->program_regbase); 829 udelay(10); 830 831 /* Check if BUSY flag is low */ 832 if (inl(info->plx_regbase + PLX_ICR) & 0x20) { 833 printk(KERN_ERR 834 "comedi%d: me4000: xilinx_download(): " 835 "Xilinx is still busy (idx = %d)\n", 836 dev->minor, idx); 837 return -EIO; 838 } 839 } 840 } 841 842 /* If done flag is high download was successful */ 843 if (inl(info->plx_regbase + PLX_ICR) & 0x4) { 844 } else { 845 printk(KERN_ERR 846 "comedi%d: me4000: xilinx_download(): " 847 "DONE flag is not set\n", dev->minor); 848 printk(KERN_ERR 849 "comedi%d: me4000: xilinx_download(): " 850 "Download not successful\n", dev->minor); 851 return -EIO; 852 } 853 854 /* Set /CS and /WRITE */ 855 value = inl(info->plx_regbase + PLX_ICR); 856 value |= 0x100; 857 outl(value, info->plx_regbase + PLX_ICR); 858 859 return 0; 860} 861 862static int reset_board(struct comedi_device *dev) 863{ 864 unsigned long icr; 865 866 CALL_PDEBUG("In reset_board()\n"); 867 868 /* Make a hardware reset */ 869 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR); 870 icr |= 0x40000000; 871 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR); 872 icr &= ~0x40000000; 873 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR); 874 875 /* 0x8000 to the DACs means an output voltage of 0V */ 876 me4000_outl(dev, 0x8000, 877 info->me4000_regbase + ME4000_AO_00_SINGLE_REG); 878 me4000_outl(dev, 0x8000, 879 info->me4000_regbase + ME4000_AO_01_SINGLE_REG); 880 me4000_outl(dev, 0x8000, 881 info->me4000_regbase + ME4000_AO_02_SINGLE_REG); 882 me4000_outl(dev, 0x8000, 883 info->me4000_regbase + ME4000_AO_03_SINGLE_REG); 884 885 /* Set both stop bits in the analog input control register */ 886 me4000_outl(dev, 887 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, 888 info->me4000_regbase + ME4000_AI_CTRL_REG); 889 890 /* Set both stop bits in the analog output control register */ 891 me4000_outl(dev, 892 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, 893 info->me4000_regbase + ME4000_AO_00_CTRL_REG); 894 me4000_outl(dev, 895 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, 896 info->me4000_regbase + ME4000_AO_01_CTRL_REG); 897 me4000_outl(dev, 898 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, 899 info->me4000_regbase + ME4000_AO_02_CTRL_REG); 900 me4000_outl(dev, 901 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, 902 info->me4000_regbase + ME4000_AO_03_CTRL_REG); 903 904 /* Enable interrupts on the PLX */ 905 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR); 906 907 /* Set the adustment register for AO demux */ 908 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE, 909 info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG); 910 911 /* 912 * Set digital I/O direction for port 0 913 * to output on isolated versions 914 */ 915 if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) { 916 me4000_outl(dev, 0x1, 917 info->me4000_regbase + ME4000_DIO_CTRL_REG); 918 } 919 920 return 0; 921} 922 923static int me4000_detach(struct comedi_device *dev) 924{ 925 CALL_PDEBUG("In me4000_detach()\n"); 926 927 if (info) { 928 if (info->pci_dev_p) { 929 reset_board(dev); 930 if (info->plx_regbase) 931 comedi_pci_disable(info->pci_dev_p); 932 pci_dev_put(info->pci_dev_p); 933 } 934 } 935 936 return 0; 937} 938 939/*============================================================================= 940 Analog input section 941 ===========================================================================*/ 942 943static int me4000_ai_insn_read(struct comedi_device *dev, 944 struct comedi_subdevice *subdevice, 945 struct comedi_insn *insn, unsigned int *data) 946{ 947 948 int chan = CR_CHAN(insn->chanspec); 949 int rang = CR_RANGE(insn->chanspec); 950 int aref = CR_AREF(insn->chanspec); 951 952 unsigned long entry = 0; 953 unsigned long tmp; 954 long lval; 955 956 CALL_PDEBUG("In me4000_ai_insn_read()\n"); 957 958 if (insn->n == 0) { 959 return 0; 960 } else if (insn->n > 1) { 961 printk(KERN_ERR 962 "comedi%d: me4000: me4000_ai_insn_read(): " 963 "Invalid instruction length %d\n", dev->minor, insn->n); 964 return -EINVAL; 965 } 966 967 switch (rang) { 968 case 0: 969 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5; 970 break; 971 case 1: 972 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10; 973 break; 974 case 2: 975 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5; 976 break; 977 case 3: 978 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; 979 break; 980 default: 981 printk(KERN_ERR 982 "comedi%d: me4000: me4000_ai_insn_read(): " 983 "Invalid range specified\n", dev->minor); 984 return -EINVAL; 985 } 986 987 switch (aref) { 988 case AREF_GROUND: 989 case AREF_COMMON: 990 if (chan >= thisboard->ai.count) { 991 printk(KERN_ERR 992 "comedi%d: me4000: me4000_ai_insn_read(): " 993 "Analog input is not available\n", dev->minor); 994 return -EINVAL; 995 } 996 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan; 997 break; 998 999 case AREF_DIFF: 1000 if (rang == 0 || rang == 1) { 1001 printk(KERN_ERR 1002 "comedi%d: me4000: me4000_ai_insn_read(): " 1003 "Range must be bipolar when aref = diff\n", 1004 dev->minor); 1005 return -EINVAL; 1006 } 1007 1008 if (chan >= thisboard->ai.diff_count) { 1009 printk(KERN_ERR 1010 "comedi%d: me4000: me4000_ai_insn_read(): " 1011 "Analog input is not available\n", dev->minor); 1012 return -EINVAL; 1013 } 1014 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan; 1015 break; 1016 default: 1017 printk(KERN_ERR 1018 "comedi%d: me4000: me4000_ai_insn_read(): " 1019 "Invalid aref specified\n", dev->minor); 1020 return -EINVAL; 1021 } 1022 1023 entry |= ME4000_AI_LIST_LAST_ENTRY; 1024 1025 /* Clear channel list, data fifo and both stop bits */ 1026 tmp = me4000_inl(dev, info->ai_context.ctrl_reg); 1027 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | 1028 ME4000_AI_CTRL_BIT_DATA_FIFO | 1029 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); 1030 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1031 1032 /* Set the acquisition mode to single */ 1033 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 | 1034 ME4000_AI_CTRL_BIT_MODE_2); 1035 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1036 1037 /* Enable channel list and data fifo */ 1038 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO; 1039 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1040 1041 /* Generate channel list entry */ 1042 me4000_outl(dev, entry, info->ai_context.channel_list_reg); 1043 1044 /* Set the timer to maximum sample rate */ 1045 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg); 1046 me4000_outl(dev, ME4000_AI_MIN_TICKS, 1047 info->ai_context.chan_pre_timer_reg); 1048 1049 /* Start conversion by dummy read */ 1050 me4000_inl(dev, info->ai_context.start_reg); 1051 1052 /* Wait until ready */ 1053 udelay(10); 1054 if (! 1055 (me4000_inl(dev, info->ai_context.status_reg) & 1056 ME4000_AI_STATUS_BIT_EF_DATA)) { 1057 printk(KERN_ERR 1058 "comedi%d: me4000: me4000_ai_insn_read(): " 1059 "Value not available after wait\n", dev->minor); 1060 return -EIO; 1061 } 1062 1063 /* Read value from data fifo */ 1064 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF; 1065 data[0] = lval ^ 0x8000; 1066 1067 return 1; 1068} 1069 1070static int me4000_ai_cancel(struct comedi_device *dev, 1071 struct comedi_subdevice *s) 1072{ 1073 unsigned long tmp; 1074 1075 CALL_PDEBUG("In me4000_ai_cancel()\n"); 1076 1077 /* Stop any running conversion */ 1078 tmp = me4000_inl(dev, info->ai_context.ctrl_reg); 1079 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); 1080 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1081 1082 /* Clear the control register */ 1083 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg); 1084 1085 return 0; 1086} 1087 1088static int ai_check_chanlist(struct comedi_device *dev, 1089 struct comedi_subdevice *s, struct comedi_cmd *cmd) 1090{ 1091 int aref; 1092 int i; 1093 1094 CALL_PDEBUG("In ai_check_chanlist()\n"); 1095 1096 /* Check whether a channel list is available */ 1097 if (!cmd->chanlist_len) { 1098 printk(KERN_ERR 1099 "comedi%d: me4000: ai_check_chanlist(): " 1100 "No channel list available\n", dev->minor); 1101 return -EINVAL; 1102 } 1103 1104 /* Check the channel list size */ 1105 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) { 1106 printk(KERN_ERR 1107 "comedi%d: me4000: ai_check_chanlist(): " 1108 "Channel list is to large\n", dev->minor); 1109 return -EINVAL; 1110 } 1111 1112 /* Check the pointer */ 1113 if (!cmd->chanlist) { 1114 printk(KERN_ERR 1115 "comedi%d: me4000: ai_check_chanlist(): " 1116 "NULL pointer to channel list\n", dev->minor); 1117 return -EFAULT; 1118 } 1119 1120 /* Check whether aref is equal for all entries */ 1121 aref = CR_AREF(cmd->chanlist[0]); 1122 for (i = 0; i < cmd->chanlist_len; i++) { 1123 if (CR_AREF(cmd->chanlist[i]) != aref) { 1124 printk(KERN_ERR 1125 "comedi%d: me4000: ai_check_chanlist(): " 1126 "Mode is not equal for all entries\n", 1127 dev->minor); 1128 return -EINVAL; 1129 } 1130 } 1131 1132 /* Check whether channels are available for this ending */ 1133 if (aref == SDF_DIFF) { 1134 for (i = 0; i < cmd->chanlist_len; i++) { 1135 if (CR_CHAN(cmd->chanlist[i]) >= 1136 thisboard->ai.diff_count) { 1137 printk(KERN_ERR 1138 "comedi%d: me4000: ai_check_chanlist():" 1139 " Channel number to high\n", dev->minor); 1140 return -EINVAL; 1141 } 1142 } 1143 } else { 1144 for (i = 0; i < cmd->chanlist_len; i++) { 1145 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) { 1146 printk(KERN_ERR 1147 "comedi%d: me4000: ai_check_chanlist(): " 1148 "Channel number to high\n", dev->minor); 1149 return -EINVAL; 1150 } 1151 } 1152 } 1153 1154 /* Check if bipolar is set for all entries when in differential mode */ 1155 if (aref == SDF_DIFF) { 1156 for (i = 0; i < cmd->chanlist_len; i++) { 1157 if (CR_RANGE(cmd->chanlist[i]) != 1 && 1158 CR_RANGE(cmd->chanlist[i]) != 2) { 1159 printk(KERN_ERR 1160 "comedi%d: me4000: ai_check_chanlist(): " 1161 "Bipolar is not selected in " 1162 "differential mode\n", 1163 dev->minor); 1164 return -EINVAL; 1165 } 1166 } 1167 } 1168 1169 return 0; 1170} 1171 1172static int ai_round_cmd_args(struct comedi_device *dev, 1173 struct comedi_subdevice *s, 1174 struct comedi_cmd *cmd, 1175 unsigned int *init_ticks, 1176 unsigned int *scan_ticks, unsigned int *chan_ticks) 1177{ 1178 1179 int rest; 1180 1181 CALL_PDEBUG("In ai_round_cmd_args()\n"); 1182 1183 *init_ticks = 0; 1184 *scan_ticks = 0; 1185 *chan_ticks = 0; 1186 1187 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg); 1188 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n", 1189 cmd->scan_begin_arg); 1190 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg); 1191 1192 if (cmd->start_arg) { 1193 *init_ticks = (cmd->start_arg * 33) / 1000; 1194 rest = (cmd->start_arg * 33) % 1000; 1195 1196 if (cmd->flags & TRIG_ROUND_NEAREST) { 1197 if (rest > 33) 1198 (*init_ticks)++; 1199 } else if (cmd->flags & TRIG_ROUND_UP) { 1200 if (rest) 1201 (*init_ticks)++; 1202 } 1203 } 1204 1205 if (cmd->scan_begin_arg) { 1206 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000; 1207 rest = (cmd->scan_begin_arg * 33) % 1000; 1208 1209 if (cmd->flags & TRIG_ROUND_NEAREST) { 1210 if (rest > 33) 1211 (*scan_ticks)++; 1212 } else if (cmd->flags & TRIG_ROUND_UP) { 1213 if (rest) 1214 (*scan_ticks)++; 1215 } 1216 } 1217 1218 if (cmd->convert_arg) { 1219 *chan_ticks = (cmd->convert_arg * 33) / 1000; 1220 rest = (cmd->convert_arg * 33) % 1000; 1221 1222 if (cmd->flags & TRIG_ROUND_NEAREST) { 1223 if (rest > 33) 1224 (*chan_ticks)++; 1225 } else if (cmd->flags & TRIG_ROUND_UP) { 1226 if (rest) 1227 (*chan_ticks)++; 1228 } 1229 } 1230 1231 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks); 1232 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks); 1233 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks); 1234 1235 return 0; 1236} 1237 1238static void ai_write_timer(struct comedi_device *dev, 1239 unsigned int init_ticks, 1240 unsigned int scan_ticks, unsigned int chan_ticks) 1241{ 1242 1243 CALL_PDEBUG("In ai_write_timer()\n"); 1244 1245 me4000_outl(dev, init_ticks - 1, 1246 info->ai_context.scan_pre_timer_low_reg); 1247 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg); 1248 1249 if (scan_ticks) { 1250 me4000_outl(dev, scan_ticks - 1, 1251 info->ai_context.scan_timer_low_reg); 1252 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg); 1253 } 1254 1255 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg); 1256 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg); 1257} 1258 1259static int ai_prepare(struct comedi_device *dev, 1260 struct comedi_subdevice *s, 1261 struct comedi_cmd *cmd, 1262 unsigned int init_ticks, 1263 unsigned int scan_ticks, unsigned int chan_ticks) 1264{ 1265 1266 unsigned long tmp = 0; 1267 1268 CALL_PDEBUG("In ai_prepare()\n"); 1269 1270 /* Write timer arguments */ 1271 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks); 1272 1273 /* Reset control register */ 1274 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1275 1276 /* Start sources */ 1277 if ((cmd->start_src == TRIG_EXT && 1278 cmd->scan_begin_src == TRIG_TIMER && 1279 cmd->convert_src == TRIG_TIMER) || 1280 (cmd->start_src == TRIG_EXT && 1281 cmd->scan_begin_src == TRIG_FOLLOW && 1282 cmd->convert_src == TRIG_TIMER)) { 1283 tmp = ME4000_AI_CTRL_BIT_MODE_1 | 1284 ME4000_AI_CTRL_BIT_CHANNEL_FIFO | 1285 ME4000_AI_CTRL_BIT_DATA_FIFO; 1286 } else if (cmd->start_src == TRIG_EXT && 1287 cmd->scan_begin_src == TRIG_EXT && 1288 cmd->convert_src == TRIG_TIMER) { 1289 tmp = ME4000_AI_CTRL_BIT_MODE_2 | 1290 ME4000_AI_CTRL_BIT_CHANNEL_FIFO | 1291 ME4000_AI_CTRL_BIT_DATA_FIFO; 1292 } else if (cmd->start_src == TRIG_EXT && 1293 cmd->scan_begin_src == TRIG_EXT && 1294 cmd->convert_src == TRIG_EXT) { 1295 tmp = ME4000_AI_CTRL_BIT_MODE_0 | 1296 ME4000_AI_CTRL_BIT_MODE_1 | 1297 ME4000_AI_CTRL_BIT_CHANNEL_FIFO | 1298 ME4000_AI_CTRL_BIT_DATA_FIFO; 1299 } else { 1300 tmp = ME4000_AI_CTRL_BIT_MODE_0 | 1301 ME4000_AI_CTRL_BIT_CHANNEL_FIFO | 1302 ME4000_AI_CTRL_BIT_DATA_FIFO; 1303 } 1304 1305 /* Stop triggers */ 1306 if (cmd->stop_src == TRIG_COUNT) { 1307 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg, 1308 info->ai_context.sample_counter_reg); 1309 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; 1310 } else if (cmd->stop_src == TRIG_NONE && 1311 cmd->scan_end_src == TRIG_COUNT) { 1312 me4000_outl(dev, cmd->scan_end_arg, 1313 info->ai_context.sample_counter_reg); 1314 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; 1315 } else { 1316 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ; 1317 } 1318 1319 /* Write the setup to the control register */ 1320 me4000_outl(dev, tmp, info->ai_context.ctrl_reg); 1321 1322 /* Write the channel list */ 1323 ai_write_chanlist(dev, s, cmd); 1324 1325 return 0; 1326} 1327 1328static int ai_write_chanlist(struct comedi_device *dev, 1329 struct comedi_subdevice *s, struct comedi_cmd *cmd) 1330{ 1331 unsigned int entry; 1332 unsigned int chan; 1333 unsigned int rang; 1334 unsigned int aref; 1335 int i; 1336 1337 CALL_PDEBUG("In ai_write_chanlist()\n"); 1338 1339 for (i = 0; i < cmd->chanlist_len; i++) { 1340 chan = CR_CHAN(cmd->chanlist[i]); 1341 rang = CR_RANGE(cmd->chanlist[i]); 1342 aref = CR_AREF(cmd->chanlist[i]); 1343 1344 entry = chan; 1345 1346 if (rang == 0) 1347 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5; 1348 else if (rang == 1) 1349 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10; 1350 else if (rang == 2) 1351 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5; 1352 else 1353 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; 1354 1355 if (aref == SDF_DIFF) 1356 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; 1357 else 1358 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; 1359 1360 me4000_outl(dev, entry, info->ai_context.channel_list_reg); 1361 } 1362 1363 return 0; 1364} 1365 1366static int me4000_ai_do_cmd(struct comedi_device *dev, 1367 struct comedi_subdevice *s) 1368{ 1369 int err; 1370 unsigned int init_ticks = 0; 1371 unsigned int scan_ticks = 0; 1372 unsigned int chan_ticks = 0; 1373 struct comedi_cmd *cmd = &s->async->cmd; 1374 1375 CALL_PDEBUG("In me4000_ai_do_cmd()\n"); 1376 1377 /* Reset the analog input */ 1378 err = me4000_ai_cancel(dev, s); 1379 if (err) 1380 return err; 1381 1382 /* Round the timer arguments */ 1383 err = ai_round_cmd_args(dev, 1384 s, cmd, &init_ticks, &scan_ticks, &chan_ticks); 1385 if (err) 1386 return err; 1387 1388 /* Prepare the AI for acquisition */ 1389 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks); 1390 if (err) 1391 return err; 1392 1393 /* Start acquistion by dummy read */ 1394 me4000_inl(dev, info->ai_context.start_reg); 1395 1396 return 0; 1397} 1398 1399/* 1400 * me4000_ai_do_cmd_test(): 1401 * 1402 * The demo cmd.c in ./comedilib/demo specifies 6 return values: 1403 * - success 1404 * - invalid source 1405 * - source conflict 1406 * - invalid argument 1407 * - argument conflict 1408 * - invalid chanlist 1409 * So I tried to adopt this scheme. 1410 */ 1411static int me4000_ai_do_cmd_test(struct comedi_device *dev, 1412 struct comedi_subdevice *s, 1413 struct comedi_cmd *cmd) 1414{ 1415 1416 unsigned int init_ticks; 1417 unsigned int chan_ticks; 1418 unsigned int scan_ticks; 1419 int err = 0; 1420 1421 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n"); 1422 1423 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev); 1424 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags); 1425 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n", 1426 cmd->start_src); 1427 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n", 1428 cmd->start_arg); 1429 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n", 1430 cmd->scan_begin_src); 1431 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n", 1432 cmd->scan_begin_arg); 1433 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n", 1434 cmd->convert_src); 1435 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n", 1436 cmd->convert_arg); 1437 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n", 1438 cmd->scan_end_src); 1439 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n", 1440 cmd->scan_end_arg); 1441 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n", 1442 cmd->stop_src); 1443 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg); 1444 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n", 1445 (unsigned int)cmd->chanlist); 1446 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n", 1447 cmd->chanlist_len); 1448 1449 /* Only rounding flags are implemented */ 1450 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN; 1451 1452 /* Round the timer arguments */ 1453 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks); 1454 1455 /* 1456 * Stage 1. Check if the trigger sources are generally valid. 1457 */ 1458 switch (cmd->start_src) { 1459 case TRIG_NOW: 1460 case TRIG_EXT: 1461 break; 1462 case TRIG_ANY: 1463 cmd->start_src &= TRIG_NOW | TRIG_EXT; 1464 err++; 1465 break; 1466 default: 1467 printk(KERN_ERR 1468 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1469 "Invalid start source\n", dev->minor); 1470 cmd->start_src = TRIG_NOW; 1471 err++; 1472 } 1473 switch (cmd->scan_begin_src) { 1474 case TRIG_FOLLOW: 1475 case TRIG_TIMER: 1476 case TRIG_EXT: 1477 break; 1478 case TRIG_ANY: 1479 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1480 err++; 1481 break; 1482 default: 1483 printk(KERN_ERR 1484 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1485 "Invalid scan begin source\n", dev->minor); 1486 cmd->scan_begin_src = TRIG_FOLLOW; 1487 err++; 1488 } 1489 switch (cmd->convert_src) { 1490 case TRIG_TIMER: 1491 case TRIG_EXT: 1492 break; 1493 case TRIG_ANY: 1494 cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1495 err++; 1496 break; 1497 default: 1498 printk(KERN_ERR 1499 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1500 "Invalid convert source\n", dev->minor); 1501 cmd->convert_src = TRIG_TIMER; 1502 err++; 1503 } 1504 switch (cmd->scan_end_src) { 1505 case TRIG_NONE: 1506 case TRIG_COUNT: 1507 break; 1508 case TRIG_ANY: 1509 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT; 1510 err++; 1511 break; 1512 default: 1513 printk(KERN_ERR 1514 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1515 "Invalid scan end source\n", dev->minor); 1516 cmd->scan_end_src = TRIG_NONE; 1517 err++; 1518 } 1519 switch (cmd->stop_src) { 1520 case TRIG_NONE: 1521 case TRIG_COUNT: 1522 break; 1523 case TRIG_ANY: 1524 cmd->stop_src &= TRIG_NONE | TRIG_COUNT; 1525 err++; 1526 break; 1527 default: 1528 printk(KERN_ERR 1529 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1530 "Invalid stop source\n", dev->minor); 1531 cmd->stop_src = TRIG_NONE; 1532 err++; 1533 } 1534 if (err) 1535 return 1; 1536 1537 /* 1538 * Stage 2. Check for trigger source conflicts. 1539 */ 1540 if (cmd->start_src == TRIG_NOW && 1541 cmd->scan_begin_src == TRIG_TIMER && 1542 cmd->convert_src == TRIG_TIMER) { 1543 } else if (cmd->start_src == TRIG_NOW && 1544 cmd->scan_begin_src == TRIG_FOLLOW && 1545 cmd->convert_src == TRIG_TIMER) { 1546 } else if (cmd->start_src == TRIG_EXT && 1547 cmd->scan_begin_src == TRIG_TIMER && 1548 cmd->convert_src == TRIG_TIMER) { 1549 } else if (cmd->start_src == TRIG_EXT && 1550 cmd->scan_begin_src == TRIG_FOLLOW && 1551 cmd->convert_src == TRIG_TIMER) { 1552 } else if (cmd->start_src == TRIG_EXT && 1553 cmd->scan_begin_src == TRIG_EXT && 1554 cmd->convert_src == TRIG_TIMER) { 1555 } else if (cmd->start_src == TRIG_EXT && 1556 cmd->scan_begin_src == TRIG_EXT && 1557 cmd->convert_src == TRIG_EXT) { 1558 } else { 1559 printk(KERN_ERR 1560 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1561 "Invalid start trigger combination\n", dev->minor); 1562 cmd->start_src = TRIG_NOW; 1563 cmd->scan_begin_src = TRIG_FOLLOW; 1564 cmd->convert_src = TRIG_TIMER; 1565 err++; 1566 } 1567 1568 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) { 1569 } else if (cmd->stop_src == TRIG_COUNT && 1570 cmd->scan_end_src == TRIG_NONE) { 1571 } else if (cmd->stop_src == TRIG_NONE && 1572 cmd->scan_end_src == TRIG_COUNT) { 1573 } else if (cmd->stop_src == TRIG_COUNT && 1574 cmd->scan_end_src == TRIG_COUNT) { 1575 } else { 1576 printk(KERN_ERR 1577 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1578 "Invalid stop trigger combination\n", dev->minor); 1579 cmd->stop_src = TRIG_NONE; 1580 cmd->scan_end_src = TRIG_NONE; 1581 err++; 1582 } 1583 if (err) 1584 return 2; 1585 1586 /* 1587 * Stage 3. Check if arguments are generally valid. 1588 */ 1589 if (cmd->chanlist_len < 1) { 1590 printk(KERN_ERR 1591 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1592 "No channel list\n", dev->minor); 1593 cmd->chanlist_len = 1; 1594 err++; 1595 } 1596 if (init_ticks < 66) { 1597 printk(KERN_ERR 1598 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1599 "Start arg to low\n", dev->minor); 1600 cmd->start_arg = 2000; 1601 err++; 1602 } 1603 if (scan_ticks && scan_ticks < 67) { 1604 printk(KERN_ERR 1605 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1606 "Scan begin arg to low\n", dev->minor); 1607 cmd->scan_begin_arg = 2031; 1608 err++; 1609 } 1610 if (chan_ticks < 66) { 1611 printk(KERN_ERR 1612 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1613 "Convert arg to low\n", dev->minor); 1614 cmd->convert_arg = 2000; 1615 err++; 1616 } 1617 1618 if (err) 1619 return 3; 1620 1621 /* 1622 * Stage 4. Check for argument conflicts. 1623 */ 1624 if (cmd->start_src == TRIG_NOW && 1625 cmd->scan_begin_src == TRIG_TIMER && 1626 cmd->convert_src == TRIG_TIMER) { 1627 1628 /* Check timer arguments */ 1629 if (init_ticks < ME4000_AI_MIN_TICKS) { 1630 printk(KERN_ERR 1631 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1632 "Invalid start arg\n", dev->minor); 1633 cmd->start_arg = 2000; /* 66 ticks at least */ 1634 err++; 1635 } 1636 if (chan_ticks < ME4000_AI_MIN_TICKS) { 1637 printk(KERN_ERR 1638 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1639 "Invalid convert arg\n", dev->minor); 1640 cmd->convert_arg = 2000; /* 66 ticks at least */ 1641 err++; 1642 } 1643 if (scan_ticks <= cmd->chanlist_len * chan_ticks) { 1644 printk(KERN_ERR 1645 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1646 "Invalid scan end arg\n", dev->minor); 1647 1648 /* At least one tick more */ 1649 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; 1650 err++; 1651 } 1652 } else if (cmd->start_src == TRIG_NOW && 1653 cmd->scan_begin_src == TRIG_FOLLOW && 1654 cmd->convert_src == TRIG_TIMER) { 1655 1656 /* Check timer arguments */ 1657 if (init_ticks < ME4000_AI_MIN_TICKS) { 1658 printk(KERN_ERR 1659 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1660 "Invalid start arg\n", dev->minor); 1661 cmd->start_arg = 2000; /* 66 ticks at least */ 1662 err++; 1663 } 1664 if (chan_ticks < ME4000_AI_MIN_TICKS) { 1665 printk(KERN_ERR 1666 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1667 "Invalid convert arg\n", dev->minor); 1668 cmd->convert_arg = 2000; /* 66 ticks at least */ 1669 err++; 1670 } 1671 } else if (cmd->start_src == TRIG_EXT && 1672 cmd->scan_begin_src == TRIG_TIMER && 1673 cmd->convert_src == TRIG_TIMER) { 1674 1675 /* Check timer arguments */ 1676 if (init_ticks < ME4000_AI_MIN_TICKS) { 1677 printk(KERN_ERR 1678 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1679 "Invalid start arg\n", dev->minor); 1680 cmd->start_arg = 2000; /* 66 ticks at least */ 1681 err++; 1682 } 1683 if (chan_ticks < ME4000_AI_MIN_TICKS) { 1684 printk(KERN_ERR 1685 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1686 "Invalid convert arg\n", dev->minor); 1687 cmd->convert_arg = 2000; /* 66 ticks at least */ 1688 err++; 1689 } 1690 if (scan_ticks <= cmd->chanlist_len * chan_ticks) { 1691 printk(KERN_ERR 1692 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1693 "Invalid scan end arg\n", dev->minor); 1694 1695 /* At least one tick more */ 1696 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; 1697 err++; 1698 } 1699 } else if (cmd->start_src == TRIG_EXT && 1700 cmd->scan_begin_src == TRIG_FOLLOW && 1701 cmd->convert_src == TRIG_TIMER) { 1702 1703 /* Check timer arguments */ 1704 if (init_ticks < ME4000_AI_MIN_TICKS) { 1705 printk(KERN_ERR 1706 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1707 "Invalid start arg\n", dev->minor); 1708 cmd->start_arg = 2000; /* 66 ticks at least */ 1709 err++; 1710 } 1711 if (chan_ticks < ME4000_AI_MIN_TICKS) { 1712 printk(KERN_ERR 1713 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1714 "Invalid convert arg\n", dev->minor); 1715 cmd->convert_arg = 2000; /* 66 ticks at least */ 1716 err++; 1717 } 1718 } else if (cmd->start_src == TRIG_EXT && 1719 cmd->scan_begin_src == TRIG_EXT && 1720 cmd->convert_src == TRIG_TIMER) { 1721 1722 /* Check timer arguments */ 1723 if (init_ticks < ME4000_AI_MIN_TICKS) { 1724 printk(KERN_ERR 1725 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1726 "Invalid start arg\n", dev->minor); 1727 cmd->start_arg = 2000; /* 66 ticks at least */ 1728 err++; 1729 } 1730 if (chan_ticks < ME4000_AI_MIN_TICKS) { 1731 printk(KERN_ERR 1732 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1733 "Invalid convert arg\n", dev->minor); 1734 cmd->convert_arg = 2000; /* 66 ticks at least */ 1735 err++; 1736 } 1737 } else if (cmd->start_src == TRIG_EXT && 1738 cmd->scan_begin_src == TRIG_EXT && 1739 cmd->convert_src == TRIG_EXT) { 1740 1741 /* Check timer arguments */ 1742 if (init_ticks < ME4000_AI_MIN_TICKS) { 1743 printk(KERN_ERR 1744 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1745 "Invalid start arg\n", dev->minor); 1746 cmd->start_arg = 2000; /* 66 ticks at least */ 1747 err++; 1748 } 1749 } 1750 if (cmd->stop_src == TRIG_COUNT) { 1751 if (cmd->stop_arg == 0) { 1752 printk(KERN_ERR 1753 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1754 "Invalid stop arg\n", dev->minor); 1755 cmd->stop_arg = 1; 1756 err++; 1757 } 1758 } 1759 if (cmd->scan_end_src == TRIG_COUNT) { 1760 if (cmd->scan_end_arg == 0) { 1761 printk(KERN_ERR 1762 "comedi%d: me4000: me4000_ai_do_cmd_test(): " 1763 "Invalid scan end arg\n", dev->minor); 1764 cmd->scan_end_arg = 1; 1765 err++; 1766 } 1767 } 1768 1769 if (err) 1770 return 4; 1771 1772 /* 1773 * Stage 5. Check the channel list. 1774 */ 1775 if (ai_check_chanlist(dev, s, cmd)) 1776 return 5; 1777 1778 return 0; 1779} 1780 1781static irqreturn_t me4000_ai_isr(int irq, void *dev_id) 1782{ 1783 unsigned int tmp; 1784 struct comedi_device *dev = dev_id; 1785 struct comedi_subdevice *s = dev->subdevices; 1786 struct me4000_ai_context *ai_context = &info->ai_context; 1787 int i; 1788 int c = 0; 1789 long lval; 1790 1791 ISR_PDEBUG("me4000_ai_isr() is executed\n"); 1792 1793 if (!dev->attached) { 1794 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n"); 1795 return IRQ_NONE; 1796 } 1797 1798 /* Reset all events */ 1799 s->async->events = 0; 1800 1801 /* Check if irq number is right */ 1802 if (irq != ai_context->irq) { 1803 printk(KERN_ERR 1804 "comedi%d: me4000: me4000_ai_isr(): " 1805 "Incorrect interrupt num: %d\n", dev->minor, irq); 1806 return IRQ_HANDLED; 1807 } 1808 1809 if (me4000_inl(dev, 1810 ai_context->irq_status_reg) & 1811 ME4000_IRQ_STATUS_BIT_AI_HF) { 1812 ISR_PDEBUG 1813 ("me4000_ai_isr(): Fifo half full interrupt occured\n"); 1814 1815 /* Read status register to find out what happened */ 1816 tmp = me4000_inl(dev, ai_context->ctrl_reg); 1817 1818 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && 1819 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && 1820 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { 1821 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n"); 1822 c = ME4000_AI_FIFO_COUNT; 1823 1824 /* 1825 * FIFO overflow, so stop conversion 1826 * and disable all interrupts 1827 */ 1828 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; 1829 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | 1830 ME4000_AI_CTRL_BIT_SC_IRQ); 1831 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1832 1833 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1834 1835 printk(KERN_ERR 1836 "comedi%d: me4000: me4000_ai_isr(): " 1837 "FIFO overflow\n", dev->minor); 1838 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) 1839 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) 1840 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { 1841 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n"); 1842 1843 s->async->events |= COMEDI_CB_BLOCK; 1844 1845 c = ME4000_AI_FIFO_COUNT / 2; 1846 } else { 1847 printk(KERN_ERR 1848 "comedi%d: me4000: me4000_ai_isr(): " 1849 "Can't determine state of fifo\n", dev->minor); 1850 c = 0; 1851 1852 /* 1853 * Undefined state, so stop conversion 1854 * and disable all interrupts 1855 */ 1856 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; 1857 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | 1858 ME4000_AI_CTRL_BIT_SC_IRQ); 1859 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1860 1861 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1862 1863 printk(KERN_ERR 1864 "comedi%d: me4000: me4000_ai_isr(): " 1865 "Undefined FIFO state\n", dev->minor); 1866 } 1867 1868 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c); 1869 1870 for (i = 0; i < c; i++) { 1871 /* Read value from data fifo */ 1872 lval = inl(ai_context->data_reg) & 0xFFFF; 1873 lval ^= 0x8000; 1874 1875 if (!comedi_buf_put(s->async, lval)) { 1876 /* 1877 * Buffer overflow, so stop conversion 1878 * and disable all interrupts 1879 */ 1880 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; 1881 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | 1882 ME4000_AI_CTRL_BIT_SC_IRQ); 1883 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1884 1885 s->async->events |= COMEDI_CB_OVERFLOW; 1886 1887 printk(KERN_ERR 1888 "comedi%d: me4000: me4000_ai_isr(): " 1889 "Buffer overflow\n", dev->minor); 1890 1891 break; 1892 } 1893 } 1894 1895 /* Work is done, so reset the interrupt */ 1896 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n"); 1897 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET; 1898 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1899 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET; 1900 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1901 } 1902 1903 if (me4000_inl(dev, 1904 ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { 1905 ISR_PDEBUG 1906 ("me4000_ai_isr(): Sample counter interrupt occured\n"); 1907 1908 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; 1909 1910 /* 1911 * Acquisition is complete, so stop 1912 * conversion and disable all interrupts 1913 */ 1914 tmp = me4000_inl(dev, ai_context->ctrl_reg); 1915 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; 1916 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); 1917 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1918 1919 /* Poll data until fifo empty */ 1920 while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) { 1921 /* Read value from data fifo */ 1922 lval = inl(ai_context->data_reg) & 0xFFFF; 1923 lval ^= 0x8000; 1924 1925 if (!comedi_buf_put(s->async, lval)) { 1926 printk(KERN_ERR 1927 "comedi%d: me4000: me4000_ai_isr(): " 1928 "Buffer overflow\n", dev->minor); 1929 s->async->events |= COMEDI_CB_OVERFLOW; 1930 break; 1931 } 1932 } 1933 1934 /* Work is done, so reset the interrupt */ 1935 ISR_PDEBUG 1936 ("me4000_ai_isr(): Reset interrupt from sample counter\n"); 1937 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET; 1938 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1939 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET; 1940 me4000_outl(dev, tmp, ai_context->ctrl_reg); 1941 } 1942 1943 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events); 1944 1945 if (s->async->events) 1946 comedi_event(dev, s); 1947 1948 return IRQ_HANDLED; 1949} 1950 1951/*============================================================================= 1952 Analog output section 1953 ===========================================================================*/ 1954 1955static int me4000_ao_insn_write(struct comedi_device *dev, 1956 struct comedi_subdevice *s, 1957 struct comedi_insn *insn, unsigned int *data) 1958{ 1959 1960 int chan = CR_CHAN(insn->chanspec); 1961 int rang = CR_RANGE(insn->chanspec); 1962 int aref = CR_AREF(insn->chanspec); 1963 unsigned long tmp; 1964 1965 CALL_PDEBUG("In me4000_ao_insn_write()\n"); 1966 1967 if (insn->n == 0) { 1968 return 0; 1969 } else if (insn->n > 1) { 1970 printk(KERN_ERR 1971 "comedi%d: me4000: me4000_ao_insn_write(): " 1972 "Invalid instruction length %d\n", dev->minor, insn->n); 1973 return -EINVAL; 1974 } 1975 1976 if (chan >= thisboard->ao.count) { 1977 printk(KERN_ERR 1978 "comedi%d: me4000: me4000_ao_insn_write(): " 1979 "Invalid channel %d\n", dev->minor, insn->n); 1980 return -EINVAL; 1981 } 1982 1983 if (rang != 0) { 1984 printk(KERN_ERR 1985 "comedi%d: me4000: me4000_ao_insn_write(): " 1986 "Invalid range %d\n", dev->minor, insn->n); 1987 return -EINVAL; 1988 } 1989 1990 if (aref != AREF_GROUND && aref != AREF_COMMON) { 1991 printk(KERN_ERR 1992 "comedi%d: me4000: me4000_ao_insn_write(): " 1993 "Invalid aref %d\n", dev->minor, insn->n); 1994 return -EINVAL; 1995 } 1996 1997 /* Stop any running conversion */ 1998 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg); 1999 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; 2000 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg); 2001 2002 /* Clear control register and set to single mode */ 2003 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg); 2004 2005 /* Write data value */ 2006 me4000_outl(dev, data[0], info->ao_context[chan].single_reg); 2007 2008 /* Store in the mirror */ 2009 info->ao_context[chan].mirror = data[0]; 2010 2011 return 1; 2012} 2013 2014static int me4000_ao_insn_read(struct comedi_device *dev, 2015 struct comedi_subdevice *s, 2016 struct comedi_insn *insn, unsigned int *data) 2017{ 2018 int chan = CR_CHAN(insn->chanspec); 2019 2020 if (insn->n == 0) { 2021 return 0; 2022 } else if (insn->n > 1) { 2023 printk 2024 ("comedi%d: me4000: me4000_ao_insn_read(): " 2025 "Invalid instruction length\n", dev->minor); 2026 return -EINVAL; 2027 } 2028 2029 data[0] = info->ao_context[chan].mirror; 2030 2031 return 1; 2032} 2033 2034/*============================================================================= 2035 Digital I/O section 2036 ===========================================================================*/ 2037 2038static int me4000_dio_insn_bits(struct comedi_device *dev, 2039 struct comedi_subdevice *s, 2040 struct comedi_insn *insn, unsigned int *data) 2041{ 2042 2043 CALL_PDEBUG("In me4000_dio_insn_bits()\n"); 2044 2045 /* Length of data must be 2 (mask and new data, see below) */ 2046 if (insn->n == 0) 2047 return 0; 2048 2049 if (insn->n != 2) { 2050 printk 2051 ("comedi%d: me4000: me4000_dio_insn_bits(): " 2052 "Invalid instruction length\n", dev->minor); 2053 return -EINVAL; 2054 } 2055 2056 /* 2057 * The insn data consists of a mask in data[0] and the new data 2058 * in data[1]. The mask defines which bits we are concerning about. 2059 * The new data must be anded with the mask. 2060 * Each channel corresponds to a bit. 2061 */ 2062 if (data[0]) { 2063 /* Check if requested ports are configured for output */ 2064 if ((s->io_bits & data[0]) != data[0]) 2065 return -EIO; 2066 2067 s->state &= ~data[0]; 2068 s->state |= data[0] & data[1]; 2069 2070 /* Write out the new digital output lines */ 2071 me4000_outl(dev, (s->state >> 0) & 0xFF, 2072 info->dio_context.port_0_reg); 2073 me4000_outl(dev, (s->state >> 8) & 0xFF, 2074 info->dio_context.port_1_reg); 2075 me4000_outl(dev, (s->state >> 16) & 0xFF, 2076 info->dio_context.port_2_reg); 2077 me4000_outl(dev, (s->state >> 24) & 0xFF, 2078 info->dio_context.port_3_reg); 2079 } 2080 2081 /* On return, data[1] contains the value of 2082 the digital input and output lines. */ 2083 data[1] = 2084 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) | 2085 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) | 2086 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) | 2087 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24); 2088 2089 return 2; 2090} 2091 2092static int me4000_dio_insn_config(struct comedi_device *dev, 2093 struct comedi_subdevice *s, 2094 struct comedi_insn *insn, unsigned int *data) 2095{ 2096 unsigned long tmp; 2097 int chan = CR_CHAN(insn->chanspec); 2098 2099 CALL_PDEBUG("In me4000_dio_insn_config()\n"); 2100 2101 if (data[0] == INSN_CONFIG_DIO_QUERY) { 2102 data[1] = 2103 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; 2104 return insn->n; 2105 } 2106 2107 /* 2108 * The input or output configuration of each digital line is 2109 * configured by a special insn_config instruction. chanspec 2110 * contains the channel to be changed, and data[0] contains the 2111 * value COMEDI_INPUT or COMEDI_OUTPUT. 2112 * On the ME-4000 it is only possible to switch port wise (8 bit) 2113 */ 2114 2115 tmp = me4000_inl(dev, info->dio_context.ctrl_reg); 2116 2117 if (data[0] == COMEDI_OUTPUT) { 2118 if (chan < 8) { 2119 s->io_bits |= 0xFF; 2120 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | 2121 ME4000_DIO_CTRL_BIT_MODE_1); 2122 tmp |= ME4000_DIO_CTRL_BIT_MODE_0; 2123 } else if (chan < 16) { 2124 /* 2125 * Chech for optoisolated ME-4000 version. 2126 * If one the first port is a fixed output 2127 * port and the second is a fixed input port. 2128 */ 2129 if (!me4000_inl(dev, info->dio_context.dir_reg)) 2130 return -ENODEV; 2131 2132 s->io_bits |= 0xFF00; 2133 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 | 2134 ME4000_DIO_CTRL_BIT_MODE_3); 2135 tmp |= ME4000_DIO_CTRL_BIT_MODE_2; 2136 } else if (chan < 24) { 2137 s->io_bits |= 0xFF0000; 2138 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 | 2139 ME4000_DIO_CTRL_BIT_MODE_5); 2140 tmp |= ME4000_DIO_CTRL_BIT_MODE_4; 2141 } else if (chan < 32) { 2142 s->io_bits |= 0xFF000000; 2143 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 | 2144 ME4000_DIO_CTRL_BIT_MODE_7); 2145 tmp |= ME4000_DIO_CTRL_BIT_MODE_6; 2146 } else { 2147 return -EINVAL; 2148 } 2149 } else { 2150 if (chan < 8) { 2151 /* 2152 * Chech for optoisolated ME-4000 version. 2153 * If one the first port is a fixed output 2154 * port and the second is a fixed input port. 2155 */ 2156 if (!me4000_inl(dev, info->dio_context.dir_reg)) 2157 return -ENODEV; 2158 2159 s->io_bits &= ~0xFF; 2160 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | 2161 ME4000_DIO_CTRL_BIT_MODE_1); 2162 } else if (chan < 16) { 2163 s->io_bits &= ~0xFF00; 2164 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 | 2165 ME4000_DIO_CTRL_BIT_MODE_3); 2166 } else if (chan < 24) { 2167 s->io_bits &= ~0xFF0000; 2168 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 | 2169 ME4000_DIO_CTRL_BIT_MODE_5); 2170 } else if (chan < 32) { 2171 s->io_bits &= ~0xFF000000; 2172 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 | 2173 ME4000_DIO_CTRL_BIT_MODE_7); 2174 } else { 2175 return -EINVAL; 2176 } 2177 } 2178 2179 me4000_outl(dev, tmp, info->dio_context.ctrl_reg); 2180 2181 return 1; 2182} 2183 2184/*============================================================================= 2185 Counter section 2186 ===========================================================================*/ 2187 2188static int cnt_reset(struct comedi_device *dev, unsigned int channel) 2189{ 2190 2191 CALL_PDEBUG("In cnt_reset()\n"); 2192 2193 switch (channel) { 2194 case 0: 2195 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg); 2196 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg); 2197 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg); 2198 break; 2199 case 1: 2200 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg); 2201 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg); 2202 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg); 2203 break; 2204 case 2: 2205 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg); 2206 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg); 2207 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg); 2208 break; 2209 default: 2210 printk(KERN_ERR 2211 "comedi%d: me4000: cnt_reset(): Invalid channel\n", 2212 dev->minor); 2213 return -EINVAL; 2214 } 2215 2216 return 0; 2217} 2218 2219static int cnt_config(struct comedi_device *dev, unsigned int channel, 2220 unsigned int mode) 2221{ 2222 int tmp = 0; 2223 2224 CALL_PDEBUG("In cnt_config()\n"); 2225 2226 switch (channel) { 2227 case 0: 2228 tmp |= ME4000_CNT_COUNTER_0; 2229 break; 2230 case 1: 2231 tmp |= ME4000_CNT_COUNTER_1; 2232 break; 2233 case 2: 2234 tmp |= ME4000_CNT_COUNTER_2; 2235 break; 2236 default: 2237 printk(KERN_ERR 2238 "comedi%d: me4000: cnt_config(): Invalid channel\n", 2239 dev->minor); 2240 return -EINVAL; 2241 } 2242 2243 switch (mode) { 2244 case 0: 2245 tmp |= ME4000_CNT_MODE_0; 2246 break; 2247 case 1: 2248 tmp |= ME4000_CNT_MODE_1; 2249 break; 2250 case 2: 2251 tmp |= ME4000_CNT_MODE_2; 2252 break; 2253 case 3: 2254 tmp |= ME4000_CNT_MODE_3; 2255 break; 2256 case 4: 2257 tmp |= ME4000_CNT_MODE_4; 2258 break; 2259 case 5: 2260 tmp |= ME4000_CNT_MODE_5; 2261 break; 2262 default: 2263 printk(KERN_ERR 2264 "comedi%d: me4000: cnt_config(): Invalid counter mode\n", 2265 dev->minor); 2266 return -EINVAL; 2267 } 2268 2269 /* Write the control word */ 2270 tmp |= 0x30; 2271 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg); 2272 2273 return 0; 2274} 2275 2276static int me4000_cnt_insn_config(struct comedi_device *dev, 2277 struct comedi_subdevice *s, 2278 struct comedi_insn *insn, unsigned int *data) 2279{ 2280 2281 int err; 2282 2283 CALL_PDEBUG("In me4000_cnt_insn_config()\n"); 2284 2285 switch (data[0]) { 2286 case GPCT_RESET: 2287 if (insn->n != 1) { 2288 printk(KERN_ERR 2289 "comedi%d: me4000: me4000_cnt_insn_config(): " 2290 "Invalid instruction length%d\n", 2291 dev->minor, insn->n); 2292 return -EINVAL; 2293 } 2294 2295 err = cnt_reset(dev, insn->chanspec); 2296 if (err) 2297 return err; 2298 break; 2299 case GPCT_SET_OPERATION: 2300 if (insn->n != 2) { 2301 printk(KERN_ERR 2302 "comedi%d: me4000: me4000_cnt_insn_config(): " 2303 "Invalid instruction length%d\n", 2304 dev->minor, insn->n); 2305 return -EINVAL; 2306 } 2307 2308 err = cnt_config(dev, insn->chanspec, data[1]); 2309 if (err) 2310 return err; 2311 break; 2312 default: 2313 printk(KERN_ERR 2314 "comedi%d: me4000: me4000_cnt_insn_config(): " 2315 "Invalid instruction\n", dev->minor); 2316 return -EINVAL; 2317 } 2318 2319 return 2; 2320} 2321 2322static int me4000_cnt_insn_read(struct comedi_device *dev, 2323 struct comedi_subdevice *s, 2324 struct comedi_insn *insn, unsigned int *data) 2325{ 2326 2327 unsigned short tmp; 2328 2329 CALL_PDEBUG("In me4000_cnt_insn_read()\n"); 2330 2331 if (insn->n == 0) 2332 return 0; 2333 2334 if (insn->n > 1) { 2335 printk(KERN_ERR 2336 "comedi%d: me4000: me4000_cnt_insn_read(): " 2337 "Invalid instruction length %d\n", 2338 dev->minor, insn->n); 2339 return -EINVAL; 2340 } 2341 2342 switch (insn->chanspec) { 2343 case 0: 2344 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg); 2345 data[0] = tmp; 2346 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg); 2347 data[0] |= tmp << 8; 2348 break; 2349 case 1: 2350 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg); 2351 data[0] = tmp; 2352 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg); 2353 data[0] |= tmp << 8; 2354 break; 2355 case 2: 2356 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg); 2357 data[0] = tmp; 2358 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg); 2359 data[0] |= tmp << 8; 2360 break; 2361 default: 2362 printk(KERN_ERR 2363 "comedi%d: me4000: me4000_cnt_insn_read(): " 2364 "Invalid channel %d\n", 2365 dev->minor, insn->chanspec); 2366 return -EINVAL; 2367 } 2368 2369 return 1; 2370} 2371 2372static int me4000_cnt_insn_write(struct comedi_device *dev, 2373 struct comedi_subdevice *s, 2374 struct comedi_insn *insn, unsigned int *data) 2375{ 2376 2377 unsigned short tmp; 2378 2379 CALL_PDEBUG("In me4000_cnt_insn_write()\n"); 2380 2381 if (insn->n == 0) { 2382 return 0; 2383 } else if (insn->n > 1) { 2384 printk(KERN_ERR 2385 "comedi%d: me4000: me4000_cnt_insn_write(): " 2386 "Invalid instruction length %d\n", 2387 dev->minor, insn->n); 2388 return -EINVAL; 2389 } 2390 2391 switch (insn->chanspec) { 2392 case 0: 2393 tmp = data[0] & 0xFF; 2394 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg); 2395 tmp = (data[0] >> 8) & 0xFF; 2396 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg); 2397 break; 2398 case 1: 2399 tmp = data[0] & 0xFF; 2400 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg); 2401 tmp = (data[0] >> 8) & 0xFF; 2402 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg); 2403 break; 2404 case 2: 2405 tmp = data[0] & 0xFF; 2406 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg); 2407 tmp = (data[0] >> 8) & 0xFF; 2408 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg); 2409 break; 2410 default: 2411 printk(KERN_ERR 2412 "comedi%d: me4000: me4000_cnt_insn_write(): " 2413 "Invalid channel %d\n", 2414 dev->minor, insn->chanspec); 2415 return -EINVAL; 2416 } 2417 2418 return 1; 2419} 2420 2421static int __devinit driver_me4000_pci_probe(struct pci_dev *dev, 2422 const struct pci_device_id *ent) 2423{ 2424 return comedi_pci_auto_config(dev, driver_me4000.driver_name); 2425} 2426 2427static void __devexit driver_me4000_pci_remove(struct pci_dev *dev) 2428{ 2429 comedi_pci_auto_unconfig(dev); 2430} 2431 2432static struct pci_driver driver_me4000_pci_driver = { 2433 .id_table = me4000_pci_table, 2434 .probe = &driver_me4000_pci_probe, 2435 .remove = __devexit_p(&driver_me4000_pci_remove) 2436}; 2437 2438static int __init driver_me4000_init_module(void) 2439{ 2440 int retval; 2441 2442 retval = comedi_driver_register(&driver_me4000); 2443 if (retval < 0) 2444 return retval; 2445 2446 driver_me4000_pci_driver.name = (char *)driver_me4000.driver_name; 2447 return pci_register_driver(&driver_me4000_pci_driver); 2448} 2449 2450static void __exit driver_me4000_cleanup_module(void) 2451{ 2452 pci_unregister_driver(&driver_me4000_pci_driver); 2453 comedi_driver_unregister(&driver_me4000); 2454} 2455 2456module_init(driver_me4000_init_module); 2457module_exit(driver_me4000_cleanup_module); 2458 2459MODULE_AUTHOR("Comedi http://www.comedi.org"); 2460MODULE_DESCRIPTION("Comedi low-level driver"); 2461MODULE_LICENSE("GPL"); 2462