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