adl_pci9111.c revision f2bed9b4cbc6fa34db4e9b788c5f631fb7358ecc
1/* 2 3comedi/drivers/adl_pci9111.c 4 5Hardware driver for PCI9111 ADLink cards: 6 7PCI-9111HR 8 9Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> 10 11This program is free software; you can redistribute it and/or modify 12it under the terms of the GNU General Public License as published by 13the Free Software Foundation; either version 2 of the License, or 14(at your option) any later version. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License for more details. 20 21You should have received a copy of the GNU General Public License 22along with this program; if not, write to the Free Software 23Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24*/ 25 26/* 27Driver: adl_pci9111 28Description: Adlink PCI-9111HR 29Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> 30Devices: [ADLink] PCI-9111HR (adl_pci9111) 31Status: experimental 32 33Supports: 34 35 - ai_insn read 36 - ao_insn read/write 37 - di_insn read 38 - do_insn read/write 39 - ai_do_cmd mode with the following sources: 40 41 - start_src TRIG_NOW 42 - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT 43 - convert_src TRIG_TIMER TRIG_EXT 44 - scan_end_src TRIG_COUNT 45 - stop_src TRIG_COUNT TRIG_NONE 46 47The scanned channels must be consecutive and start from 0. They must 48all have the same range and aref. 49 50Configuration options: 51 52 [0] - PCI bus number (optional) 53 [1] - PCI slot number (optional) 54 55If bus/slot is not specified, the first available PCI 56device will be used. 57 58*/ 59 60/* 61CHANGELOG: 62 632005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be 64a multiple of chanlist_len*convert_arg. 652002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data. 662002/02/18 Added external trigger support for analog input. 67 68TODO: 69 70 - Really test implemented functionality. 71 - Add support for the PCI-9111DG with a probe routine to identify 72 the card type (perhaps with the help of the channel number readback 73 of the A/D Data register). 74 - Add external multiplexer support. 75 76*/ 77 78#include "../comedidev.h" 79 80#include <linux/delay.h> 81#include <linux/interrupt.h> 82 83#include "8253.h" 84#include "comedi_fc.h" 85 86#define PCI9111_DRIVER_NAME "adl_pci9111" 87#define PCI9111_HR_DEVICE_ID 0x9111 88 89/* TODO: Add other pci9111 board id */ 90 91#define PCI9111_IO_RANGE 0x0100 92 93#define PCI9111_FIFO_HALF_SIZE 512 94 95#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 96 97#define PCI9111_RANGE_SETTING_DELAY 10 98#define PCI9111_AI_INSTANT_READ_UDELAY_US 2 99#define PCI9111_AI_INSTANT_READ_TIMEOUT 100 100 101#define PCI9111_8254_CLOCK_PERIOD_NS 500 102 103/* IO address map */ 104 105#define PCI9111_AI_FIFO_REG 0x00 106#define PCI9111_AO_REG 0x00 107#define PCI9111_DIO_REG 0x02 108#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 109#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel 110 selection */ 111#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 112#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08 113#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08 114#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A 115#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A 116#define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E 117#define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C 118#define PCI9111_8254_BASE_REG 0x40 119#define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48 120 121#define PCI9111_TRIGGER_MASK 0x0F 122#define PCI9111_PTRG_OFF (0 << 3) 123#define PCI9111_PTRG_ON (1 << 3) 124#define PCI9111_EITS_EXTERNAL (1 << 2) 125#define PCI9111_EITS_INTERNAL (0 << 2) 126#define PCI9111_TPST_SOFTWARE_TRIGGER (0 << 1) 127#define PCI9111_TPST_TIMER_PACER (1 << 1) 128#define PCI9111_ASCAN_ON (1 << 0) 129#define PCI9111_ASCAN_OFF (0 << 0) 130 131#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0) 132#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL (1 << 0) 133#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK (0 << 1) 134#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG (1 << 1) 135#define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2) 136#define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2) 137 138#define PCI9111_CHANNEL_MASK 0x0F 139 140#define PCI9111_RANGE_MASK 0x07 141#define PCI9111_FIFO_EMPTY_MASK 0x10 142#define PCI9111_FIFO_HALF_FULL_MASK 0x20 143#define PCI9111_FIFO_FULL_MASK 0x40 144#define PCI9111_AD_BUSY_MASK 0x80 145 146/* 147 * Define inlined function 148 */ 149 150#define pci9111_trigger_and_autoscan_get() \ 151 (inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) 152 153#define pci9111_trigger_and_autoscan_set(flags) \ 154 outb(flags, dev->iobase + PCI9111_REGISTER_TRIGGER_MODE_CONTROL) 155 156#define pci9111_interrupt_and_fifo_get() \ 157 ((inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \ 158 >> 4) & 0x03) 159 160#define pci9111_interrupt_and_fifo_set(flags) \ 161 outb(flags, dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL) 162 163#define pci9111_interrupt_clear() \ 164 outb(0, dev->iobase + PCI9111_REGISTER_INTERRUPT_CLEAR) 165 166#define pci9111_software_trigger() \ 167 outb(0, dev->iobase + PCI9111_REGISTER_SOFTWARE_TRIGGER) 168 169#define pci9111_fifo_reset() do { \ 170 outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 171 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ 172 outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ 173 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ 174 outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 175 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ 176 } while (0) 177 178#define pci9111_is_fifo_full() \ 179 ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 180 PCI9111_FIFO_FULL_MASK) == 0) 181 182#define pci9111_is_fifo_half_full() \ 183 ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 184 PCI9111_FIFO_HALF_FULL_MASK) == 0) 185 186#define pci9111_is_fifo_empty() \ 187 ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 188 PCI9111_FIFO_EMPTY_MASK) == 0) 189 190#define pci9111_ai_channel_set(channel) \ 191 outb((channel)&PCI9111_CHANNEL_MASK, \ 192 dev->iobase + PCI9111_REGISTER_AD_CHANNEL_CONTROL) 193 194#define pci9111_ai_channel_get() \ 195 (inb(dev->iobase + PCI9111_REGISTER_AD_CHANNEL_READBACK) \ 196 &PCI9111_CHANNEL_MASK) 197 198#define pci9111_ai_range_set(range) \ 199 outb((range)&PCI9111_RANGE_MASK, \ 200 dev->iobase + PCI9111_REGISTER_INPUT_SIGNAL_RANGE) 201 202#define pci9111_ai_range_get() \ 203 (inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK) \ 204 &PCI9111_RANGE_MASK) 205 206static const struct comedi_lrange pci9111_hr_ai_range = { 207 5, 208 { 209 BIP_RANGE(10), 210 BIP_RANGE(5), 211 BIP_RANGE(2.5), 212 BIP_RANGE(1.25), 213 BIP_RANGE(0.625) 214 } 215}; 216 217/* */ 218/* Board specification structure */ 219/* */ 220 221struct pci9111_board { 222 const char *name; /* driver name */ 223 int device_id; 224}; 225 226static const struct pci9111_board pci9111_boards[] = { 227 { 228 .name = "pci9111_hr", 229 .device_id = PCI9111_HR_DEVICE_ID, 230 }, 231}; 232 233/* Private data structure */ 234 235struct pci9111_private_data { 236 unsigned long lcr_io_base; /* Local configuration register base 237 * address */ 238 239 int stop_counter; 240 int stop_is_none; 241 242 unsigned int scan_delay; 243 unsigned int chanlist_len; 244 unsigned int chunk_counter; 245 unsigned int chunk_num_samples; 246 247 int ao_readback; /* Last written analog output data */ 248 249 unsigned int timer_divisor_1; /* Divisor values for the 8254 timer 250 * pacer */ 251 unsigned int timer_divisor_2; 252 253 int is_valid; /* Is device valid */ 254 255 short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; 256}; 257 258/* ------------------------------------------------------------------ */ 259/* PLX9050 SECTION */ 260/* ------------------------------------------------------------------ */ 261 262#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c 263 264#define PLX9050_LINTI1_ENABLE (1 << 0) 265#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1) 266#define PLX9050_LINTI1_STATUS (1 << 2) 267#define PLX9050_LINTI2_ENABLE (1 << 3) 268#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4) 269#define PLX9050_LINTI2_STATUS (1 << 5) 270#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6) 271#define PLX9050_SOFTWARE_INTERRUPT (1 << 7) 272 273static void plx9050_interrupt_control(unsigned long io_base, 274 bool LINTi1_enable, 275 bool LINTi1_active_high, 276 bool LINTi2_enable, 277 bool LINTi2_active_high, 278 bool interrupt_enable) 279{ 280 int flags = 0; 281 282 if (LINTi1_enable) 283 flags |= PLX9050_LINTI1_ENABLE; 284 if (LINTi1_active_high) 285 flags |= PLX9050_LINTI1_ACTIVE_HIGH; 286 if (LINTi2_enable) 287 flags |= PLX9050_LINTI2_ENABLE; 288 if (LINTi2_active_high) 289 flags |= PLX9050_LINTI2_ACTIVE_HIGH; 290 291 if (interrupt_enable) 292 flags |= PLX9050_PCI_INTERRUPT_ENABLE; 293 294 outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); 295} 296 297/* ------------------------------------------------------------------ */ 298/* MISCELLANEOUS SECTION */ 299/* ------------------------------------------------------------------ */ 300 301/* 8254 timer */ 302 303static void pci9111_timer_set(struct comedi_device *dev) 304{ 305 struct pci9111_private_data *dev_private = dev->private; 306 unsigned long timer_base = dev->iobase + PCI9111_8254_BASE_REG; 307 308 i8254_set_mode(timer_base, 1, 0, I8254_MODE0 | I8254_BINARY); 309 i8254_set_mode(timer_base, 1, 1, I8254_MODE2 | I8254_BINARY); 310 i8254_set_mode(timer_base, 1, 2, I8254_MODE2 | I8254_BINARY); 311 312 udelay(1); 313 314 i8254_write(timer_base, 1, 2, dev_private->timer_divisor_2); 315 i8254_write(timer_base, 1, 1, dev_private->timer_divisor_1); 316} 317 318enum pci9111_trigger_sources { 319 software, 320 timer_pacer, 321 external 322}; 323 324static void pci9111_trigger_source_set(struct comedi_device *dev, 325 enum pci9111_trigger_sources source) 326{ 327 int flags; 328 329 flags = pci9111_trigger_and_autoscan_get() & 0x09; 330 331 switch (source) { 332 case software: 333 flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; 334 break; 335 336 case timer_pacer: 337 flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; 338 break; 339 340 case external: 341 flags |= PCI9111_EITS_EXTERNAL; 342 break; 343 } 344 345 pci9111_trigger_and_autoscan_set(flags); 346} 347 348static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) 349{ 350 int flags; 351 352 flags = pci9111_trigger_and_autoscan_get() & 0x07; 353 354 if (pretrigger) 355 flags |= PCI9111_PTRG_ON; 356 357 pci9111_trigger_and_autoscan_set(flags); 358} 359 360static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) 361{ 362 int flags; 363 364 flags = pci9111_trigger_and_autoscan_get() & 0x0e; 365 366 if (autoscan) 367 flags |= PCI9111_ASCAN_ON; 368 369 pci9111_trigger_and_autoscan_set(flags); 370} 371 372enum pci9111_ISC0_sources { 373 irq_on_eoc, 374 irq_on_fifo_half_full 375}; 376 377enum pci9111_ISC1_sources { 378 irq_on_timer_tick, 379 irq_on_external_trigger 380}; 381 382static void pci9111_interrupt_source_set(struct comedi_device *dev, 383 enum pci9111_ISC0_sources irq_0_source, 384 enum pci9111_ISC1_sources irq_1_source) 385{ 386 int flags; 387 388 flags = pci9111_interrupt_and_fifo_get() & 0x04; 389 390 if (irq_0_source == irq_on_fifo_half_full) 391 flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; 392 393 if (irq_1_source == irq_on_external_trigger) 394 flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; 395 396 pci9111_interrupt_and_fifo_set(flags); 397} 398 399/* ------------------------------------------------------------------ */ 400/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ 401/* ------------------------------------------------------------------ */ 402 403/* Cancel analog input autoscan */ 404 405#undef AI_DO_CMD_DEBUG 406 407static int pci9111_ai_cancel(struct comedi_device *dev, 408 struct comedi_subdevice *s) 409{ 410 struct pci9111_private_data *dev_private = dev->private; 411 412 /* Disable interrupts */ 413 414 plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 415 true, false); 416 417 pci9111_trigger_source_set(dev, software); 418 419 pci9111_autoscan_set(dev, false); 420 421 pci9111_fifo_reset(); 422 423#ifdef AI_DO_CMD_DEBUG 424 printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); 425#endif 426 427 return 0; 428} 429 430/* Test analog input command */ 431 432#define pci9111_check_trigger_src(src, flags) do { \ 433 tmp = src; \ 434 src &= flags; \ 435 if (!src || tmp != src) \ 436 error++; \ 437 } while (false); 438 439static int 440pci9111_ai_do_cmd_test(struct comedi_device *dev, 441 struct comedi_subdevice *s, struct comedi_cmd *cmd) 442{ 443 struct pci9111_private_data *dev_private = dev->private; 444 int tmp; 445 int error = 0; 446 int range, reference; 447 int i; 448 449 /* Step 1 : check if trigger are trivialy valid */ 450 451 pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); 452 pci9111_check_trigger_src(cmd->scan_begin_src, 453 TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 454 pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); 455 pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); 456 pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); 457 458 if (error) 459 return 1; 460 461 /* step 2 : make sure trigger sources are unique and mutually 462 * compatible */ 463 464 if (cmd->start_src != TRIG_NOW) 465 error++; 466 467 if ((cmd->scan_begin_src != TRIG_TIMER) && 468 (cmd->scan_begin_src != TRIG_FOLLOW) && 469 (cmd->scan_begin_src != TRIG_EXT)) 470 error++; 471 472 if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) 473 error++; 474 if ((cmd->convert_src == TRIG_TIMER) && 475 !((cmd->scan_begin_src == TRIG_TIMER) || 476 (cmd->scan_begin_src == TRIG_FOLLOW))) 477 error++; 478 if ((cmd->convert_src == TRIG_EXT) && 479 !((cmd->scan_begin_src == TRIG_EXT) || 480 (cmd->scan_begin_src == TRIG_FOLLOW))) 481 error++; 482 483 484 if (cmd->scan_end_src != TRIG_COUNT) 485 error++; 486 if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) 487 error++; 488 489 if (error) 490 return 2; 491 492 /* Step 3 : make sure arguments are trivialy compatible */ 493 494 if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { 495 cmd->start_arg = 0; 496 error++; 497 } 498 499 if ((cmd->convert_src == TRIG_TIMER) && 500 (cmd->convert_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { 501 cmd->convert_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; 502 error++; 503 } 504 if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { 505 cmd->convert_arg = 0; 506 error++; 507 } 508 509 if ((cmd->scan_begin_src == TRIG_TIMER) && 510 (cmd->scan_begin_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { 511 cmd->scan_begin_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; 512 error++; 513 } 514 if ((cmd->scan_begin_src == TRIG_FOLLOW) 515 && (cmd->scan_begin_arg != 0)) { 516 cmd->scan_begin_arg = 0; 517 error++; 518 } 519 if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { 520 cmd->scan_begin_arg = 0; 521 error++; 522 } 523 524 if ((cmd->scan_end_src == TRIG_COUNT) && 525 (cmd->scan_end_arg != cmd->chanlist_len)) { 526 cmd->scan_end_arg = cmd->chanlist_len; 527 error++; 528 } 529 530 if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { 531 cmd->stop_arg = 1; 532 error++; 533 } 534 if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { 535 cmd->stop_arg = 0; 536 error++; 537 } 538 539 if (error) 540 return 3; 541 542 /* Step 4 : fix up any arguments */ 543 544 if (cmd->convert_src == TRIG_TIMER) { 545 tmp = cmd->convert_arg; 546 i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 547 &(dev_private->timer_divisor_1), 548 &(dev_private->timer_divisor_2), 549 &(cmd->convert_arg), 550 cmd->flags & TRIG_ROUND_MASK); 551 if (tmp != cmd->convert_arg) 552 error++; 553 } 554 /* There's only one timer on this card, so the scan_begin timer must */ 555 /* be a multiple of chanlist_len*convert_arg */ 556 557 if (cmd->scan_begin_src == TRIG_TIMER) { 558 559 unsigned int scan_begin_min; 560 unsigned int scan_begin_arg; 561 unsigned int scan_factor; 562 563 scan_begin_min = cmd->chanlist_len * cmd->convert_arg; 564 565 if (cmd->scan_begin_arg != scan_begin_min) { 566 if (scan_begin_min < cmd->scan_begin_arg) { 567 scan_factor = 568 cmd->scan_begin_arg / scan_begin_min; 569 scan_begin_arg = scan_factor * scan_begin_min; 570 if (cmd->scan_begin_arg != scan_begin_arg) { 571 cmd->scan_begin_arg = scan_begin_arg; 572 error++; 573 } 574 } else { 575 cmd->scan_begin_arg = scan_begin_min; 576 error++; 577 } 578 } 579 } 580 581 if (error) 582 return 4; 583 584 /* Step 5 : check channel list */ 585 586 if (cmd->chanlist) { 587 588 range = CR_RANGE(cmd->chanlist[0]); 589 reference = CR_AREF(cmd->chanlist[0]); 590 591 if (cmd->chanlist_len > 1) { 592 for (i = 0; i < cmd->chanlist_len; i++) { 593 if (CR_CHAN(cmd->chanlist[i]) != i) { 594 comedi_error(dev, 595 "entries in chanlist must be consecutive " 596 "channels,counting upwards from 0\n"); 597 error++; 598 } 599 if (CR_RANGE(cmd->chanlist[i]) != range) { 600 comedi_error(dev, 601 "entries in chanlist must all have the same gain\n"); 602 error++; 603 } 604 if (CR_AREF(cmd->chanlist[i]) != reference) { 605 comedi_error(dev, 606 "entries in chanlist must all have the same reference\n"); 607 error++; 608 } 609 } 610 } 611 } 612 613 if (error) 614 return 5; 615 616 return 0; 617 618} 619 620/* Analog input command */ 621 622static int pci9111_ai_do_cmd(struct comedi_device *dev, 623 struct comedi_subdevice *s) 624{ 625 struct pci9111_private_data *dev_private = dev->private; 626 struct comedi_cmd *async_cmd = &s->async->cmd; 627 628 if (!dev->irq) { 629 comedi_error(dev, 630 "no irq assigned for PCI9111, cannot do hardware conversion"); 631 return -1; 632 } 633 /* Set channel scan limit */ 634 /* PCI9111 allows only scanning from channel 0 to channel n */ 635 /* TODO: handle the case of an external multiplexer */ 636 637 if (async_cmd->chanlist_len > 1) { 638 pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); 639 pci9111_autoscan_set(dev, true); 640 } else { 641 pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); 642 pci9111_autoscan_set(dev, false); 643 } 644 645 /* Set gain */ 646 /* This is the same gain on every channel */ 647 648 pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); 649 650 /* Set counter */ 651 652 switch (async_cmd->stop_src) { 653 case TRIG_COUNT: 654 dev_private->stop_counter = 655 async_cmd->stop_arg * async_cmd->chanlist_len; 656 dev_private->stop_is_none = 0; 657 break; 658 659 case TRIG_NONE: 660 dev_private->stop_counter = 0; 661 dev_private->stop_is_none = 1; 662 break; 663 664 default: 665 comedi_error(dev, "Invalid stop trigger"); 666 return -1; 667 } 668 669 /* Set timer pacer */ 670 671 dev_private->scan_delay = 0; 672 switch (async_cmd->convert_src) { 673 case TRIG_TIMER: 674 i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 675 &(dev_private->timer_divisor_1), 676 &(dev_private->timer_divisor_2), 677 &(async_cmd->convert_arg), 678 async_cmd-> 679 flags & TRIG_ROUND_MASK); 680#ifdef AI_DO_CMD_DEBUG 681 printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", 682 dev_private->timer_divisor_1, 683 dev_private->timer_divisor_2); 684#endif 685 686 pci9111_trigger_source_set(dev, software); 687 pci9111_timer_set(dev); 688 pci9111_fifo_reset(); 689 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 690 irq_on_timer_tick); 691 pci9111_trigger_source_set(dev, timer_pacer); 692 plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 693 false, true, true); 694 695 if (async_cmd->scan_begin_src == TRIG_TIMER) { 696 dev_private->scan_delay = 697 (async_cmd->scan_begin_arg / 698 (async_cmd->convert_arg * 699 async_cmd->chanlist_len)) - 1; 700 } 701 702 break; 703 704 case TRIG_EXT: 705 706 pci9111_trigger_source_set(dev, external); 707 pci9111_fifo_reset(); 708 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 709 irq_on_timer_tick); 710 plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 711 false, true, true); 712 713 break; 714 715 default: 716 comedi_error(dev, "Invalid convert trigger"); 717 return -1; 718 } 719 720 dev_private->stop_counter *= (1 + dev_private->scan_delay); 721 dev_private->chanlist_len = async_cmd->chanlist_len; 722 dev_private->chunk_counter = 0; 723 dev_private->chunk_num_samples = 724 dev_private->chanlist_len * (1 + dev_private->scan_delay); 725 726#ifdef AI_DO_CMD_DEBUG 727 printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); 728 printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", 729 pci9111_trigger_and_autoscan_get()); 730 printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", 731 pci9111_interrupt_and_fifo_get()); 732 printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); 733 printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", 734 dev_private->stop_counter); 735 printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", 736 dev_private->scan_delay); 737 printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", 738 dev_private->chanlist_len); 739 printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", 740 dev_private->chunk_num_samples); 741#endif 742 743 return 0; 744} 745 746static void pci9111_ai_munge(struct comedi_device *dev, 747 struct comedi_subdevice *s, void *data, 748 unsigned int num_bytes, 749 unsigned int start_chan_index) 750{ 751 short *array = data; 752 unsigned int maxdata = s->maxdata; 753 unsigned int invert = (maxdata + 1) >> 1; 754 unsigned int shift = (maxdata == 0xffff) ? 0 : 4; 755 unsigned int num_samples = num_bytes / sizeof(short); 756 unsigned int i; 757 758 for (i = 0; i < num_samples; i++) 759 array[i] = ((array[i] >> shift) & maxdata) ^ invert; 760} 761 762/* ------------------------------------------------------------------ */ 763/* INTERRUPT SECTION */ 764/* ------------------------------------------------------------------ */ 765 766#undef INTERRUPT_DEBUG 767 768static irqreturn_t pci9111_interrupt(int irq, void *p_device) 769{ 770 struct comedi_device *dev = p_device; 771 struct pci9111_private_data *dev_private = dev->private; 772 struct comedi_subdevice *s = dev->read_subdev; 773 struct comedi_async *async; 774 unsigned long irq_flags; 775 unsigned char intcsr; 776 777 if (!dev->attached) { 778 /* Ignore interrupt before device fully attached. */ 779 /* Might not even have allocated subdevices yet! */ 780 return IRQ_NONE; 781 } 782 783 async = s->async; 784 785 spin_lock_irqsave(&dev->spinlock, irq_flags); 786 787 /* Check if we are source of interrupt */ 788 intcsr = inb(dev_private->lcr_io_base + 789 PLX9050_REGISTER_INTERRUPT_CONTROL); 790 if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) 791 && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 792 == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 793 || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS)) 794 == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) { 795 /* Not the source of the interrupt. */ 796 /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */ 797 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 798 return IRQ_NONE; 799 } 800 801 if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) == 802 (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { 803 /* Interrupt comes from fifo_half-full signal */ 804 805 if (pci9111_is_fifo_full()) { 806 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 807 comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); 808 pci9111_interrupt_clear(); 809 pci9111_ai_cancel(dev, s); 810 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 811 comedi_event(dev, s); 812 813 return IRQ_HANDLED; 814 } 815 816 if (pci9111_is_fifo_half_full()) { 817 unsigned int num_samples; 818 unsigned int bytes_written = 0; 819 820#ifdef INTERRUPT_DEBUG 821 printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); 822#endif 823 824 num_samples = 825 PCI9111_FIFO_HALF_SIZE > 826 dev_private->stop_counter 827 && !dev_private-> 828 stop_is_none ? dev_private->stop_counter : 829 PCI9111_FIFO_HALF_SIZE; 830 insw(dev->iobase + PCI9111_AI_FIFO_REG, 831 dev_private->ai_bounce_buffer, num_samples); 832 833 if (dev_private->scan_delay < 1) { 834 bytes_written = 835 cfc_write_array_to_buffer(s, 836 dev_private-> 837 ai_bounce_buffer, 838 num_samples * 839 sizeof(short)); 840 } else { 841 int position = 0; 842 int to_read; 843 844 while (position < num_samples) { 845 if (dev_private->chunk_counter < 846 dev_private->chanlist_len) { 847 to_read = 848 dev_private->chanlist_len - 849 dev_private->chunk_counter; 850 851 if (to_read > 852 num_samples - position) 853 to_read = 854 num_samples - 855 position; 856 857 bytes_written += 858 cfc_write_array_to_buffer 859 (s, 860 dev_private->ai_bounce_buffer 861 + position, 862 to_read * sizeof(short)); 863 } else { 864 to_read = 865 dev_private->chunk_num_samples 866 - 867 dev_private->chunk_counter; 868 if (to_read > 869 num_samples - position) 870 to_read = 871 num_samples - 872 position; 873 874 bytes_written += 875 sizeof(short) * to_read; 876 } 877 878 position += to_read; 879 dev_private->chunk_counter += to_read; 880 881 if (dev_private->chunk_counter >= 882 dev_private->chunk_num_samples) 883 dev_private->chunk_counter = 0; 884 } 885 } 886 887 dev_private->stop_counter -= 888 bytes_written / sizeof(short); 889 } 890 } 891 892 if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { 893 async->events |= COMEDI_CB_EOA; 894 pci9111_ai_cancel(dev, s); 895 } 896 897 /* Very important, otherwise another interrupt request will be inserted 898 * and will cause driver hangs on processing interrupt event. */ 899 900 pci9111_interrupt_clear(); 901 902 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 903 904 comedi_event(dev, s); 905 906 return IRQ_HANDLED; 907} 908 909/* ------------------------------------------------------------------ */ 910/* INSTANT ANALOG INPUT OUTPUT SECTION */ 911/* ------------------------------------------------------------------ */ 912 913/* analog instant input */ 914 915static int pci9111_ai_insn_read(struct comedi_device *dev, 916 struct comedi_subdevice *s, 917 struct comedi_insn *insn, unsigned int *data) 918{ 919 unsigned int maxdata = s->maxdata; 920 unsigned int invert = (maxdata + 1) >> 1; 921 unsigned int shift = (maxdata == 0xffff) ? 0 : 4; 922 int timeout; 923 int i; 924 925 pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); 926 927 if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) 928 pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); 929 930 pci9111_fifo_reset(); 931 932 for (i = 0; i < insn->n; i++) { 933 pci9111_software_trigger(); 934 935 timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; 936 937 while (timeout--) { 938 if (!pci9111_is_fifo_empty()) 939 goto conversion_done; 940 } 941 942 comedi_error(dev, "A/D read timeout"); 943 data[i] = 0; 944 pci9111_fifo_reset(); 945 return -ETIME; 946 947conversion_done: 948 949 data[i] = inw(dev->iobase + PCI9111_AI_FIFO_REG); 950 data[i] = ((data[i] >> shift) & maxdata) ^ invert; 951 } 952 953 return i; 954} 955 956static int pci9111_ao_insn_write(struct comedi_device *dev, 957 struct comedi_subdevice *s, 958 struct comedi_insn *insn, 959 unsigned int *data) 960{ 961 struct pci9111_private_data *dev_private = dev->private; 962 unsigned int val = 0; 963 int i; 964 965 for (i = 0; i < insn->n; i++) { 966 val = data[i]; 967 outw(val, dev->iobase + PCI9111_AO_REG); 968 } 969 dev_private->ao_readback = val; 970 971 return insn->n; 972} 973 974static int pci9111_ao_insn_read(struct comedi_device *dev, 975 struct comedi_subdevice *s, 976 struct comedi_insn *insn, 977 unsigned int *data) 978{ 979 struct pci9111_private_data *dev_private = dev->private; 980 int i; 981 982 for (i = 0; i < insn->n; i++) 983 data[i] = dev_private->ao_readback; 984 985 return insn->n; 986} 987 988static int pci9111_di_insn_bits(struct comedi_device *dev, 989 struct comedi_subdevice *s, 990 struct comedi_insn *insn, 991 unsigned int *data) 992{ 993 data[1] = inw(dev->iobase + PCI9111_DIO_REG); 994 995 return insn->n; 996} 997 998static int pci9111_do_insn_bits(struct comedi_device *dev, 999 struct comedi_subdevice *s, 1000 struct comedi_insn *insn, 1001 unsigned int *data) 1002{ 1003 unsigned int mask = data[0]; 1004 unsigned int bits = data[1]; 1005 1006 if (mask) { 1007 s->state &= ~mask; 1008 s->state |= (bits & mask); 1009 1010 outw(s->state, dev->iobase + PCI9111_DIO_REG); 1011 } 1012 1013 data[1] = s->state; 1014 1015 return insn->n; 1016} 1017 1018/* ------------------------------------------------------------------ */ 1019/* INITIALISATION SECTION */ 1020/* ------------------------------------------------------------------ */ 1021 1022/* Reset device */ 1023 1024static int pci9111_reset(struct comedi_device *dev) 1025{ 1026 struct pci9111_private_data *dev_private = dev->private; 1027 1028 /* Set trigger source to software */ 1029 1030 plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 1031 true, false); 1032 1033 pci9111_trigger_source_set(dev, software); 1034 pci9111_pretrigger_set(dev, false); 1035 pci9111_autoscan_set(dev, false); 1036 1037 /* Reset 8254 chip */ 1038 1039 dev_private->timer_divisor_1 = 0; 1040 dev_private->timer_divisor_2 = 0; 1041 1042 pci9111_timer_set(dev); 1043 1044 return 0; 1045} 1046 1047static struct pci_dev *pci9111_find_pci(struct comedi_device *dev, 1048 struct comedi_devconfig *it) 1049{ 1050 struct pci_dev *pcidev = NULL; 1051 int bus = it->options[0]; 1052 int slot = it->options[1]; 1053 int i; 1054 1055 for_each_pci_dev(pcidev) { 1056 if (pcidev->vendor != PCI_VENDOR_ID_ADLINK) 1057 continue; 1058 for (i = 0; i < ARRAY_SIZE(pci9111_boards); i++) { 1059 if (pcidev->device != pci9111_boards[i].device_id) 1060 continue; 1061 if (bus || slot) { 1062 /* requested particular bus/slot */ 1063 if (pcidev->bus->number != bus || 1064 PCI_SLOT(pcidev->devfn) != slot) 1065 continue; 1066 } 1067 dev->board_ptr = pci9111_boards + i; 1068 printk(KERN_ERR 1069 "comedi%d: found %s (b:s:f=%d:%d:%d), irq=%d\n", 1070 dev->minor, pci9111_boards[i].name, 1071 pcidev->bus->number, PCI_SLOT(pcidev->devfn), 1072 PCI_FUNC(pcidev->devfn), pcidev->irq); 1073 return pcidev; 1074 } 1075 } 1076 printk(KERN_ERR 1077 "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 1078 dev->minor, bus, slot); 1079 return NULL; 1080} 1081 1082static int pci9111_attach(struct comedi_device *dev, 1083 struct comedi_devconfig *it) 1084{ 1085 struct pci9111_private_data *dev_private; 1086 struct pci_dev *pcidev; 1087 struct comedi_subdevice *s; 1088 unsigned long io_base, lcr_io_base; 1089 int ret; 1090 const struct pci9111_board *board; 1091 1092 ret = alloc_private(dev, sizeof(*dev_private)); 1093 if (ret) 1094 return ret; 1095 dev_private = dev->private; 1096 1097 /* Probe the device to determine what device in the series it is. */ 1098 pcidev = pci9111_find_pci(dev, it); 1099 if (!pcidev) 1100 return -EIO; 1101 comedi_set_hw_dev(dev, &pcidev->dev); 1102 board = (struct pci9111_board *)dev->board_ptr; 1103 1104 /* TODO: Warn about non-tested boards. */ 1105 1106 /* Read local configuration register base address 1107 * [PCI_BASE_ADDRESS #1]. */ 1108 1109 lcr_io_base = pci_resource_start(pcidev, 1); 1110 1111 /* Enable PCI device and request regions */ 1112 if (comedi_pci_enable(pcidev, PCI9111_DRIVER_NAME) < 0) { 1113 printk 1114 ("comedi%d: Failed to enable PCI device and request regions\n", 1115 dev->minor); 1116 return -EIO; 1117 } 1118 /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ 1119 1120 io_base = pci_resource_start(pcidev, 2); 1121 1122 dev->iobase = io_base; 1123 dev->board_name = board->name; 1124 dev_private->is_valid = 0; 1125 dev_private->lcr_io_base = lcr_io_base; 1126 1127 pci9111_reset(dev); 1128 1129 /* Irq setup */ 1130 1131 dev->irq = 0; 1132 if (pcidev->irq > 0) { 1133 dev->irq = pcidev->irq; 1134 1135 if (request_irq(dev->irq, pci9111_interrupt, 1136 IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { 1137 printk(KERN_ERR 1138 "comedi%d: unable to allocate irq %u\n", 1139 dev->minor, dev->irq); 1140 return -EINVAL; 1141 } 1142 } 1143 1144 /* TODO: Add external multiplexer setup (according to option[2]). */ 1145 1146 ret = comedi_alloc_subdevices(dev, 4); 1147 if (ret) 1148 return ret; 1149 1150 s = &dev->subdevices[0]; 1151 dev->read_subdev = s; 1152 s->type = COMEDI_SUBD_AI; 1153 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; 1154 s->n_chan = 16; 1155 s->maxdata = 0xffff; 1156 s->len_chanlist = 16; 1157 s->range_table = &pci9111_hr_ai_range; 1158 s->cancel = pci9111_ai_cancel; 1159 s->insn_read = pci9111_ai_insn_read; 1160 s->do_cmdtest = pci9111_ai_do_cmd_test; 1161 s->do_cmd = pci9111_ai_do_cmd; 1162 s->munge = pci9111_ai_munge; 1163 1164 s = &dev->subdevices[1]; 1165 s->type = COMEDI_SUBD_AO; 1166 s->subdev_flags = SDF_WRITABLE | SDF_COMMON; 1167 s->n_chan = 1; 1168 s->maxdata = 0x0fff; 1169 s->len_chanlist = 1; 1170 s->range_table = &range_bipolar10; 1171 s->insn_write = pci9111_ao_insn_write; 1172 s->insn_read = pci9111_ao_insn_read; 1173 1174 s = &dev->subdevices[2]; 1175 s->type = COMEDI_SUBD_DI; 1176 s->subdev_flags = SDF_READABLE; 1177 s->n_chan = 16; 1178 s->maxdata = 1; 1179 s->range_table = &range_digital; 1180 s->insn_bits = pci9111_di_insn_bits; 1181 1182 s = &dev->subdevices[3]; 1183 s->type = COMEDI_SUBD_DO; 1184 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1185 s->n_chan = 16; 1186 s->maxdata = 1; 1187 s->range_table = &range_digital; 1188 s->insn_bits = pci9111_do_insn_bits; 1189 1190 dev_private->is_valid = 1; 1191 1192 dev_info(dev->class_dev, "%s attached\n", dev->board_name); 1193 1194 return 0; 1195} 1196 1197static void pci9111_detach(struct comedi_device *dev) 1198{ 1199 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 1200 struct pci9111_private_data *dev_private = dev->private; 1201 1202 if (dev_private) { 1203 if (dev_private->is_valid) 1204 pci9111_reset(dev); 1205 } 1206 if (dev->irq != 0) 1207 free_irq(dev->irq, dev); 1208 if (pcidev) { 1209 if (dev->iobase) 1210 comedi_pci_disable(pcidev); 1211 pci_dev_put(pcidev); 1212 } 1213} 1214 1215static struct comedi_driver adl_pci9111_driver = { 1216 .driver_name = "adl_pci9111", 1217 .module = THIS_MODULE, 1218 .attach = pci9111_attach, 1219 .detach = pci9111_detach, 1220}; 1221 1222static int __devinit pci9111_pci_probe(struct pci_dev *dev, 1223 const struct pci_device_id *ent) 1224{ 1225 return comedi_pci_auto_config(dev, &adl_pci9111_driver); 1226} 1227 1228static void __devexit pci9111_pci_remove(struct pci_dev *dev) 1229{ 1230 comedi_pci_auto_unconfig(dev); 1231} 1232 1233static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { 1234 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, 1235 /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ 1236 { 0 } 1237}; 1238MODULE_DEVICE_TABLE(pci, pci9111_pci_table); 1239 1240static struct pci_driver adl_pci9111_pci_driver = { 1241 .name = "adl_pci9111", 1242 .id_table = pci9111_pci_table, 1243 .probe = pci9111_pci_probe, 1244 .remove = __devexit_p(pci9111_pci_remove), 1245}; 1246module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver); 1247 1248MODULE_AUTHOR("Comedi http://www.comedi.org"); 1249MODULE_DESCRIPTION("Comedi low-level driver"); 1250MODULE_LICENSE("GPL"); 1251