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