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