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