hwdrv_apci1564.c revision 25417922694e60f04cd4dc8448ada9236f18c532
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 should also find the complete GPL in the COPYING file accompanying this source code. 21 22@endverbatim 23*/ 24/* 25 26 +-----------------------------------------------------------------------+ 27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | 28 +-----------------------------------------------------------------------+ 29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | 30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | 31 +-------------------------------+---------------------------------------+ 32 | Project : APCI-1564 | Compiler : GCC | 33 | Module name : hwdrv_apci1564.c| Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-------------------------------+---------------------------------------+ 37 | Description : Hardware Layer Access For APCI-1564 | 38 +-----------------------------------------------------------------------+ 39 | UPDATES | 40 +----------+-----------+------------------------------------------------+ 41 | Date | Author | Description of updates | 42 +----------+-----------+------------------------------------------------+ 43 | | | | 44 | | | | 45 | | | | 46 +----------+-----------+------------------------------------------------+ 47*/ 48 49/* 50+----------------------------------------------------------------------------+ 51| Included files | 52+----------------------------------------------------------------------------+ 53*/ 54 55#include <linux/delay.h> 56#include "hwdrv_apci1564.h" 57 58/* Global variables */ 59static unsigned int ui_InterruptStatus_1564 = 0; 60static unsigned int ui_InterruptData, ui_Type; 61 62/* 63+----------------------------------------------------------------------------+ 64| Function Name : int i_APCI1564_ConfigDigitalInput | 65| (struct comedi_device *dev,struct comedi_subdevice *s, | 66| struct comedi_insn *insn,unsigned int *data) | 67+----------------------------------------------------------------------------+ 68| Task : Configures the digital input Subdevice | 69+----------------------------------------------------------------------------+ 70| Input Parameters : struct comedi_device *dev : Driver handle | 71| unsigned int *data : Data Pointer contains | 72| configuration parameters as below | 73| | 74| data[0] : 1 Enable Digital Input Interrupt | 75| 0 Disable Digital Input Interrupt | 76| data[1] : 0 ADDIDATA Interrupt OR LOGIC | 77| : 1 ADDIDATA Interrupt AND LOGIC | 78| data[2] : Interrupt mask for the mode 1 | 79| data[3] : Interrupt mask for the mode 2 | 80| | 81+----------------------------------------------------------------------------+ 82| Output Parameters : -- | 83+----------------------------------------------------------------------------+ 84| Return Value : TRUE : No error occur | 85| : FALSE : Error occur. Return the error | 86| | 87+----------------------------------------------------------------------------+ 88*/ 89int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, 90 struct comedi_insn *insn, unsigned int *data) 91{ 92 devpriv->tsk_Current = current; 93 /*******************************/ 94 /* Set the digital input logic */ 95 /*******************************/ 96 if (data[0] == ADDIDATA_ENABLE) { 97 data[2] = data[2] << 4; 98 data[3] = data[3] << 4; 99 outl(data[2], 100 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 101 APCI1564_DIGITAL_IP_INTERRUPT_MODE1); 102 outl(data[3], 103 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 104 APCI1564_DIGITAL_IP_INTERRUPT_MODE2); 105 if (data[1] == ADDIDATA_OR) { 106 outl(0x4, 107 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 108 APCI1564_DIGITAL_IP_IRQ); 109 } /* if (data[1] == ADDIDATA_OR) */ 110 else { 111 outl(0x6, 112 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 113 APCI1564_DIGITAL_IP_IRQ); 114 } /* else if (data[1] == ADDIDATA_OR) */ 115 } /* if (data[0] == ADDIDATA_ENABLE) */ 116 else { 117 outl(0x0, 118 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 119 APCI1564_DIGITAL_IP_INTERRUPT_MODE1); 120 outl(0x0, 121 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 122 APCI1564_DIGITAL_IP_INTERRUPT_MODE2); 123 outl(0x0, 124 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 125 APCI1564_DIGITAL_IP_IRQ); 126 } /* else if (data[0] == ADDIDATA_ENABLE) */ 127 128 return insn->n; 129} 130 131/* 132+----------------------------------------------------------------------------+ 133| Function Name : int i_APCI1564_Read1DigitalInput | 134| (struct comedi_device *dev,struct comedi_subdevice *s, | 135| struct comedi_insn *insn,unsigned int *data) | 136+----------------------------------------------------------------------------+ 137| Task : Return the status of the digital input | 138+----------------------------------------------------------------------------+ 139| Input Parameters : struct comedi_device *dev : Driver handle | 140| unsigned int ui_Channel : Channel number to read | 141| unsigned int *data : Data Pointer to read status | 142+----------------------------------------------------------------------------+ 143| Output Parameters : -- | 144+----------------------------------------------------------------------------+ 145| Return Value : TRUE : No error occur | 146| : FALSE : Error occur. Return the error | 147| | 148+----------------------------------------------------------------------------+ 149*/ 150int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, 151 struct comedi_insn *insn, unsigned int *data) 152{ 153 unsigned int ui_TmpValue = 0; 154 unsigned int ui_Channel; 155 156 ui_Channel = CR_CHAN(insn->chanspec); 157 if (ui_Channel <= 31) { 158 ui_TmpValue = 159 (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); 160/* 161* since only 1 channel reqd to bring it to last bit it is rotated 8 162* +(chan - 1) times then ANDed with 1 for last bit. 163*/ 164 *data = (ui_TmpValue >> ui_Channel) & 0x1; 165 } /* if (ui_Channel >= 0 && ui_Channel <=31) */ 166 else { 167 comedi_error(dev, "Not a valid channel number !!! \n"); 168 return -EINVAL; /* "sorry channel spec wrong " */ 169 } /* else if (ui_Channel >= 0 && ui_Channel <=31) */ 170 return insn->n; 171} 172 173/* 174+----------------------------------------------------------------------------+ 175| Function Name : int i_APCI1564_ReadMoreDigitalInput | 176| (struct comedi_device *dev,struct comedi_subdevice *s, | 177| struct comedi_insn *insn,unsigned int *data) | 178+----------------------------------------------------------------------------+ 179| Task : Return the status of the Requested digital inputs | 180+----------------------------------------------------------------------------+ 181| Input Parameters : struct comedi_device *dev : Driver handle | 182| unsigned int ui_NoOfChannels : No Of Channels To be Read | 183| unsigned int *data : Data Pointer to read status | 184+----------------------------------------------------------------------------+ 185| Output Parameters : -- | 186+----------------------------------------------------------------------------+ 187| Return Value : TRUE : No error occur | 188| : FALSE : Error occur. Return the error | 189| | 190+----------------------------------------------------------------------------+ 191*/ 192int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, 193 struct comedi_insn *insn, unsigned int *data) 194{ 195 unsigned int ui_PortValue = data[0]; 196 unsigned int ui_Mask = 0; 197 unsigned int ui_NoOfChannels; 198 199 ui_NoOfChannels = CR_CHAN(insn->chanspec); 200 if (data[1] == 0) { 201 *data = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); 202 switch (ui_NoOfChannels) { 203 case 2: 204 ui_Mask = 3; 205 *data = (*data >> (2 * ui_PortValue)) & ui_Mask; 206 break; 207 case 4: 208 ui_Mask = 15; 209 *data = (*data >> (4 * ui_PortValue)) & ui_Mask; 210 break; 211 case 8: 212 ui_Mask = 255; 213 *data = (*data >> (8 * ui_PortValue)) & ui_Mask; 214 break; 215 case 16: 216 ui_Mask = 65535; 217 *data = (*data >> (16 * ui_PortValue)) & ui_Mask; 218 break; 219 case 31: 220 break; 221 default: 222 comedi_error(dev, "Not a valid Channel number !!!\n"); 223 return -EINVAL; /* "sorry channel spec wrong " */ 224 break; 225 } /* switch (ui_NoOfChannels) */ 226 } /* if (data[1]==0) */ 227 else { 228 if (data[1] == 1) { 229 *data = ui_InterruptStatus_1564; 230 } /* if (data[1]==1) */ 231 } /* else if (data[1]==0) */ 232 return insn->n; 233} 234 235/* 236+----------------------------------------------------------------------------+ 237| Function Name : int i_APCI1564_ConfigDigitalOutput | 238| (struct comedi_device *dev,struct comedi_subdevice *s, | 239| struct comedi_insn *insn,unsigned int *data) | 240+----------------------------------------------------------------------------+ 241| Task : Configures The Digital Output Subdevice. | 242+----------------------------------------------------------------------------+ 243| Input Parameters : struct comedi_device *dev : Driver handle | 244| unsigned int *data : Data Pointer contains | 245| configuration parameters as below | 246| | 247| data[1] : 1 Enable VCC Interrupt | 248| 0 Disable VCC Interrupt | 249| data[2] : 1 Enable CC Interrupt | 250| 0 Disable CC Interrupt | 251| | 252+----------------------------------------------------------------------------+ 253| Output Parameters : -- | 254+----------------------------------------------------------------------------+ 255| Return Value : TRUE : No error occur | 256| : FALSE : Error occur. Return the error | 257| | 258+----------------------------------------------------------------------------+ 259*/ 260int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, 261 struct comedi_insn *insn, unsigned int *data) 262{ 263 unsigned int ul_Command = 0; 264 265 if ((data[0] != 0) && (data[0] != 1)) { 266 comedi_error(dev, 267 "Not a valid Data !!! ,Data should be 1 or 0\n"); 268 return -EINVAL; 269 } /* if ((data[0]!=0) && (data[0]!=1)) */ 270 if (data[0]) { 271 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; 272 } /* if (data[0]) */ 273 else { 274 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; 275 } /* else if (data[0]) */ 276 if (data[1] == ADDIDATA_ENABLE) { 277 ul_Command = ul_Command | 0x1; 278 } /* if (data[1] == ADDIDATA_ENABLE) */ 279 else { 280 ul_Command = ul_Command & 0xFFFFFFFE; 281 } /* else if (data[1] == ADDIDATA_ENABLE) */ 282 if (data[2] == ADDIDATA_ENABLE) { 283 ul_Command = ul_Command | 0x2; 284 } /* if (data[2] == ADDIDATA_ENABLE) */ 285 else { 286 ul_Command = ul_Command & 0xFFFFFFFD; 287 } /* else if (data[2] == ADDIDATA_ENABLE) */ 288 outl(ul_Command, 289 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 290 APCI1564_DIGITAL_OP_INTERRUPT); 291 ui_InterruptData = 292 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 293 APCI1564_DIGITAL_OP_INTERRUPT); 294 devpriv->tsk_Current = current; 295 return insn->n; 296} 297 298/* 299+----------------------------------------------------------------------------+ 300| Function Name : int i_APCI1564_WriteDigitalOutput | 301| (struct comedi_device *dev,struct comedi_subdevice *s, | 302| struct comedi_insn *insn,unsigned int *data) | 303+----------------------------------------------------------------------------+ 304| Task : Writes port value To the selected port | 305+----------------------------------------------------------------------------+ 306| Input Parameters : struct comedi_device *dev : Driver handle | 307| unsigned int ui_NoOfChannels : No Of Channels To Write | 308| unsigned int *data : Data Pointer to read status | 309+----------------------------------------------------------------------------+ 310| Output Parameters : -- | 311+----------------------------------------------------------------------------+ 312| Return Value : TRUE : No error occur | 313| : FALSE : Error occur. Return the error | 314| | 315+----------------------------------------------------------------------------+ 316*/ 317int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, 318 struct comedi_insn *insn, unsigned int *data) 319{ 320 unsigned int ui_Temp, ui_Temp1; 321 unsigned int ui_NoOfChannel; 322 323 ui_NoOfChannel = CR_CHAN(insn->chanspec); 324 if (devpriv->b_OutputMemoryStatus) { 325 ui_Temp = 326 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 327 APCI1564_DIGITAL_OP_RW); 328 } /* if (devpriv->b_OutputMemoryStatus ) */ 329 else { 330 ui_Temp = 0; 331 } /* else if (devpriv->b_OutputMemoryStatus ) */ 332 if (data[3] == 0) { 333 if (data[1] == 0) { 334 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; 335 outl(data[0], 336 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 337 APCI1564_DIGITAL_OP_RW); 338 } /* if (data[1]==0) */ 339 else { 340 if (data[1] == 1) { 341 switch (ui_NoOfChannel) { 342 case 2: 343 data[0] = 344 (data[0] << (2 * 345 data[2])) | ui_Temp; 346 break; 347 case 4: 348 data[0] = 349 (data[0] << (4 * 350 data[2])) | ui_Temp; 351 break; 352 case 8: 353 data[0] = 354 (data[0] << (8 * 355 data[2])) | ui_Temp; 356 break; 357 case 16: 358 data[0] = 359 (data[0] << (16 * 360 data[2])) | ui_Temp; 361 break; 362 case 31: 363 data[0] = data[0] | ui_Temp; 364 break; 365 default: 366 comedi_error(dev, " chan spec wrong"); 367 return -EINVAL; /* "sorry channel spec wrong " */ 368 } /* switch (ui_NoOfChannels) */ 369 outl(data[0], 370 devpriv->i_IobaseAmcc + 371 APCI1564_DIGITAL_OP + 372 APCI1564_DIGITAL_OP_RW); 373 } /* if (data[1]==1) */ 374 else { 375 printk("\nSpecified channel not supported\n"); 376 } /* else if (data[1]==1) */ 377 } /* else if (data[1]==0) */ 378 } /* if(data[3]==0) */ 379 else { 380 if (data[3] == 1) { 381 if (data[1] == 0) { 382 data[0] = ~data[0] & 0x1; 383 ui_Temp1 = 1; 384 ui_Temp1 = ui_Temp1 << ui_NoOfChannel; 385 ui_Temp = ui_Temp | ui_Temp1; 386 data[0] = 387 (data[0] << ui_NoOfChannel) ^ 388 0xffffffff; 389 data[0] = data[0] & ui_Temp; 390 outl(data[0], 391 devpriv->i_IobaseAmcc + 392 APCI1564_DIGITAL_OP + 393 APCI1564_DIGITAL_OP_RW); 394 } /* if (data[1]==0) */ 395 else { 396 if (data[1] == 1) { 397 switch (ui_NoOfChannel) { 398 case 2: 399 data[0] = ~data[0] & 0x3; 400 ui_Temp1 = 3; 401 ui_Temp1 = 402 ui_Temp1 << 2 * data[2]; 403 ui_Temp = ui_Temp | ui_Temp1; 404 data[0] = 405 ((data[0] << (2 * 406 data 407 [2])) ^ 408 0xffffffff) & ui_Temp; 409 break; 410 case 4: 411 data[0] = ~data[0] & 0xf; 412 ui_Temp1 = 15; 413 ui_Temp1 = 414 ui_Temp1 << 4 * data[2]; 415 ui_Temp = ui_Temp | ui_Temp1; 416 data[0] = 417 ((data[0] << (4 * 418 data 419 [2])) ^ 420 0xffffffff) & ui_Temp; 421 break; 422 case 8: 423 data[0] = ~data[0] & 0xff; 424 ui_Temp1 = 255; 425 ui_Temp1 = 426 ui_Temp1 << 8 * data[2]; 427 ui_Temp = ui_Temp | ui_Temp1; 428 data[0] = 429 ((data[0] << (8 * 430 data 431 [2])) ^ 432 0xffffffff) & ui_Temp; 433 break; 434 case 16: 435 data[0] = ~data[0] & 0xffff; 436 ui_Temp1 = 65535; 437 ui_Temp1 = 438 ui_Temp1 << 16 * 439 data[2]; 440 ui_Temp = ui_Temp | ui_Temp1; 441 data[0] = 442 ((data[0] << (16 * 443 data 444 [2])) ^ 445 0xffffffff) & ui_Temp; 446 break; 447 case 31: 448 break; 449 default: 450 comedi_error(dev, 451 " chan spec wrong"); 452 return -EINVAL; /* "sorry channel spec wrong " */ 453 } /* switch(ui_NoOfChannels) */ 454 outl(data[0], 455 devpriv->i_IobaseAmcc + 456 APCI1564_DIGITAL_OP + 457 APCI1564_DIGITAL_OP_RW); 458 } /* if (data[1]==1) */ 459 else { 460 printk("\nSpecified channel not supported\n"); 461 } /* else if (data[1]==1) */ 462 } /* else if (data[1]==0) */ 463 } /* if (data[3]==1); */ 464 else { 465 printk("\nSpecified functionality does not exist\n"); 466 return -EINVAL; 467 } /* else if (data[3]==1) */ 468 } /* else if (data[3]==0) */ 469 return insn->n; 470} 471 472/* 473+----------------------------------------------------------------------------+ 474| Function Name : int i_APCI1564_ReadDigitalOutput | 475| (struct comedi_device *dev,struct comedi_subdevice *s, | 476| struct comedi_insn *insn,unsigned int *data) | 477+----------------------------------------------------------------------------+ 478| Task : Read value of the selected channel or port | 479+----------------------------------------------------------------------------+ 480| Input Parameters : struct comedi_device *dev : Driver handle | 481| unsigned int ui_NoOfChannels : No Of Channels To read | 482| unsigned int *data : Data Pointer to read status | 483+----------------------------------------------------------------------------+ 484| Output Parameters : -- | 485+----------------------------------------------------------------------------+ 486| Return Value : TRUE : No error occur | 487| : FALSE : Error occur. Return the error | 488| | 489+----------------------------------------------------------------------------+ 490*/ 491int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, 492 struct comedi_insn *insn, unsigned int *data) 493{ 494 unsigned int ui_Temp; 495 unsigned int ui_NoOfChannel; 496 497 ui_NoOfChannel = CR_CHAN(insn->chanspec); 498 ui_Temp = data[0]; 499 *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 500 APCI1564_DIGITAL_OP_RW); 501 if (ui_Temp == 0) { 502 *data = (*data >> ui_NoOfChannel) & 0x1; 503 } /* if (ui_Temp==0) */ 504 else { 505 if (ui_Temp == 1) { 506 switch (ui_NoOfChannel) { 507 case 2: 508 *data = (*data >> (2 * data[1])) & 3; 509 break; 510 511 case 4: 512 *data = (*data >> (4 * data[1])) & 15; 513 break; 514 515 case 8: 516 *data = (*data >> (8 * data[1])) & 255; 517 break; 518 519 case 16: 520 *data = (*data >> (16 * data[1])) & 65535; 521 break; 522 523 case 31: 524 break; 525 526 default: 527 comedi_error(dev, " chan spec wrong"); 528 return -EINVAL; /* "sorry channel spec wrong " */ 529 break; 530 } /* switch(ui_NoOfChannels) */ 531 } /* if (ui_Temp==1) */ 532 else { 533 printk("\nSpecified channel not supported \n"); 534 } /* else if (ui_Temp==1) */ 535 } /* else if (ui_Temp==0) */ 536 return insn->n; 537} 538 539/* 540+----------------------------------------------------------------------------+ 541| Function Name : int i_APCI1564_ConfigTimerCounterWatchdog | 542| (struct comedi_device *dev,struct comedi_subdevice *s, | 543| struct comedi_insn *insn,unsigned int *data) | 544+----------------------------------------------------------------------------+ 545| Task : Configures The Timer , Counter or Watchdog | 546+----------------------------------------------------------------------------+ 547| Input Parameters : struct comedi_device *dev : Driver handle | 548| unsigned int *data : Data Pointer contains | 549| configuration parameters as below | 550| | 551| data[0] : 0 Configure As Timer | 552| 1 Configure As Counter | 553| 2 Configure As Watchdog | 554| data[1] : 1 Enable Interrupt | 555| 0 Disable Interrupt | 556| data[2] : Time Unit | 557| data[3] : Reload Value | 558| data[4] : Timer Mode | 559| data[5] : Timer Counter Watchdog Number| 560 data[6] : Counter Direction 561+----------------------------------------------------------------------------+ 562| Output Parameters : -- | 563+----------------------------------------------------------------------------+ 564| Return Value : TRUE : No error occur | 565| : FALSE : Error occur. Return the error | 566| | 567+----------------------------------------------------------------------------+ 568*/ 569int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, 570 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 571{ 572 unsigned int ul_Command1 = 0; 573 devpriv->tsk_Current = current; 574 if (data[0] == ADDIDATA_WATCHDOG) { 575 devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; 576 577 /* Disable the watchdog */ 578 outl(0x0, 579 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + 580 APCI1564_TCW_PROG); 581 /* Loading the Reload value */ 582 outl(data[3], 583 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + 584 APCI1564_TCW_RELOAD_VALUE); 585 } /* if (data[0]==ADDIDATA_WATCHDOG) */ 586 else if (data[0] == ADDIDATA_TIMER) { 587 /* First Stop The Timer */ 588 ul_Command1 = 589 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 590 APCI1564_TCW_PROG); 591 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; 592 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* Stop The Timer */ 593 594 devpriv->b_TimerSelectMode = ADDIDATA_TIMER; 595 if (data[1] == 1) { 596 outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ 597 outl(0x0, 598 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 599 APCI1564_DIGITAL_IP_IRQ); 600 outl(0x0, 601 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 602 APCI1564_DIGITAL_OP_IRQ); 603 outl(0x0, 604 devpriv->i_IobaseAmcc + 605 APCI1564_DIGITAL_OP_WATCHDOG + 606 APCI1564_TCW_IRQ); 607 outl(0x0, 608 devpriv->iobase + APCI1564_COUNTER1 + 609 APCI1564_TCW_IRQ); 610 outl(0x0, 611 devpriv->iobase + APCI1564_COUNTER2 + 612 APCI1564_TCW_IRQ); 613 outl(0x0, 614 devpriv->iobase + APCI1564_COUNTER3 + 615 APCI1564_TCW_IRQ); 616 outl(0x0, 617 devpriv->iobase + APCI1564_COUNTER4 + 618 APCI1564_TCW_IRQ); 619 } /* if (data[1]==1) */ 620 else { 621 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* disable Timer interrupt */ 622 } /* else if (data[1]==1) */ 623 624 /* Loading Timebase */ 625 626 outl(data[2], 627 devpriv->i_IobaseAmcc + APCI1564_TIMER + 628 APCI1564_TCW_TIMEBASE); 629 630 /* Loading the Reload value */ 631 outl(data[3], 632 devpriv->i_IobaseAmcc + APCI1564_TIMER + 633 APCI1564_TCW_RELOAD_VALUE); 634 635 ul_Command1 = 636 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 637 APCI1564_TCW_PROG); 638 ul_Command1 = 639 (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; 640 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* mode 2 */ 641 } /* else if (data[0]==ADDIDATA_TIMER) */ 642 else if (data[0] == ADDIDATA_COUNTER) { 643 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; 644 devpriv->b_ModeSelectRegister = data[5]; 645 646 /* First Stop The Counter */ 647 ul_Command1 = 648 inl(devpriv->iobase + ((data[5] - 1) * 0x20) + 649 APCI1564_TCW_PROG); 650 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; 651 outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); /* Stop The Timer */ 652 653 /************************/ 654 /* Set the reload value */ 655 /************************/ 656 outl(data[3], 657 devpriv->iobase + ((data[5] - 1) * 0x20) + 658 APCI1564_TCW_RELOAD_VALUE); 659 660 /******************************/ 661 /* Set the mode : */ 662 /* - Disable the hardware */ 663 /* - Disable the counter mode */ 664 /* - Disable the warning */ 665 /* - Disable the reset */ 666 /* - Disable the timer mode */ 667 /* - Enable the counter mode */ 668 /******************************/ 669 ul_Command1 = 670 (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | 671 (unsigned int) ((unsigned int) data[4] << 16UL); 672 outl(ul_Command1, 673 devpriv->iobase + ((data[5] - 1) * 0x20) + 674 APCI1564_TCW_PROG); 675 676 /* Enable or Disable Interrupt */ 677 ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1); 678 outl(ul_Command1, 679 devpriv->iobase + ((data[5] - 1) * 0x20) + 680 APCI1564_TCW_PROG); 681 682 /*****************************/ 683 /* Set the Up/Down selection */ 684 /*****************************/ 685 ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18); 686 outl(ul_Command1, 687 devpriv->iobase + ((data[5] - 1) * 0x20) + 688 APCI1564_TCW_PROG); 689 } /* else if (data[0]==ADDIDATA_COUNTER) */ 690 else { 691 printk(" Invalid subdevice."); 692 } /* else if (data[0]==ADDIDATA_WATCHDOG) */ 693 694 return insn->n; 695} 696 697/* 698+----------------------------------------------------------------------------+ 699| Function Name : int i_APCI1564_StartStopWriteTimerCounterWatchdog | 700| (struct comedi_device *dev,struct comedi_subdevice *s, | 701| struct comedi_insn *insn,unsigned int *data) | 702+----------------------------------------------------------------------------+ 703| Task : Start / Stop The Selected Timer , Counter or Watchdog | 704+----------------------------------------------------------------------------+ 705| Input Parameters : struct comedi_device *dev : Driver handle | 706| unsigned int *data : Data Pointer contains | 707| configuration parameters as below | 708| | 709| data[0] : 0 Timer | 710| 1 Counter | 711| 2 Watchdog | | data[1] : 1 Start | 712| 0 Stop | 713| 2 Trigger | 714| Clear (Only Counter) | 715+----------------------------------------------------------------------------+ 716| Output Parameters : -- | 717+----------------------------------------------------------------------------+ 718| Return Value : TRUE : No error occur | 719| : FALSE : Error occur. Return the error | 720| | 721+----------------------------------------------------------------------------+ 722*/ 723int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, 724 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 725{ 726 unsigned int ul_Command1 = 0; 727 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 728 switch (data[1]) { 729 case 0: /* stop the watchdog */ 730 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG); /* disable the watchdog */ 731 break; 732 case 1: /* start the watchdog */ 733 outl(0x0001, 734 devpriv->i_IobaseAmcc + 735 APCI1564_DIGITAL_OP_WATCHDOG + 736 APCI1564_TCW_PROG); 737 break; 738 case 2: /* Software trigger */ 739 outl(0x0201, 740 devpriv->i_IobaseAmcc + 741 APCI1564_DIGITAL_OP_WATCHDOG + 742 APCI1564_TCW_PROG); 743 break; 744 default: 745 printk("\nSpecified functionality does not exist\n"); 746 return -EINVAL; 747 } /* switch (data[1]) */ 748 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */ 749 if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { 750 if (data[1] == 1) { 751 ul_Command1 = 752 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 753 APCI1564_TCW_PROG); 754 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; 755 756 /* Enable the Timer */ 757 outl(ul_Command1, 758 devpriv->i_IobaseAmcc + APCI1564_TIMER + 759 APCI1564_TCW_PROG); 760 } /* if (data[1]==1) */ 761 else if (data[1] == 0) { 762 /* Stop The Timer */ 763 764 ul_Command1 = 765 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 766 APCI1564_TCW_PROG); 767 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; 768 outl(ul_Command1, 769 devpriv->i_IobaseAmcc + APCI1564_TIMER + 770 APCI1564_TCW_PROG); 771 } /* else if(data[1]==0) */ 772 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */ 773 if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) { 774 ul_Command1 = 775 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister - 776 1) * 0x20) + APCI1564_TCW_PROG); 777 if (data[1] == 1) { 778 /* Start the Counter subdevice */ 779 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; 780 } /* if (data[1] == 1) */ 781 else if (data[1] == 0) { 782 /* Stops the Counter subdevice */ 783 ul_Command1 = 0; 784 785 } /* else if (data[1] == 0) */ 786 else if (data[1] == 2) { 787 /* Clears the Counter subdevice */ 788 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400; 789 } /* else if (data[1] == 3) */ 790 outl(ul_Command1, 791 devpriv->iobase + ((devpriv->b_ModeSelectRegister - 792 1) * 0x20) + APCI1564_TCW_PROG); 793 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */ 794 return insn->n; 795} 796 797/* 798+----------------------------------------------------------------------------+ 799| Function Name : int i_APCI1564_ReadTimerCounterWatchdog | 800| (struct comedi_device *dev,struct comedi_subdevice *s, | 801| struct comedi_insn *insn,unsigned int *data) | 802+----------------------------------------------------------------------------+ 803| Task : Read The Selected Timer , Counter or Watchdog | 804+----------------------------------------------------------------------------+ 805| Input Parameters : struct comedi_device *dev : Driver handle | 806| unsigned int *data : Data Pointer contains | 807| configuration parameters as below | 808| | 809 810+----------------------------------------------------------------------------+ 811| Output Parameters : -- | 812+----------------------------------------------------------------------------+ 813| Return Value : TRUE : No error occur | 814| : FALSE : Error occur. Return the error | 815| | 816+----------------------------------------------------------------------------+ 817*/ 818int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, 819 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 820{ 821 unsigned int ul_Command1 = 0; 822 823 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 824 /* Stores the status of the Watchdog */ 825 data[0] = 826 inl(devpriv->i_IobaseAmcc + 827 APCI1564_DIGITAL_OP_WATCHDOG + 828 APCI1564_TCW_TRIG_STATUS) & 0x1; 829 data[1] = 830 inl(devpriv->i_IobaseAmcc + 831 APCI1564_DIGITAL_OP_WATCHDOG); 832 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */ 833 else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { 834 /* Stores the status of the Timer */ 835 data[0] = 836 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 837 APCI1564_TCW_TRIG_STATUS) & 0x1; 838 839 /* Stores the Actual value of the Timer */ 840 data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER); 841 } /* else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */ 842 else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) { 843 /* Read the Counter Actual Value. */ 844 data[0] = 845 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister - 846 1) * 0x20) + 847 APCI1564_TCW_SYNC_ENABLEDISABLE); 848 ul_Command1 = 849 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister - 850 1) * 0x20) + APCI1564_TCW_TRIG_STATUS); 851 852 /***********************************/ 853 /* Get the software trigger status */ 854 /***********************************/ 855 data[1] = (unsigned char) ((ul_Command1 >> 1) & 1); 856 857 /***********************************/ 858 /* Get the hardware trigger status */ 859 /***********************************/ 860 data[2] = (unsigned char) ((ul_Command1 >> 2) & 1); 861 862 /*********************************/ 863 /* Get the software clear status */ 864 /*********************************/ 865 data[3] = (unsigned char) ((ul_Command1 >> 3) & 1); 866 867 /***************************/ 868 /* Get the overflow status */ 869 /***************************/ 870 data[4] = (unsigned char) ((ul_Command1 >> 0) & 1); 871 } /* else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */ 872 else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER) 873 && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG) 874 && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) { 875 printk("\n Invalid Subdevice !!!\n"); 876 } /* else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER)) */ 877 return insn->n; 878} 879 880/* 881+----------------------------------------------------------------------------+ 882| Function Name : int i_APCI1564_ReadInterruptStatus | 883| (struct comedi_device *dev,struct comedi_subdevice *s, | 884| struct comedi_insn *insn,unsigned int *data) | 885+----------------------------------------------------------------------------+ 886| Task :Reads the interrupt status register | 887+----------------------------------------------------------------------------+ 888| Input Parameters : | 889+----------------------------------------------------------------------------+ 890| Output Parameters : -- | 891+----------------------------------------------------------------------------+ 892| Return Value : | 893| | 894+----------------------------------------------------------------------------+ 895*/ 896 897int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, 898 struct comedi_insn *insn, unsigned int *data) 899{ 900 *data = ui_Type; 901 return insn->n; 902} 903 904/* 905+----------------------------------------------------------------------------+ 906| Function Name : static void v_APCI1564_Interrupt | 907| (int irq , void *d) | 908+----------------------------------------------------------------------------+ 909| Task : Interrupt handler for the interruptible digital inputs | 910+----------------------------------------------------------------------------+ 911| Input Parameters : int irq : irq number | 912| void *d : void pointer | 913+----------------------------------------------------------------------------+ 914| Output Parameters : -- | 915+----------------------------------------------------------------------------+ 916| Return Value : TRUE : No error occur | 917| : FALSE : Error occur. Return the error | 918| | 919+----------------------------------------------------------------------------+ 920*/ 921static void v_APCI1564_Interrupt(int irq, void *d) 922{ 923 struct comedi_device *dev = d; 924 unsigned int ui_DO, ui_DI; 925 unsigned int ui_Timer; 926 unsigned int ui_C1, ui_C2, ui_C3, ui_C4; 927 unsigned int ul_Command2 = 0; 928 ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 929 APCI1564_DIGITAL_IP_IRQ) & 0x01; 930 ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 931 APCI1564_DIGITAL_OP_IRQ) & 0x01; 932 ui_Timer = 933 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 934 APCI1564_TCW_IRQ) & 0x01; 935 ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 + 936 APCI1564_TCW_IRQ) & 0x1; 937 ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 + 938 APCI1564_TCW_IRQ) & 0x1; 939 ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 + 940 APCI1564_TCW_IRQ) & 0x1; 941 ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 + 942 APCI1564_TCW_IRQ) & 0x1; 943 if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0 944 && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) { 945 printk("\nInterrupt from unknown source\n"); 946 } /* if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0) */ 947 948 if (ui_DI == 1) { 949 ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 950 APCI1564_DIGITAL_IP_IRQ); 951 outl(0x0, 952 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 953 APCI1564_DIGITAL_IP_IRQ); 954 ui_InterruptStatus_1564 = 955 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + 956 APCI1564_DIGITAL_IP_INTERRUPT_STATUS); 957 ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0; 958 send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ 959 outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); /* enable the interrupt */ 960 return; 961 } 962 963 if (ui_DO == 1) { 964 /* Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */ 965 ui_Type = 966 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 967 APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3; 968 /* Disable the Interrupt */ 969 outl(0x0, 970 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + 971 APCI1564_DIGITAL_OP_INTERRUPT); 972 973 /* Sends signal to user space */ 974 send_sig(SIGIO, devpriv->tsk_Current, 0); 975 976 } /* if (ui_DO) */ 977 978 if (ui_Timer == 1) { 979 devpriv->b_TimerSelectMode = ADDIDATA_TIMER; 980 if (devpriv->b_TimerSelectMode) { 981 982 /* Disable Timer Interrupt */ 983 ul_Command2 = 984 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + 985 APCI1564_TCW_PROG); 986 outl(0x0, 987 devpriv->i_IobaseAmcc + APCI1564_TIMER + 988 APCI1564_TCW_PROG); 989 990 /* Send a signal to from kernel to user space */ 991 send_sig(SIGIO, devpriv->tsk_Current, 0); 992 993 /* Enable Timer Interrupt */ 994 995 outl(ul_Command2, 996 devpriv->i_IobaseAmcc + APCI1564_TIMER + 997 APCI1564_TCW_PROG); 998 } 999 }/* if (ui_Timer == 1) */ 1000 1001 1002 if (ui_C1 == 1) { 1003 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; 1004 if (devpriv->b_TimerSelectMode) { 1005 1006 /* Disable Counter Interrupt */ 1007 ul_Command2 = 1008 inl(devpriv->iobase + APCI1564_COUNTER1 + 1009 APCI1564_TCW_PROG); 1010 outl(0x0, 1011 devpriv->iobase + APCI1564_COUNTER1 + 1012 APCI1564_TCW_PROG); 1013 1014 /* Send a signal to from kernel to user space */ 1015 send_sig(SIGIO, devpriv->tsk_Current, 0); 1016 1017 /* Enable Counter Interrupt */ 1018 outl(ul_Command2, 1019 devpriv->iobase + APCI1564_COUNTER1 + 1020 APCI1564_TCW_PROG); 1021 } 1022 } /* if (ui_C1 == 1) */ 1023 1024 if (ui_C2 == 1) { 1025 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; 1026 if (devpriv->b_TimerSelectMode) { 1027 1028 /* Disable Counter Interrupt */ 1029 ul_Command2 = 1030 inl(devpriv->iobase + APCI1564_COUNTER2 + 1031 APCI1564_TCW_PROG); 1032 outl(0x0, 1033 devpriv->iobase + APCI1564_COUNTER2 + 1034 APCI1564_TCW_PROG); 1035 1036 /* Send a signal to from kernel to user space */ 1037 send_sig(SIGIO, devpriv->tsk_Current, 0); 1038 1039 /* Enable Counter Interrupt */ 1040 outl(ul_Command2, 1041 devpriv->iobase + APCI1564_COUNTER2 + 1042 APCI1564_TCW_PROG); 1043 } 1044 } /* if ((ui_C2 == 1) */ 1045 1046 if (ui_C3 == 1) { 1047 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; 1048 if (devpriv->b_TimerSelectMode) { 1049 1050 /* Disable Counter Interrupt */ 1051 ul_Command2 = 1052 inl(devpriv->iobase + APCI1564_COUNTER3 + 1053 APCI1564_TCW_PROG); 1054 outl(0x0, 1055 devpriv->iobase + APCI1564_COUNTER3 + 1056 APCI1564_TCW_PROG); 1057 1058 /* Send a signal to from kernel to user space */ 1059 send_sig(SIGIO, devpriv->tsk_Current, 0); 1060 1061 /* Enable Counter Interrupt */ 1062 outl(ul_Command2, 1063 devpriv->iobase + APCI1564_COUNTER3 + 1064 APCI1564_TCW_PROG); 1065 } 1066 } /* if ((ui_C3 == 1) */ 1067 1068 if (ui_C4 == 1) { 1069 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; 1070 if (devpriv->b_TimerSelectMode) { 1071 1072 /* Disable Counter Interrupt */ 1073 ul_Command2 = 1074 inl(devpriv->iobase + APCI1564_COUNTER4 + 1075 APCI1564_TCW_PROG); 1076 outl(0x0, 1077 devpriv->iobase + APCI1564_COUNTER4 + 1078 APCI1564_TCW_PROG); 1079 1080 /* Send a signal to from kernel to user space */ 1081 send_sig(SIGIO, devpriv->tsk_Current, 0); 1082 1083 /* Enable Counter Interrupt */ 1084 outl(ul_Command2, 1085 devpriv->iobase + APCI1564_COUNTER4 + 1086 APCI1564_TCW_PROG); 1087 } 1088 } /* if (ui_C4 == 1) */ 1089 return; 1090} 1091 1092/* 1093+----------------------------------------------------------------------------+ 1094| Function Name : int i_APCI1564_Reset(struct comedi_device *dev) | | 1095+----------------------------------------------------------------------------+ 1096| Task :resets all the registers | 1097+----------------------------------------------------------------------------+ 1098| Input Parameters : struct comedi_device *dev 1099+----------------------------------------------------------------------------+ 1100| Output Parameters : -- | 1101+----------------------------------------------------------------------------+ 1102| Return Value : | 1103| | 1104+----------------------------------------------------------------------------+ 1105*/ 1106 1107int i_APCI1564_Reset(struct comedi_device *dev) 1108{ 1109 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); /* disable the interrupts */ 1110 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ 1111 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ 1112 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2); 1113 devpriv->b_DigitalOutputRegister = 0; 1114 ui_Type = 0; 1115 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP); /* Resets the output channels */ 1116 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT); /* Disables the interrupt. */ 1117 outl(0x0, 1118 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + 1119 APCI1564_TCW_RELOAD_VALUE); 1120 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER); 1121 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); 1122 1123 outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG); 1124 outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG); 1125 outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG); 1126 outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG); 1127 return 0; 1128} 1129