hwdrv_APCI1710.c revision 356cdbcb838ebcc234a43ec81621a39231fdcb7a
1/** 2@verbatim 3 4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 5 6 ADDI-DATA GmbH 7 Dieselstrasse 3 8 D-77833 Ottersweier 9 Tel: +19(0)7223/9493-0 10 Fax: +49(0)7223/9493-92 11 http://www.addi-data-com 12 info@addi-data.com 13 14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 15 16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20You shoud also find the complete GPL in the COPYING file accompanying this source code. 21 22@endverbatim 23*/ 24/* 25 +-----------------------------------------------------------------------+ 26 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | 27 +-----------------------------------------------------------------------+ 28 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | 29 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | 30 +-------------------------------+---------------------------------------+ 31 | Project : APCI-1710 | Compiler : GCC | 32 | Module name : hwdrv_apci1710.c| Version : 2.96 | 33 +-------------------------------+---------------------------------------+ 34 | Project manager: Eric Stolz | Date : 02/12/2002 | 35 +-------------------------------+---------------------------------------+ 36 | Description : Hardware Layer Acces For APCI-1710 | 37 +-----------------------------------------------------------------------+ 38 | UPDATES | 39 +----------+-----------+------------------------------------------------+ 40 | Date | Author | Description of updates | 41 +----------+-----------+------------------------------------------------+ 42 | | | | 43 | | | | 44 | | | | 45 +----------+-----------+------------------------------------------------+ 46*/ 47#include "hwdrv_APCI1710.h" 48#include "APCI1710_Inp_cpt.c" 49 50#include "APCI1710_Ssi.c" 51#include "APCI1710_Tor.c" 52#include "APCI1710_Ttl.c" 53#include "APCI1710_Dig_io.c" 54#include "APCI1710_82x54.c" 55#include "APCI1710_Chrono.c" 56#include "APCI1710_Pwm.c" 57#include "APCI1710_INCCPT.c" 58 59void i_ADDI_AttachPCI1710(struct comedi_device *dev) 60{ 61 struct comedi_subdevice *s; 62 int ret = 0; 63 int n_subdevices = 9; 64 65 /* Update-0.7.57->0.7.68dev->n_subdevices = 9; */ 66 if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) 67 return; 68 69 /* Allocate and Initialise Timer Subdevice Structures */ 70 s = dev->subdevices + 0; 71 72 s->type = COMEDI_SUBD_TIMER; 73 s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 74 s->n_chan = 3; 75 s->maxdata = 0; 76 s->len_chanlist = 3; 77 s->range_table = &range_digital; 78 s->insn_write = i_APCI1710_InsnWriteEnableDisableTimer; 79 s->insn_read = i_APCI1710_InsnReadAllTimerValue; 80 s->insn_config = i_APCI1710_InsnConfigInitTimer; 81 s->insn_bits = i_APCI1710_InsnBitsTimer; 82 83 /* Allocate and Initialise DIO Subdevice Structures */ 84 s = dev->subdevices + 1; 85 86 s->type = COMEDI_SUBD_DIO; 87 s->subdev_flags = 88 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 89 s->n_chan = 7; 90 s->maxdata = 1; 91 s->len_chanlist = 7; 92 s->range_table = &range_digital; 93 s->insn_config = i_APCI1710_InsnConfigDigitalIO; 94 s->insn_read = i_APCI1710_InsnReadDigitalIOChlValue; 95 s->insn_bits = i_APCI1710_InsnBitsDigitalIOPortOnOff; 96 s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff; 97 98 /* Allocate and Initialise Chrono Subdevice Structures */ 99 s = dev->subdevices + 2; 100 101 s->type = COMEDI_SUBD_CHRONO; 102 s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 103 s->n_chan = 4; 104 s->maxdata = 0; 105 s->len_chanlist = 4; 106 s->range_table = &range_digital; 107 s->insn_write = i_APCI1710_InsnWriteEnableDisableChrono; 108 s->insn_read = i_APCI1710_InsnReadChrono; 109 s->insn_config = i_APCI1710_InsnConfigInitChrono; 110 s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO; 111 112 /* Allocate and Initialise PWM Subdevice Structures */ 113 s = dev->subdevices + 3; 114 s->type = COMEDI_SUBD_PWM; 115 s->subdev_flags = 116 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 117 s->n_chan = 3; 118 s->maxdata = 1; 119 s->len_chanlist = 3; 120 s->range_table = &range_digital; 121 s->io_bits = 0; /* all bits input */ 122 s->insn_config = i_APCI1710_InsnConfigPWM; 123 s->insn_read = i_APCI1710_InsnReadGetPWMStatus; 124 s->insn_write = i_APCI1710_InsnWritePWM; 125 s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt; 126 127 /* Allocate and Initialise TTLIO Subdevice Structures */ 128 s = dev->subdevices + 4; 129 s->type = COMEDI_SUBD_TTLIO; 130 s->subdev_flags = 131 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 132 s->n_chan = 8; 133 s->maxdata = 1; 134 s->len_chanlist = 8; 135 s->range_table = &range_apci1710_ttl; /* to pass arguments in range */ 136 s->insn_config = i_APCI1710_InsnConfigInitTTLIO; 137 s->insn_bits = i_APCI1710_InsnBitsReadTTLIO; 138 s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff; 139 s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue; 140 141 /* Allocate and Initialise TOR Subdevice Structures */ 142 s = dev->subdevices + 5; 143 s->type = COMEDI_SUBD_TOR; 144 s->subdev_flags = 145 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 146 s->n_chan = 8; 147 s->maxdata = 1; 148 s->len_chanlist = 8; 149 s->range_table = &range_digital; 150 s->io_bits = 0; /* all bits input */ 151 s->insn_config = i_APCI1710_InsnConfigInitTorCounter; 152 s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation; 153 s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter; 154 s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue; 155 156 /* Allocate and Initialise SSI Subdevice Structures */ 157 s = dev->subdevices + 6; 158 s->type = COMEDI_SUBD_SSI; 159 s->subdev_flags = 160 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 161 s->n_chan = 4; 162 s->maxdata = 1; 163 s->len_chanlist = 4; 164 s->range_table = &range_apci1710_ssi; 165 s->insn_config = i_APCI1710_InsnConfigInitSSI; 166 s->insn_read = i_APCI1710_InsnReadSSIValue; 167 s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO; 168 169 /* Allocate and Initialise PULSEENCODER Subdevice Structures */ 170 s = dev->subdevices + 7; 171 s->type = COMEDI_SUBD_PULSEENCODER; 172 s->subdev_flags = 173 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 174 s->n_chan = 4; 175 s->maxdata = 1; 176 s->len_chanlist = 4; 177 s->range_table = &range_digital; 178 s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder; 179 s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder; 180 s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder; 181 s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder; 182 183 /* Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures */ 184 s = dev->subdevices + 8; 185 s->type = COMEDI_SUBD_INCREMENTALCOUNTER; 186 s->subdev_flags = 187 SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON; 188 s->n_chan = 500; 189 s->maxdata = 1; 190 s->len_chanlist = 500; 191 s->range_table = &range_apci1710_inccpt; 192 s->insn_config = i_APCI1710_InsnConfigINCCPT; 193 s->insn_write = i_APCI1710_InsnWriteINCCPT; 194 s->insn_read = i_APCI1710_InsnReadINCCPT; 195 s->insn_bits = i_APCI1710_InsnBitsINCCPT; 196} 197 198int i_APCI1710_Reset(struct comedi_device *dev); 199void v_APCI1710_Interrupt(int irq, void *d); 200/* for 1710 */ 201 202int i_APCI1710_Reset(struct comedi_device *dev) 203{ 204 int ret; 205 unsigned int dw_Dummy; 206 207 /*********************************/ 208 /* Read all module configuration */ 209 /*********************************/ 210 ret = inl(devpriv->s_BoardInfos.ui_Address + 60); 211 devpriv->s_BoardInfos.dw_MolduleConfiguration[0] = ret; 212 213 ret = inl(devpriv->s_BoardInfos.ui_Address + 124); 214 devpriv->s_BoardInfos.dw_MolduleConfiguration[1] = ret; 215 216 ret = inl(devpriv->s_BoardInfos.ui_Address + 188); 217 devpriv->s_BoardInfos.dw_MolduleConfiguration[2] = ret; 218 219 ret = inl(devpriv->s_BoardInfos.ui_Address + 252); 220 devpriv->s_BoardInfos.dw_MolduleConfiguration[3] = ret; 221 222 /* outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60); */ 223 outl(0x83838383, devpriv->s_BoardInfos.ui_Address + 0x60); 224 225 devpriv->s_BoardInfos.b_BoardVersion = 1; 226 227 /* Enable the interrupt for the controler */ 228 dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38); 229 outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38); 230 231 return 0; 232} 233 234/* 235+----------------------------------------------------------------------------+ 236| Function's Name : __void__ v_APCI1710_InterruptFunction | 237| (unsigned char b_Interrupt, __CPPARGS) | 238+----------------------------------------------------------------------------+ 239| Task : APCI-1710 interrupt function | 240+----------------------------------------------------------------------------+ 241| Input Parameters : unsigned char b_Interrupt : Interrupt number | 242+----------------------------------------------------------------------------+ 243| Output Parameters : - | 244+----------------------------------------------------------------------------+ 245| Return Value : 0 : OK | 246| -1 : Error | 247+----------------------------------------------------------------------------+ 248*/ 249 250void v_APCI1710_Interrupt(int irq, void *d) 251{ 252 struct comedi_device *dev = d; 253 unsigned char b_ModuleCpt = 0; 254 unsigned char b_InterruptFlag = 0; 255 unsigned char b_PWMCpt = 0; 256 unsigned char b_TorCounterCpt = 0; 257 unsigned char b_PulseIncoderCpt = 0; 258 unsigned int ui_16BitValue; 259 unsigned int ul_InterruptLatchReg = 0; 260 unsigned int ul_LatchRegisterValue = 0; 261 unsigned int ul_82X54InterruptStatus; 262 unsigned int ul_StatusRegister; 263 264 union str_ModuleInfo *ps_ModuleInfo; 265 266 printk("APCI1710 Interrupt\n"); 267 for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt++, ps_ModuleInfo++) { 268 269 /**************************/ 270 /* 1199/0225 to 0100/0226 */ 271 /**************************/ 272 ps_ModuleInfo = &devpriv->s_ModuleInfo[b_ModuleCpt]; 273 274 /***********************/ 275 /* Test if 82X54 timer */ 276 /***********************/ 277 278 if ((devpriv->s_BoardInfos. 279 dw_MolduleConfiguration[b_ModuleCpt] & 280 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 281 282 /* printk("TIMER Interrupt Occurred\n"); */ 283 ul_82X54InterruptStatus = inl(devpriv->s_BoardInfos. 284 ui_Address + 12 + (64 * b_ModuleCpt)); 285 286 /***************************/ 287 /* Test if interrupt occur */ 288 /***************************/ 289 290 if ((ul_82X54InterruptStatus & ps_ModuleInfo-> 291 s_82X54ModuleInfo. 292 b_InterruptMask) != 0) { 293 devpriv-> 294 s_InterruptParameters. 295 s_FIFOInterruptParameters[devpriv-> 296 s_InterruptParameters. 297 ui_Write]. 298 ul_OldInterruptMask = 299 (ul_82X54InterruptStatus & 300 ps_ModuleInfo->s_82X54ModuleInfo. 301 b_InterruptMask) << 4; 302 303 devpriv-> 304 s_InterruptParameters. 305 s_FIFOInterruptParameters[devpriv-> 306 s_InterruptParameters. 307 ui_Write]. 308 b_OldModuleMask = 1 << b_ModuleCpt; 309 310 devpriv-> 311 s_InterruptParameters. 312 s_FIFOInterruptParameters[devpriv-> 313 s_InterruptParameters. 314 ui_Write].ul_OldCounterLatchValue = 0; 315 316 devpriv-> 317 s_InterruptParameters. 318 ul_InterruptOccur++; 319 320 /****************************/ 321 /* Increment the write FIFO */ 322 /****************************/ 323 324 devpriv-> 325 s_InterruptParameters. 326 ui_Write = (devpriv-> 327 s_InterruptParameters. 328 ui_Write + 1) % APCI1710_SAVE_INTERRUPT; 329 330 b_InterruptFlag = 1; 331 332 /**********************/ 333 /* Call user function */ 334 /**********************/ 335 /* Send a signal to from kernel to user space */ 336 send_sig(SIGIO, devpriv->tsk_Current, 0); 337 338 } /* if ((ul_82X54InterruptStatus & 0x7) != 0) */ 339 } /* 82X54 timer */ 340 341 /***************************/ 342 /* Test if increm. counter */ 343 /***************************/ 344 345 if ((devpriv->s_BoardInfos. 346 dw_MolduleConfiguration[b_ModuleCpt] & 347 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) { 348 349 ul_InterruptLatchReg = inl(devpriv->s_BoardInfos. 350 ui_Address + (64 * b_ModuleCpt)); 351 352 /*********************/ 353 /* Test if interrupt */ 354 /*********************/ 355 356 if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo-> 357 s_SiemensCounterInfo. 358 s_ModeRegister. 359 s_ByteModeRegister. 360 b_ModeRegister2 & 0x80)) { 361 /************************************/ 362 /* Test if strobe latch I interrupt */ 363 /************************************/ 364 365 if (ul_InterruptLatchReg & 2) { 366 ul_LatchRegisterValue = 367 inl(devpriv->s_BoardInfos. 368 ui_Address + 4 + 369 (64 * b_ModuleCpt)); 370 371 devpriv-> 372 s_InterruptParameters. 373 s_FIFOInterruptParameters 374 [devpriv->s_InterruptParameters. 375 ui_Write].ul_OldInterruptMask = 376 1UL; 377 378 devpriv-> 379 s_InterruptParameters. 380 s_FIFOInterruptParameters 381 [devpriv->s_InterruptParameters. 382 ui_Write].b_OldModuleMask = 383 1 << b_ModuleCpt; 384 385 devpriv-> 386 s_InterruptParameters. 387 s_FIFOInterruptParameters 388 [devpriv->s_InterruptParameters. 389 ui_Write]. 390 ul_OldCounterLatchValue = 391 ul_LatchRegisterValue; 392 393 devpriv-> 394 s_InterruptParameters. 395 ul_InterruptOccur++; 396 397 /****************************/ 398 /* 0899/0224 to 1199/0225 */ 399 /****************************/ 400 /* Increment the write FIFO */ 401 /****************************/ 402 403 devpriv-> 404 s_InterruptParameters. 405 ui_Write = (devpriv-> 406 s_InterruptParameters. 407 ui_Write + 408 1) % APCI1710_SAVE_INTERRUPT; 409 410 b_InterruptFlag = 1; 411 412 /**********************/ 413 /* Call user function */ 414 /**********************/ 415 /* Send a signal to from kernel to user space */ 416 send_sig(SIGIO, devpriv->tsk_Current, 417 0); 418 419 } 420 421 /*************************************/ 422 /* Test if strobe latch II interrupt */ 423 /*************************************/ 424 425 if (ul_InterruptLatchReg & 0x20) { 426 427 ul_LatchRegisterValue = 428 inl(devpriv->s_BoardInfos. 429 ui_Address + 8 + 430 (64 * b_ModuleCpt)); 431 432 devpriv-> 433 s_InterruptParameters. 434 s_FIFOInterruptParameters 435 [devpriv->s_InterruptParameters. 436 ui_Write].ul_OldInterruptMask = 437 2UL; 438 439 devpriv-> 440 s_InterruptParameters. 441 s_FIFOInterruptParameters 442 [devpriv->s_InterruptParameters. 443 ui_Write].b_OldModuleMask = 444 1 << b_ModuleCpt; 445 446 devpriv-> 447 s_InterruptParameters. 448 s_FIFOInterruptParameters 449 [devpriv->s_InterruptParameters. 450 ui_Write]. 451 ul_OldCounterLatchValue = 452 ul_LatchRegisterValue; 453 454 devpriv-> 455 s_InterruptParameters. 456 ul_InterruptOccur++; 457 458 /****************************/ 459 /* 0899/0224 to 1199/0225 */ 460 /****************************/ 461 /* Increment the write FIFO */ 462 /****************************/ 463 464 devpriv-> 465 s_InterruptParameters. 466 ui_Write = (devpriv-> 467 s_InterruptParameters. 468 ui_Write + 469 1) % APCI1710_SAVE_INTERRUPT; 470 471 b_InterruptFlag = 1; 472 473 /**********************/ 474 /* Call user function */ 475 /**********************/ 476 /* Send a signal to from kernel to user space */ 477 send_sig(SIGIO, devpriv->tsk_Current, 478 0); 479 480 } 481 } 482 483 ul_InterruptLatchReg = inl(devpriv->s_BoardInfos. 484 ui_Address + 24 + (64 * b_ModuleCpt)); 485 486 /***************************/ 487 /* Test if index interrupt */ 488 /***************************/ 489 490 if (ul_InterruptLatchReg & 0x8) { 491 ps_ModuleInfo-> 492 s_SiemensCounterInfo. 493 s_InitFlag.b_IndexInterruptOccur = 1; 494 495 if (ps_ModuleInfo-> 496 s_SiemensCounterInfo. 497 s_ModeRegister. 498 s_ByteModeRegister. 499 b_ModeRegister2 & 500 APCI1710_INDEX_AUTO_MODE) { 501 502 outl(ps_ModuleInfo-> 503 s_SiemensCounterInfo. 504 s_ModeRegister. 505 dw_ModeRegister1_2_3_4, 506 devpriv->s_BoardInfos. 507 ui_Address + 20 + 508 (64 * b_ModuleCpt)); 509 } 510 511 /*****************************/ 512 /* Test if interrupt enabled */ 513 /*****************************/ 514 515 if ((ps_ModuleInfo-> 516 s_SiemensCounterInfo. 517 s_ModeRegister. 518 s_ByteModeRegister. 519 b_ModeRegister3 & 520 APCI1710_ENABLE_INDEX_INT) == 521 APCI1710_ENABLE_INDEX_INT) { 522 devpriv->s_InterruptParameters. 523 s_FIFOInterruptParameters 524 [devpriv->s_InterruptParameters. 525 ui_Write].ul_OldInterruptMask = 526 4UL; 527 528 devpriv-> 529 s_InterruptParameters. 530 s_FIFOInterruptParameters 531 [devpriv->s_InterruptParameters. 532 ui_Write].b_OldModuleMask = 533 1 << b_ModuleCpt; 534 535 devpriv-> 536 s_InterruptParameters. 537 s_FIFOInterruptParameters 538 [devpriv->s_InterruptParameters. 539 ui_Write]. 540 ul_OldCounterLatchValue = 541 ul_LatchRegisterValue; 542 543 devpriv-> 544 s_InterruptParameters. 545 ul_InterruptOccur++; 546 547 /****************************/ 548 /* 0899/0224 to 1199/0225 */ 549 /****************************/ 550 /* Increment the write FIFO */ 551 /****************************/ 552 553 devpriv-> 554 s_InterruptParameters. 555 ui_Write = (devpriv-> 556 s_InterruptParameters. 557 ui_Write + 558 1) % APCI1710_SAVE_INTERRUPT; 559 560 b_InterruptFlag = 1; 561 562 /**********************/ 563 /* Call user function */ 564 /**********************/ 565 /* Send a signal to from kernel to user space */ 566 send_sig(SIGIO, devpriv->tsk_Current, 567 0); 568 569 } 570 } 571 572 /*****************************/ 573 /* Test if compare interrupt */ 574 /*****************************/ 575 576 if (ul_InterruptLatchReg & 0x10) { 577 /*****************************/ 578 /* Test if interrupt enabled */ 579 /*****************************/ 580 581 if ((ps_ModuleInfo-> 582 s_SiemensCounterInfo. 583 s_ModeRegister. 584 s_ByteModeRegister. 585 b_ModeRegister3 & 586 APCI1710_ENABLE_COMPARE_INT) == 587 APCI1710_ENABLE_COMPARE_INT) { 588 devpriv->s_InterruptParameters. 589 s_FIFOInterruptParameters 590 [devpriv->s_InterruptParameters. 591 ui_Write].ul_OldInterruptMask = 592 8UL; 593 594 devpriv-> 595 s_InterruptParameters. 596 s_FIFOInterruptParameters 597 [devpriv->s_InterruptParameters. 598 ui_Write].b_OldModuleMask = 599 1 << b_ModuleCpt; 600 601 devpriv-> 602 s_InterruptParameters. 603 s_FIFOInterruptParameters 604 [devpriv->s_InterruptParameters. 605 ui_Write]. 606 ul_OldCounterLatchValue = 607 ul_LatchRegisterValue; 608 609 devpriv-> 610 s_InterruptParameters. 611 ul_InterruptOccur++; 612 613 /****************************/ 614 /* 0899/0224 to 1199/0225 */ 615 /****************************/ 616 /* Increment the write FIFO */ 617 /****************************/ 618 619 devpriv-> 620 s_InterruptParameters. 621 ui_Write = (devpriv-> 622 s_InterruptParameters. 623 ui_Write + 624 1) % APCI1710_SAVE_INTERRUPT; 625 626 b_InterruptFlag = 1; 627 628 /**********************/ 629 /* Call user function */ 630 /**********************/ 631 /* Send a signal to from kernel to user space */ 632 send_sig(SIGIO, devpriv->tsk_Current, 633 0); 634 635 } 636 } 637 638 /*******************************************/ 639 /* Test if frequency measurement interrupt */ 640 /*******************************************/ 641 642 if (ul_InterruptLatchReg & 0x20) { 643 /*******************/ 644 /* Read the status */ 645 /*******************/ 646 647 ul_StatusRegister = inl(devpriv->s_BoardInfos. 648 ui_Address + 32 + (64 * b_ModuleCpt)); 649 650 /******************/ 651 /* Read the value */ 652 /******************/ 653 654 ul_LatchRegisterValue = 655 inl(devpriv->s_BoardInfos.ui_Address + 656 28 + (64 * b_ModuleCpt)); 657 658 switch ((ul_StatusRegister >> 1) & 3) { 659 case 0: 660 /*************************/ 661 /* Test the counter mode */ 662 /*************************/ 663 664 if ((devpriv->s_ModuleInfo[b_ModuleCpt]. 665 s_SiemensCounterInfo. 666 s_ModeRegister. 667 s_ByteModeRegister. 668 b_ModeRegister1 & 669 APCI1710_16BIT_COUNTER) 670 == APCI1710_16BIT_COUNTER) { 671 /****************************************/ 672 /* Test if 16-bit counter 1 pulse occur */ 673 /****************************************/ 674 675 if ((ul_LatchRegisterValue & 676 0xFFFFU) != 0) { 677 ui_16BitValue = 678 (unsigned int) 679 ul_LatchRegisterValue 680 & 0xFFFFU; 681 ul_LatchRegisterValue = 682 (ul_LatchRegisterValue 683 & 0xFFFF0000UL) 684 | (0xFFFFU - 685 ui_16BitValue); 686 } 687 688 /****************************************/ 689 /* Test if 16-bit counter 2 pulse occur */ 690 /****************************************/ 691 692 if ((ul_LatchRegisterValue & 693 0xFFFF0000UL) != 694 0) { 695 ui_16BitValue = 696 (unsigned int) ( 697 (ul_LatchRegisterValue 698 >> 16) & 699 0xFFFFU); 700 ul_LatchRegisterValue = 701 (ul_LatchRegisterValue 702 & 0xFFFFUL) | 703 ((0xFFFFU - 704 ui_16BitValue) 705 << 16); 706 } 707 } else { 708 if (ul_LatchRegisterValue != 0) { 709 ul_LatchRegisterValue = 710 0xFFFFFFFFUL - 711 ul_LatchRegisterValue; 712 } 713 } 714 break; 715 716 case 1: 717 /****************************************/ 718 /* Test if 16-bit counter 2 pulse occur */ 719 /****************************************/ 720 721 if ((ul_LatchRegisterValue & 722 0xFFFF0000UL) != 0) { 723 ui_16BitValue = 724 (unsigned int) ( 725 (ul_LatchRegisterValue 726 >> 16) & 727 0xFFFFU); 728 ul_LatchRegisterValue = 729 (ul_LatchRegisterValue & 730 0xFFFFUL) | ((0xFFFFU - 731 ui_16BitValue) 732 << 16); 733 } 734 break; 735 736 case 2: 737 /****************************************/ 738 /* Test if 16-bit counter 1 pulse occur */ 739 /****************************************/ 740 741 if ((ul_LatchRegisterValue & 0xFFFFU) != 742 0) { 743 ui_16BitValue = 744 (unsigned int) 745 ul_LatchRegisterValue & 746 0xFFFFU; 747 ul_LatchRegisterValue = 748 (ul_LatchRegisterValue & 749 0xFFFF0000UL) | (0xFFFFU 750 - ui_16BitValue); 751 } 752 break; 753 } 754 755 devpriv-> 756 s_InterruptParameters. 757 s_FIFOInterruptParameters[devpriv-> 758 s_InterruptParameters. 759 ui_Write]. 760 ul_OldInterruptMask = 0x10000UL; 761 762 devpriv-> 763 s_InterruptParameters. 764 s_FIFOInterruptParameters[devpriv-> 765 s_InterruptParameters. 766 ui_Write]. 767 b_OldModuleMask = 1 << b_ModuleCpt; 768 769 devpriv-> 770 s_InterruptParameters. 771 s_FIFOInterruptParameters[devpriv-> 772 s_InterruptParameters. 773 ui_Write]. 774 ul_OldCounterLatchValue = 775 ul_LatchRegisterValue; 776 777 devpriv-> 778 s_InterruptParameters. 779 ul_InterruptOccur++; 780 781 /****************************/ 782 /* 0899/0224 to 1199/0225 */ 783 /****************************/ 784 /* Increment the write FIFO */ 785 /****************************/ 786 787 devpriv-> 788 s_InterruptParameters. 789 ui_Write = (devpriv-> 790 s_InterruptParameters. 791 ui_Write + 1) % APCI1710_SAVE_INTERRUPT; 792 793 b_InterruptFlag = 1; 794 795 /**********************/ 796 /* Call user function */ 797 /**********************/ 798 /* Send a signal to from kernel to user space */ 799 send_sig(SIGIO, devpriv->tsk_Current, 0); 800 801 } 802 } /* Incremental counter */ 803 804 /***************/ 805 /* Test if CDA */ 806 /***************/ 807 808 if ((devpriv->s_BoardInfos. 809 dw_MolduleConfiguration[b_ModuleCpt] & 810 0xFFFF0000UL) == APCI1710_CDA) { 811 /******************************************/ 812 /* Test if CDA enable and functionality 0 */ 813 /******************************************/ 814 815 if ((devpriv->s_ModuleInfo[b_ModuleCpt]. 816 s_CDAModuleInfo. 817 b_CDAEnable == APCI1710_ENABLE) 818 && (devpriv->s_ModuleInfo[b_ModuleCpt]. 819 s_CDAModuleInfo.b_FctSelection == 0)) { 820 /****************************/ 821 /* Get the interrupt status */ 822 /****************************/ 823 824 ul_StatusRegister = inl(devpriv->s_BoardInfos. 825 ui_Address + 16 + (64 * b_ModuleCpt)); 826 /***************************/ 827 /* Test if interrupt occur */ 828 /***************************/ 829 830 if (ul_StatusRegister & 1) { 831 devpriv-> 832 s_InterruptParameters. 833 s_FIFOInterruptParameters 834 [devpriv->s_InterruptParameters. 835 ui_Write].ul_OldInterruptMask = 836 0x80000UL; 837 838 devpriv-> 839 s_InterruptParameters. 840 s_FIFOInterruptParameters 841 [devpriv->s_InterruptParameters. 842 ui_Write].b_OldModuleMask = 843 1 << b_ModuleCpt; 844 845 devpriv-> 846 s_InterruptParameters. 847 s_FIFOInterruptParameters 848 [devpriv->s_InterruptParameters. 849 ui_Write]. 850 ul_OldCounterLatchValue = 0; 851 852 devpriv-> 853 s_InterruptParameters. 854 ul_InterruptOccur++; 855 856 /****************************/ 857 /* Increment the write FIFO */ 858 /****************************/ 859 860 devpriv-> 861 s_InterruptParameters. 862 ui_Write = (devpriv-> 863 s_InterruptParameters. 864 ui_Write + 865 1) % APCI1710_SAVE_INTERRUPT; 866 867 b_InterruptFlag = 1; 868 869 /**********************/ 870 /* Call user function */ 871 /**********************/ 872 873 /* Send a signal to from kernel to user space */ 874 send_sig(SIGIO, devpriv->tsk_Current, 875 0); 876 877 } /* if (ul_StatusRegister & 1) */ 878 879 } 880 } /* CDA */ 881 882 /***********************/ 883 /* Test if PWM counter */ 884 /***********************/ 885 886 if ((devpriv->s_BoardInfos. 887 dw_MolduleConfiguration[b_ModuleCpt] & 888 0xFFFF0000UL) == APCI1710_PWM) { 889 for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt++) { 890 /*************************************/ 891 /* Test if PWM interrupt initialised */ 892 /*************************************/ 893 894 if (devpriv-> 895 s_ModuleInfo[b_ModuleCpt]. 896 s_PWMModuleInfo. 897 s_PWMInfo[b_PWMCpt]. 898 b_InterruptEnable == APCI1710_ENABLE) { 899 /*****************************/ 900 /* Read the interrupt status */ 901 /*****************************/ 902 903 ul_StatusRegister = 904 inl(devpriv->s_BoardInfos. 905 ui_Address + 16 + 906 (20 * b_PWMCpt) + 907 (64 * b_ModuleCpt)); 908 909 /***************************/ 910 /* Test if interrupt occur */ 911 /***************************/ 912 913 if (ul_StatusRegister & 0x1) { 914 devpriv-> 915 s_InterruptParameters. 916 s_FIFOInterruptParameters 917 [devpriv-> 918 s_InterruptParameters. 919 ui_Write]. 920 ul_OldInterruptMask = 921 0x4000UL << b_PWMCpt; 922 923 devpriv-> 924 s_InterruptParameters. 925 s_FIFOInterruptParameters 926 [devpriv-> 927 s_InterruptParameters. 928 ui_Write]. 929 b_OldModuleMask = 930 1 << b_ModuleCpt; 931 932 devpriv-> 933 s_InterruptParameters. 934 ul_InterruptOccur++; 935 936 /****************************/ 937 /* Increment the write FIFO */ 938 /****************************/ 939 940 devpriv-> 941 s_InterruptParameters. 942 ui_Write = (devpriv-> 943 s_InterruptParameters. 944 ui_Write + 945 1) % 946 APCI1710_SAVE_INTERRUPT; 947 948 b_InterruptFlag = 1; 949 950 /**********************/ 951 /* Call user function */ 952 /**********************/ 953 /* Send a signal to from kernel to user space */ 954 send_sig(SIGIO, 955 devpriv->tsk_Current, 956 0); 957 958 } /* if (ul_StatusRegister & 0x1) */ 959 } /* if (APCI1710_ENABLE) */ 960 } /* for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++) */ 961 } /* PWM counter */ 962 963 /***********************/ 964 /* Test if tor counter */ 965 /***********************/ 966 967 if ((devpriv->s_BoardInfos. 968 dw_MolduleConfiguration[b_ModuleCpt] & 969 0xFFFF0000UL) == APCI1710_TOR_COUNTER) { 970 for (b_TorCounterCpt = 0; b_TorCounterCpt < 2; 971 b_TorCounterCpt++) { 972 /*************************************/ 973 /* Test if tor interrupt initialised */ 974 /*************************************/ 975 976 if (devpriv-> 977 s_ModuleInfo[b_ModuleCpt]. 978 s_TorCounterModuleInfo. 979 s_TorCounterInfo[b_TorCounterCpt]. 980 b_InterruptEnable == APCI1710_ENABLE) { 981 /*****************************/ 982 /* Read the interrupt status */ 983 /*****************************/ 984 985 ul_StatusRegister = 986 inl(devpriv->s_BoardInfos. 987 ui_Address + 12 + 988 (16 * b_TorCounterCpt) + 989 (64 * b_ModuleCpt)); 990 991 /***************************/ 992 /* Test if interrupt occur */ 993 /***************************/ 994 995 if (ul_StatusRegister & 0x1) { 996 /******************************/ 997 /* Read the tor counter value */ 998 /******************************/ 999 1000 ul_LatchRegisterValue = 1001 inl(devpriv-> 1002 s_BoardInfos. 1003 ui_Address + 0 + 1004 (16 * b_TorCounterCpt) + 1005 (64 * b_ModuleCpt)); 1006 1007 devpriv-> 1008 s_InterruptParameters. 1009 s_FIFOInterruptParameters 1010 [devpriv-> 1011 s_InterruptParameters. 1012 ui_Write]. 1013 ul_OldInterruptMask = 1014 0x1000UL << 1015 b_TorCounterCpt; 1016 1017 devpriv-> 1018 s_InterruptParameters. 1019 s_FIFOInterruptParameters 1020 [devpriv-> 1021 s_InterruptParameters. 1022 ui_Write]. 1023 b_OldModuleMask = 1024 1 << b_ModuleCpt; 1025 1026 devpriv-> 1027 s_InterruptParameters. 1028 s_FIFOInterruptParameters 1029 [devpriv-> 1030 s_InterruptParameters. 1031 ui_Write]. 1032 ul_OldCounterLatchValue 1033 = ul_LatchRegisterValue; 1034 1035 devpriv-> 1036 s_InterruptParameters. 1037 ul_InterruptOccur++; 1038 1039 /****************************/ 1040 /* Increment the write FIFO */ 1041 /****************************/ 1042 1043 devpriv-> 1044 s_InterruptParameters. 1045 ui_Write = (devpriv-> 1046 s_InterruptParameters. 1047 ui_Write + 1048 1) % 1049 APCI1710_SAVE_INTERRUPT; 1050 1051 b_InterruptFlag = 1; 1052 1053 /**********************/ 1054 /* Call user function */ 1055 /**********************/ 1056 1057 /* Send a signal to from kernel to user space */ 1058 send_sig(SIGIO, 1059 devpriv->tsk_Current, 1060 0); 1061 } /* if (ul_StatusRegister & 0x1) */ 1062 } /* if (APCI1710_ENABLE) */ 1063 } /* for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++) */ 1064 } /* Tor counter */ 1065 1066 /***********************/ 1067 /* Test if chronometer */ 1068 /***********************/ 1069 1070 if ((devpriv->s_BoardInfos. 1071 dw_MolduleConfiguration[b_ModuleCpt] & 1072 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1073 1074 /* printk("APCI1710 Chrono Interrupt\n"); */ 1075 /*****************************/ 1076 /* Read the interrupt status */ 1077 /*****************************/ 1078 1079 ul_InterruptLatchReg = inl(devpriv->s_BoardInfos. 1080 ui_Address + 12 + (64 * b_ModuleCpt)); 1081 1082 /***************************/ 1083 /* Test if interrupt occur */ 1084 /***************************/ 1085 1086 if ((ul_InterruptLatchReg & 0x8) == 0x8) { 1087 /****************************/ 1088 /* Clear the interrupt flag */ 1089 /****************************/ 1090 1091 outl(0, devpriv->s_BoardInfos. 1092 ui_Address + 32 + (64 * b_ModuleCpt)); 1093 1094 /***************************/ 1095 /* Test if continuous mode */ 1096 /***************************/ 1097 1098 if (ps_ModuleInfo-> 1099 s_ChronoModuleInfo. 1100 b_CycleMode == APCI1710_ENABLE) { 1101 /********************/ 1102 /* Clear the status */ 1103 /********************/ 1104 1105 outl(0, devpriv->s_BoardInfos. 1106 ui_Address + 36 + 1107 (64 * b_ModuleCpt)); 1108 } 1109 1110 /*************************/ 1111 /* Read the timing value */ 1112 /*************************/ 1113 1114 ul_LatchRegisterValue = 1115 inl(devpriv->s_BoardInfos.ui_Address + 1116 4 + (64 * b_ModuleCpt)); 1117 1118 /*****************************/ 1119 /* Test if interrupt enabled */ 1120 /*****************************/ 1121 1122 if (ps_ModuleInfo-> 1123 s_ChronoModuleInfo.b_InterruptMask) { 1124 devpriv-> 1125 s_InterruptParameters. 1126 s_FIFOInterruptParameters 1127 [devpriv->s_InterruptParameters. 1128 ui_Write].ul_OldInterruptMask = 1129 0x80; 1130 1131 devpriv-> 1132 s_InterruptParameters. 1133 s_FIFOInterruptParameters 1134 [devpriv->s_InterruptParameters. 1135 ui_Write].b_OldModuleMask = 1136 1 << b_ModuleCpt; 1137 1138 devpriv-> 1139 s_InterruptParameters. 1140 s_FIFOInterruptParameters 1141 [devpriv->s_InterruptParameters. 1142 ui_Write]. 1143 ul_OldCounterLatchValue = 1144 ul_LatchRegisterValue; 1145 1146 devpriv-> 1147 s_InterruptParameters. 1148 ul_InterruptOccur++; 1149 1150 /****************************/ 1151 /* Increment the write FIFO */ 1152 /****************************/ 1153 1154 devpriv-> 1155 s_InterruptParameters. 1156 ui_Write = (devpriv-> 1157 s_InterruptParameters. 1158 ui_Write + 1159 1) % APCI1710_SAVE_INTERRUPT; 1160 1161 b_InterruptFlag = 1; 1162 1163 /**********************/ 1164 /* Call user function */ 1165 /**********************/ 1166 /* Send a signal to from kernel to user space */ 1167 send_sig(SIGIO, devpriv->tsk_Current, 1168 0); 1169 1170 } 1171 } 1172 } /* Chronometer */ 1173 1174 /*************************/ 1175 /* Test if pulse encoder */ 1176 /*************************/ 1177 1178 if ((devpriv->s_BoardInfos. 1179 dw_MolduleConfiguration[b_ModuleCpt] & 1180 0xFFFF0000UL) == APCI1710_PULSE_ENCODER) { 1181 /****************************/ 1182 /* Read the status register */ 1183 /****************************/ 1184 1185 ul_StatusRegister = inl(devpriv->s_BoardInfos. 1186 ui_Address + 20 + (64 * b_ModuleCpt)); 1187 1188 if (ul_StatusRegister & 0xF) { 1189 for (b_PulseIncoderCpt = 0; 1190 b_PulseIncoderCpt < 4; 1191 b_PulseIncoderCpt++) { 1192 /*************************************/ 1193 /* Test if pulse encoder initialised */ 1194 /*************************************/ 1195 1196 if ((ps_ModuleInfo-> 1197 s_PulseEncoderModuleInfo. 1198 s_PulseEncoderInfo 1199 [b_PulseIncoderCpt]. 1200 b_PulseEncoderInit == 1) 1201 && (((ps_ModuleInfo->s_PulseEncoderModuleInfo.dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) && (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1)) { 1202 devpriv->s_InterruptParameters. 1203 s_FIFOInterruptParameters 1204 [devpriv-> 1205 s_InterruptParameters. 1206 ui_Write]. 1207 ul_OldInterruptMask = 1208 0x100UL << 1209 b_PulseIncoderCpt; 1210 1211 devpriv-> 1212 s_InterruptParameters. 1213 s_FIFOInterruptParameters 1214 [devpriv-> 1215 s_InterruptParameters. 1216 ui_Write]. 1217 b_OldModuleMask = 1218 1 << b_ModuleCpt; 1219 1220 devpriv-> 1221 s_InterruptParameters. 1222 s_FIFOInterruptParameters 1223 [devpriv-> 1224 s_InterruptParameters. 1225 ui_Write]. 1226 ul_OldCounterLatchValue 1227 = ul_LatchRegisterValue; 1228 1229 devpriv-> 1230 s_InterruptParameters. 1231 ul_InterruptOccur++; 1232 1233 /****************************/ 1234 /* 0899/0224 to 1199/0225 */ 1235 /****************************/ 1236 /* Increment the write FIFO */ 1237 /****************************/ 1238 1239 devpriv-> 1240 s_InterruptParameters. 1241 ui_Write = (devpriv-> 1242 s_InterruptParameters. 1243 ui_Write + 1244 1) % 1245 APCI1710_SAVE_INTERRUPT; 1246 1247 b_InterruptFlag = 1; 1248 1249 /**********************/ 1250 /* Call user function */ 1251 /**********************/ 1252 /* Send a signal to from kernel to user space */ 1253 send_sig(SIGIO, 1254 devpriv->tsk_Current, 1255 0); 1256 1257 } 1258 } 1259 } 1260 } /* pulse encoder */ 1261 1262 } 1263 return; 1264 1265} 1266