hwdrv_apci3xxx.c revision c3744138715045adb316284ee7a1e608f0278f6c
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 Dieselstrasse 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-3XXX | Compiler : GCC | 32 | Module name : hwdrv_apci3xxx.c| Version : 2.96 | 33 +-------------------------------+---------------------------------------+ 34 | Project manager: S. Weber | Date : 15/09/2005 | 35 +-----------------------------------------------------------------------+ 36 | Description :APCI3XXX Module. Hardware abstraction Layer for APCI3XXX| 37 +-----------------------------------------------------------------------+ 38 | UPDATE'S | 39 +-----------------------------------------------------------------------+ 40 | Date | Author | Description of updates | 41 +----------+-----------+------------------------------------------------+ 42 | | | | 43 | | | | 44 +----------+-----------+------------------------------------------------+ 45*/ 46 47#include "hwdrv_apci3xxx.h" 48 49/* 50+----------------------------------------------------------------------------+ 51| ANALOG INPUT FUNCTIONS | 52+----------------------------------------------------------------------------+ 53*/ 54 55/* 56+----------------------------------------------------------------------------+ 57| Function Name : int i_APCI3XXX_TestConversionStarted | 58| (struct comedi_device *dev) | 59+----------------------------------------------------------------------------+ 60| Task Test if any conversion started | 61+----------------------------------------------------------------------------+ 62| Input Parameters : - | 63+----------------------------------------------------------------------------+ 64| Output Parameters : - | 65+----------------------------------------------------------------------------+ 66| Return Value : 0 : Conversion not started | 67| 1 : Conversion started | 68+----------------------------------------------------------------------------+ 69*/ 70 71int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) 72{ 73 if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) { 74 return (1); 75 } else { 76 return (0); 77 } 78} 79 80/* 81+----------------------------------------------------------------------------+ 82| Function Name : int i_APCI3XXX_AnalogInputConfigOperatingMode | 83| (struct comedi_device *dev, | 84| struct comedi_subdevice *s, | 85| struct comedi_insn *insn, | 86| unsigned int *data) | 87+----------------------------------------------------------------------------+ 88| Task Converting mode and convert time selection | 89+----------------------------------------------------------------------------+ 90| Input Parameters : b_SingleDiff = (unsigned char) data[1]; | 91| b_TimeBase = (unsigned char) data[2]; (0: ns, 1:micros 2:ms)| 92| dw_ReloadValue = (unsigned int) data[3]; | 93| ........ | 94+----------------------------------------------------------------------------+ 95| Output Parameters : - | 96+----------------------------------------------------------------------------+ 97| Return Value :>0 : No error | 98| -1 : Single/Diff selection error | 99| -2 : Convert time base unity selection error | 100| -3 : Convert time value selection error | 101| -10: Any conversion started | 102| .... | 103| -100 : Config command error | 104| -101 : Data size error | 105+----------------------------------------------------------------------------+ 106*/ 107 108int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, 109 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 110{ 111 int i_ReturnValue = insn->n; 112 unsigned char b_TimeBase = 0; 113 unsigned char b_SingleDiff = 0; 114 unsigned int dw_ReloadValue = 0; 115 unsigned int dw_TestReloadValue = 0; 116 117 /************************/ 118 /* Test the buffer size */ 119 /************************/ 120 121 if (insn->n == 4) { 122 /****************************/ 123 /* Get the Singel/Diff flag */ 124 /****************************/ 125 126 b_SingleDiff = (unsigned char) data[1]; 127 128 /****************************/ 129 /* Get the time base unitiy */ 130 /****************************/ 131 132 b_TimeBase = (unsigned char) data[2]; 133 134 /*************************************/ 135 /* Get the convert time reload value */ 136 /*************************************/ 137 138 dw_ReloadValue = (unsigned int) data[3]; 139 140 /**********************/ 141 /* Test the time base */ 142 /**********************/ 143 144 if ((devpriv->ps_BoardInfo-> 145 b_AvailableConvertUnit & (1 << b_TimeBase)) != 146 0) { 147 /*******************************/ 148 /* Test the convert time value */ 149 /*******************************/ 150 151 if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) { 152 dw_TestReloadValue = dw_ReloadValue; 153 154 if (b_TimeBase == 1) { 155 dw_TestReloadValue = 156 dw_TestReloadValue * 1000UL; 157 } 158 if (b_TimeBase == 2) { 159 dw_TestReloadValue = 160 dw_TestReloadValue * 1000000UL; 161 } 162 163 /*******************************/ 164 /* Test the convert time value */ 165 /*******************************/ 166 167 if (dw_TestReloadValue >= 168 devpriv->ps_BoardInfo-> 169 ui_MinAcquisitiontimeNs) { 170 if ((b_SingleDiff == APCI3XXX_SINGLE) 171 || (b_SingleDiff == 172 APCI3XXX_DIFF)) { 173 if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) { 174 /*******************************/ 175 /* Single/Diff selection error */ 176 /*******************************/ 177 178 printk("Single/Diff selection error\n"); 179 i_ReturnValue = -1; 180 } else { 181 /**********************************/ 182 /* Test if conversion not started */ 183 /**********************************/ 184 185 if (i_APCI3XXX_TestConversionStarted(dev) == 0) { 186 devpriv-> 187 ui_EocEosConversionTime 188 = 189 (unsigned int) 190 dw_ReloadValue; 191 devpriv-> 192 b_EocEosConversionTimeBase 193 = 194 b_TimeBase; 195 devpriv-> 196 b_SingelDiff 197 = 198 b_SingleDiff; 199 devpriv-> 200 b_AiInitialisation 201 = 1; 202 203 /*******************************/ 204 /* Set the convert timing unit */ 205 /*******************************/ 206 207 writel((unsigned int) 208 b_TimeBase, 209 (void *) 210 (devpriv-> 211 dw_AiBase 212 + 213 36)); 214 215 /**************************/ 216 /* Set the convert timing */ 217 /*************************/ 218 219 writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32)); 220 } else { 221 /**************************/ 222 /* Any conversion started */ 223 /**************************/ 224 225 printk("Any conversion started\n"); 226 i_ReturnValue = 227 -10; 228 } 229 } 230 } else { 231 /*******************************/ 232 /* Single/Diff selection error */ 233 /*******************************/ 234 235 printk("Single/Diff selection error\n"); 236 i_ReturnValue = -1; 237 } 238 } else { 239 /************************/ 240 /* Time selection error */ 241 /************************/ 242 243 printk("Convert time value selection error\n"); 244 i_ReturnValue = -3; 245 } 246 } else { 247 /************************/ 248 /* Time selection error */ 249 /************************/ 250 251 printk("Convert time value selection error\n"); 252 i_ReturnValue = -3; 253 } 254 } else { 255 /*****************************/ 256 /* Time base selection error */ 257 /*****************************/ 258 259 printk("Convert time base unity selection error\n"); 260 i_ReturnValue = -2; 261 } 262 } else { 263 /*******************/ 264 /* Data size error */ 265 /*******************/ 266 267 printk("Buffer size error\n"); 268 i_ReturnValue = -101; 269 } 270 271 return (i_ReturnValue); 272} 273 274/* 275+----------------------------------------------------------------------------+ 276| Function Name : int i_APCI3XXX_InsnConfigAnalogInput | 277| (struct comedi_device *dev, | 278| struct comedi_subdevice *s, | 279| struct comedi_insn *insn, | 280| unsigned int *data) | 281+----------------------------------------------------------------------------+ 282| Task Converting mode and convert time selection | 283+----------------------------------------------------------------------------+ 284| Input Parameters : b_ConvertMode = (unsigned char) data[0]; | 285| b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)| 286| dw_ReloadValue = (unsigned int) data[2]; | 287| ........ | 288+----------------------------------------------------------------------------+ 289| Output Parameters : - | 290+----------------------------------------------------------------------------+ 291| Return Value :>0: No error | 292| .... | 293| -100 : Config command error | 294| -101 : Data size error | 295+----------------------------------------------------------------------------+ 296*/ 297 298int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev, 299 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 300{ 301 int i_ReturnValue = insn->n; 302 303 /************************/ 304 /* Test the buffer size */ 305 /************************/ 306 307 if (insn->n >= 1) { 308 switch ((unsigned char) data[0]) { 309 case APCI3XXX_CONFIGURATION: 310 i_ReturnValue = 311 i_APCI3XXX_AnalogInputConfigOperatingMode(dev, 312 s, insn, data); 313 break; 314 315 default: 316 i_ReturnValue = -100; 317 printk("Config command error %d\n", data[0]); 318 break; 319 } 320 } else { 321 /*******************/ 322 /* Data size error */ 323 /*******************/ 324 325 printk("Buffer size error\n"); 326 i_ReturnValue = -101; 327 } 328 329 return (i_ReturnValue); 330} 331 332/* 333+----------------------------------------------------------------------------+ 334| Function Name : int i_APCI3XXX_InsnReadAnalogInput | 335| (struct comedi_device *dev, | 336| struct comedi_subdevice *s, | 337| struct comedi_insn *insn, | 338| unsigned int *data) | 339+----------------------------------------------------------------------------+ 340| Task Read 1 analog input | 341+----------------------------------------------------------------------------+ 342| Input Parameters : b_Range = CR_RANGE(insn->chanspec); | 343| b_Channel = CR_CHAN(insn->chanspec); | 344| dw_NbrOfAcquisition = insn->n; | 345+----------------------------------------------------------------------------+ 346| Output Parameters : - | 347+----------------------------------------------------------------------------+ 348| Return Value :>0: No error | 349| -3 : Channel selection error | 350| -4 : Configuration selelection error | 351| -10: Any conversion started | 352| .... | 353| -100 : Config command error | 354| -101 : Data size error | 355+----------------------------------------------------------------------------+ 356*/ 357 358int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, 359 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 360{ 361 int i_ReturnValue = insn->n; 362 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec); 363 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 364 unsigned int dw_Temp = 0; 365 unsigned int dw_Configuration = 0; 366 unsigned int dw_AcquisitionCpt = 0; 367 unsigned char b_Interrupt = 0; 368 369 /*************************************/ 370 /* Test if operating mode configured */ 371 /*************************************/ 372 373 if (devpriv->b_AiInitialisation) { 374 /***************************/ 375 /* Test the channel number */ 376 /***************************/ 377 378 if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel) 379 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE)) 380 || ((b_Channel < devpriv->ps_BoardInfo-> 381 i_NbrAiChannelDiff) 382 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) { 383 /**********************************/ 384 /* Test the channel configuration */ 385 /**********************************/ 386 387 if (b_Configuration > 7) { 388 /***************************/ 389 /* Channel not initialised */ 390 /***************************/ 391 392 i_ReturnValue = -4; 393 printk("Channel %d range %d selection error\n", 394 b_Channel, b_Configuration); 395 } 396 } else { 397 /***************************/ 398 /* Channel selection error */ 399 /***************************/ 400 401 i_ReturnValue = -3; 402 printk("Channel %d selection error\n", b_Channel); 403 } 404 405 /**************************/ 406 /* Test if no error occur */ 407 /**************************/ 408 409 if (i_ReturnValue >= 0) { 410 /************************/ 411 /* Test the buffer size */ 412 /************************/ 413 414 if ((b_Interrupt != 0) || ((b_Interrupt == 0) 415 && (insn->n >= 1))) { 416 /**********************************/ 417 /* Test if conversion not started */ 418 /**********************************/ 419 420 if (i_APCI3XXX_TestConversionStarted(dev) == 0) { 421 /******************/ 422 /* Clear the FIFO */ 423 /******************/ 424 425 writel(0x10000UL, 426 (void *)(devpriv->dw_AiBase + 427 12)); 428 429 /*******************************/ 430 /* Get and save the delay mode */ 431 /*******************************/ 432 433 dw_Temp = 434 readl((void *)(devpriv-> 435 dw_AiBase + 4)); 436 dw_Temp = dw_Temp & 0xFFFFFEF0UL; 437 438 /***********************************/ 439 /* Channel configuration selection */ 440 /***********************************/ 441 442 writel(dw_Temp, 443 (void *)(devpriv->dw_AiBase + 444 4)); 445 446 /**************************/ 447 /* Make the configuration */ 448 /**************************/ 449 450 dw_Configuration = 451 (b_Configuration & 3) | 452 ((unsigned int) (b_Configuration >> 2) 453 << 6) | ((unsigned int) devpriv-> 454 b_SingelDiff << 7); 455 456 /***************************/ 457 /* Write the configuration */ 458 /***************************/ 459 460 writel(dw_Configuration, 461 (void *)(devpriv->dw_AiBase + 462 0)); 463 464 /*********************/ 465 /* Channel selection */ 466 /*********************/ 467 468 writel(dw_Temp | 0x100UL, 469 (void *)(devpriv->dw_AiBase + 470 4)); 471 writel((unsigned int) b_Channel, 472 (void *)(devpriv->dw_AiBase + 473 0)); 474 475 /***********************/ 476 /* Restaure delay mode */ 477 /***********************/ 478 479 writel(dw_Temp, 480 (void *)(devpriv->dw_AiBase + 481 4)); 482 483 /***********************************/ 484 /* Set the number of sequence to 1 */ 485 /***********************************/ 486 487 writel(1, 488 (void *)(devpriv->dw_AiBase + 489 48)); 490 491 /***************************/ 492 /* Save the interrupt flag */ 493 /***************************/ 494 495 devpriv->b_EocEosInterrupt = 496 b_Interrupt; 497 498 /*******************************/ 499 /* Save the number of channels */ 500 /*******************************/ 501 502 devpriv->ui_AiNbrofChannels = 1; 503 504 /******************************/ 505 /* Test if interrupt not used */ 506 /******************************/ 507 508 if (b_Interrupt == 0) { 509 for (dw_AcquisitionCpt = 0; 510 dw_AcquisitionCpt < 511 insn->n; 512 dw_AcquisitionCpt++) { 513 /************************/ 514 /* Start the conversion */ 515 /************************/ 516 517 writel(0x80000UL, 518 (void *) 519 (devpriv-> 520 dw_AiBase 521 + 8)); 522 523 /****************/ 524 /* Wait the EOS */ 525 /****************/ 526 527 do { 528 dw_Temp = 529 readl( 530 (void *) 531 (devpriv-> 532 dw_AiBase 533 + 534 20)); 535 dw_Temp = 536 dw_Temp 537 & 1; 538 } 539 while (dw_Temp != 1); 540 541 /*************************/ 542 /* Read the analog value */ 543 /*************************/ 544 545 data[dw_AcquisitionCpt] 546 = 547 (unsigned int) 548 readl((void 549 *) 550 (devpriv-> 551 dw_AiBase 552 + 28)); 553 } 554 } else { 555 /************************/ 556 /* Start the conversion */ 557 /************************/ 558 559 writel(0x180000UL, 560 (void *)(devpriv-> 561 dw_AiBase + 8)); 562 } 563 } else { 564 /**************************/ 565 /* Any conversion started */ 566 /**************************/ 567 568 printk("Any conversion started\n"); 569 i_ReturnValue = -10; 570 } 571 } else { 572 /*******************/ 573 /* Data size error */ 574 /*******************/ 575 576 printk("Buffer size error\n"); 577 i_ReturnValue = -101; 578 } 579 } 580 } else { 581 /***************************/ 582 /* Channel selection error */ 583 /***************************/ 584 585 printk("Operating mode not configured\n"); 586 i_ReturnValue = -1; 587 } 588 return (i_ReturnValue); 589} 590 591/* 592+----------------------------------------------------------------------------+ 593| Function name : void v_APCI3XXX_Interrupt (int irq, | 594| void *d) | 595+----------------------------------------------------------------------------+ 596| Task :Interrupt handler for APCI3XXX | 597| When interrupt occurs this gets called. | 598| First it finds which interrupt has been generated and | 599| handles corresponding interrupt | 600+----------------------------------------------------------------------------+ 601| Input Parameters : - | 602+----------------------------------------------------------------------------+ 603| Return Value : - | 604+----------------------------------------------------------------------------+ 605*/ 606 607void v_APCI3XXX_Interrupt(int irq, void *d) 608{ 609 struct comedi_device *dev = d; 610 unsigned char b_CopyCpt = 0; 611 unsigned int dw_Status = 0; 612 613 /***************************/ 614 /* Test if interrupt occur */ 615 /***************************/ 616 617 dw_Status = readl((void *)(devpriv->dw_AiBase + 16)); 618 if ( (dw_Status & 0x2UL) == 0x2UL) { 619 /***********************/ 620 /* Reset the interrupt */ 621 /***********************/ 622 623 writel(dw_Status, (void *)(devpriv->dw_AiBase + 16)); 624 625 /*****************************/ 626 /* Test if interrupt enabled */ 627 /*****************************/ 628 629 if (devpriv->b_EocEosInterrupt == 1) { 630 /********************************/ 631 /* Read all analog inputs value */ 632 /********************************/ 633 634 for (b_CopyCpt = 0; 635 b_CopyCpt < devpriv->ui_AiNbrofChannels; 636 b_CopyCpt++) { 637 devpriv->ui_AiReadData[b_CopyCpt] = 638 (unsigned int) readl((void *)(devpriv-> 639 dw_AiBase + 28)); 640 } 641 642 /**************************/ 643 /* Set the interrupt flag */ 644 /**************************/ 645 646 devpriv->b_EocEosInterrupt = 2; 647 648 /**********************************************/ 649 /* Send a signal to from kernel to user space */ 650 /**********************************************/ 651 652 send_sig(SIGIO, devpriv->tsk_Current, 0); 653 } 654 } 655} 656 657/* 658+----------------------------------------------------------------------------+ 659| ANALOG OUTPUT SUBDEVICE | 660+----------------------------------------------------------------------------+ 661*/ 662 663/* 664+----------------------------------------------------------------------------+ 665| Function Name : int i_APCI3XXX_InsnWriteAnalogOutput | 666| (struct comedi_device *dev, | 667| struct comedi_subdevice *s, | 668| struct comedi_insn *insn, | 669| unsigned int *data) | 670+----------------------------------------------------------------------------+ 671| Task Read 1 analog input | 672+----------------------------------------------------------------------------+ 673| Input Parameters : b_Range = CR_RANGE(insn->chanspec); | 674| b_Channel = CR_CHAN(insn->chanspec); | 675| data[0] = analog value; | 676+----------------------------------------------------------------------------+ 677| Output Parameters : - | 678+----------------------------------------------------------------------------+ 679| Return Value :>0: No error | 680| -3 : Channel selection error | 681| -4 : Configuration selelection error | 682| .... | 683| -101 : Data size error | 684+----------------------------------------------------------------------------+ 685*/ 686 687int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, 688 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 689{ 690 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec); 691 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 692 unsigned int dw_Status = 0; 693 int i_ReturnValue = insn->n; 694 695 /************************/ 696 /* Test the buffer size */ 697 /************************/ 698 699 if (insn->n >= 1) { 700 /***************************/ 701 /* Test the channel number */ 702 /***************************/ 703 704 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) { 705 /**********************************/ 706 /* Test the channel configuration */ 707 /**********************************/ 708 709 if (b_Range < 2) { 710 /***************************/ 711 /* Set the range selection */ 712 /***************************/ 713 714 writel(b_Range, 715 (void *)(devpriv->dw_AiBase + 96)); 716 717 /**************************************************/ 718 /* Write the analog value to the selected channel */ 719 /**************************************************/ 720 721 writel((data[0] << 8) | b_Channel, 722 (void *)(devpriv->dw_AiBase + 100)); 723 724 /****************************/ 725 /* Wait the end of transfer */ 726 /****************************/ 727 728 do { 729 dw_Status = 730 readl((void *)(devpriv-> 731 dw_AiBase + 96)); 732 } 733 while ((dw_Status & 0x100) != 0x100); 734 } else { 735 /***************************/ 736 /* Channel not initialised */ 737 /***************************/ 738 739 i_ReturnValue = -4; 740 printk("Channel %d range %d selection error\n", 741 b_Channel, b_Range); 742 } 743 } else { 744 /***************************/ 745 /* Channel selection error */ 746 /***************************/ 747 748 i_ReturnValue = -3; 749 printk("Channel %d selection error\n", b_Channel); 750 } 751 } else { 752 /*******************/ 753 /* Data size error */ 754 /*******************/ 755 756 printk("Buffer size error\n"); 757 i_ReturnValue = -101; 758 } 759 760 return (i_ReturnValue); 761} 762 763/* 764+----------------------------------------------------------------------------+ 765| TTL FUNCTIONS | 766+----------------------------------------------------------------------------+ 767*/ 768 769/* 770+----------------------------------------------------------------------------+ 771| Function Name : int i_APCI3XXX_InsnConfigInitTTLIO | 772| (struct comedi_device *dev, | 773| struct comedi_subdevice *s, | 774| struct comedi_insn *insn, | 775| unsigned int *data) | 776+----------------------------------------------------------------------------+ 777| Task You must calling this function be | 778| for you call any other function witch access of TTL. | 779| APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)| 780+----------------------------------------------------------------------------+ 781| Input Parameters : b_InitType = (unsigned char) data[0]; | 782| b_Port2Mode = (unsigned char) data[1]; | 783+----------------------------------------------------------------------------+ 784| Output Parameters : - | 785+----------------------------------------------------------------------------+ 786| Return Value :>0: No error | 787| -1: Port 2 mode selection is wrong | 788| .... | 789| -100 : Config command error | 790| -101 : Data size error | 791+----------------------------------------------------------------------------+ 792*/ 793 794int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, 795 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 796{ 797 int i_ReturnValue = insn->n; 798 unsigned char b_Command = 0; 799 800 /************************/ 801 /* Test the buffer size */ 802 /************************/ 803 804 if (insn->n >= 1) { 805 /*******************/ 806 /* Get the command */ 807 /* **************** */ 808 809 b_Command = (unsigned char) data[0]; 810 811 /********************/ 812 /* Test the command */ 813 /********************/ 814 815 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) { 816 /***************************************/ 817 /* Test the initialisation buffer size */ 818 /***************************************/ 819 820 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) 821 && (insn->n != 2)) { 822 /*******************/ 823 /* Data size error */ 824 /*******************/ 825 826 printk("Buffer size error\n"); 827 i_ReturnValue = -101; 828 } 829 } else { 830 /************************/ 831 /* Config command error */ 832 /************************/ 833 834 printk("Command selection error\n"); 835 i_ReturnValue = -100; 836 } 837 } else { 838 /*******************/ 839 /* Data size error */ 840 /*******************/ 841 842 printk("Buffer size error\n"); 843 i_ReturnValue = -101; 844 } 845 846 /*********************************************************************************/ 847 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */ 848 /*********************************************************************************/ 849 850 if ((i_ReturnValue >= 0) 851 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) { 852 /**********************/ 853 /* Test the direction */ 854 /**********************/ 855 856 if ((data[1] == 0) || (data[1] == 0xFF)) { 857 /**************************/ 858 /* Save the configuration */ 859 /**************************/ 860 861 devpriv->ul_TTLPortConfiguration[0] = 862 devpriv->ul_TTLPortConfiguration[0] | data[1]; 863 } else { 864 /************************/ 865 /* Port direction error */ 866 /************************/ 867 868 printk("Port 2 direction selection error\n"); 869 i_ReturnValue = -1; 870 } 871 } 872 873 /**************************/ 874 /* Test if no error occur */ 875 /**************************/ 876 877 if (i_ReturnValue >= 0) { 878 /***********************************/ 879 /* Test if TTL port initilaisation */ 880 /***********************************/ 881 882 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) { 883 /*************************/ 884 /* Set the configuration */ 885 /*************************/ 886 887 outl(data[1], devpriv->iobase + 224); 888 } 889 } 890 891 return (i_ReturnValue); 892} 893 894/* 895+----------------------------------------------------------------------------+ 896| TTL INPUT FUNCTIONS | 897+----------------------------------------------------------------------------+ 898*/ 899 900/* 901+----------------------------------------------------------------------------+ 902| Function Name : int i_APCI3XXX_InsnBitsTTLIO | 903| (struct comedi_device *dev, | 904| struct comedi_subdevice *s, | 905| struct comedi_insn *insn, | 906| unsigned int *data) | 907+----------------------------------------------------------------------------+ 908| Task : Write the selected output mask and read the status from| 909| all TTL channles | 910+----------------------------------------------------------------------------+ 911| Input Parameters : dw_ChannelMask = data [0]; | 912| dw_BitMask = data [1]; | 913+----------------------------------------------------------------------------+ 914| Output Parameters : data[1] : All TTL channles states | 915+----------------------------------------------------------------------------+ 916| Return Value : >0 : No error | 917| -4 : Channel mask error | 918| -101 : Data size error | 919+----------------------------------------------------------------------------+ 920*/ 921 922int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, 923 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 924{ 925 int i_ReturnValue = insn->n; 926 unsigned char b_ChannelCpt = 0; 927 unsigned int dw_ChannelMask = 0; 928 unsigned int dw_BitMask = 0; 929 unsigned int dw_Status = 0; 930 931 /************************/ 932 /* Test the buffer size */ 933 /************************/ 934 935 if (insn->n >= 2) { 936 /*******************************/ 937 /* Get the channe and bit mask */ 938 /*******************************/ 939 940 dw_ChannelMask = data[0]; 941 dw_BitMask = data[1]; 942 943 /*************************/ 944 /* Test the channel mask */ 945 /*************************/ 946 947 if (((dw_ChannelMask & 0XFF00FF00) == 0) && 948 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF) 949 || (((devpriv->ul_TTLPortConfiguration[0] & 950 0xFF) == 0) 951 && ((dw_ChannelMask & 0XFF0000) == 952 0)))) { 953 /*********************************/ 954 /* Test if set/reset any channel */ 955 /*********************************/ 956 957 if (dw_ChannelMask) { 958 /****************************************/ 959 /* Test if set/rest any port 0 channels */ 960 /****************************************/ 961 962 if (dw_ChannelMask & 0xFF) { 963 /*******************************************/ 964 /* Read port 0 (first digital output port) */ 965 /*******************************************/ 966 967 dw_Status = inl(devpriv->iobase + 80); 968 969 for (b_ChannelCpt = 0; b_ChannelCpt < 8; 970 b_ChannelCpt++) { 971 if ((dw_ChannelMask >> 972 b_ChannelCpt) & 973 1) { 974 dw_Status = 975 (dw_Status & 976 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 977 } 978 } 979 980 outl(dw_Status, devpriv->iobase + 80); 981 } 982 983 /****************************************/ 984 /* Test if set/rest any port 2 channels */ 985 /****************************************/ 986 987 if (dw_ChannelMask & 0xFF0000) { 988 dw_BitMask = dw_BitMask >> 16; 989 dw_ChannelMask = dw_ChannelMask >> 16; 990 991 /********************************************/ 992 /* Read port 2 (second digital output port) */ 993 /********************************************/ 994 995 dw_Status = inl(devpriv->iobase + 112); 996 997 for (b_ChannelCpt = 0; b_ChannelCpt < 8; 998 b_ChannelCpt++) { 999 if ((dw_ChannelMask >> 1000 b_ChannelCpt) & 1001 1) { 1002 dw_Status = 1003 (dw_Status & 1004 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 1005 } 1006 } 1007 1008 outl(dw_Status, devpriv->iobase + 112); 1009 } 1010 } 1011 1012 /*******************************************/ 1013 /* Read port 0 (first digital output port) */ 1014 /*******************************************/ 1015 1016 data[1] = inl(devpriv->iobase + 80); 1017 1018 /******************************************/ 1019 /* Read port 1 (first digital input port) */ 1020 /******************************************/ 1021 1022 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8); 1023 1024 /************************/ 1025 /* Test if port 2 input */ 1026 /************************/ 1027 1028 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) { 1029 data[1] = 1030 data[1] | (inl(devpriv->iobase + 1031 96) << 16); 1032 } else { 1033 data[1] = 1034 data[1] | (inl(devpriv->iobase + 1035 112) << 16); 1036 } 1037 } else { 1038 /************************/ 1039 /* Config command error */ 1040 /************************/ 1041 1042 printk("Channel mask error\n"); 1043 i_ReturnValue = -4; 1044 } 1045 } else { 1046 /*******************/ 1047 /* Data size error */ 1048 /*******************/ 1049 1050 printk("Buffer size error\n"); 1051 i_ReturnValue = -101; 1052 } 1053 1054 return (i_ReturnValue); 1055} 1056 1057/* 1058+----------------------------------------------------------------------------+ 1059| Function Name : int i_APCI3XXX_InsnReadTTLIO | 1060| (struct comedi_device *dev, | 1061| struct comedi_subdevice *s, | 1062| struct comedi_insn *insn, | 1063| unsigned int *data) | 1064+----------------------------------------------------------------------------+ 1065| Task : Read the status from selected channel | 1066+----------------------------------------------------------------------------+ 1067| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1068+----------------------------------------------------------------------------+ 1069| Output Parameters : data[0] : Selected TTL channel state | 1070+----------------------------------------------------------------------------+ 1071| Return Value : 0 : No error | 1072| -3 : Channel selection error | 1073| -101 : Data size error | 1074+----------------------------------------------------------------------------+ 1075*/ 1076 1077int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, 1078 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1079{ 1080 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1081 int i_ReturnValue = insn->n; 1082 unsigned int *pls_ReadData = data; 1083 1084 /************************/ 1085 /* Test the buffer size */ 1086 /************************/ 1087 1088 if (insn->n >= 1) { 1089 /***********************/ 1090 /* Test if read port 0 */ 1091 /***********************/ 1092 1093 if (b_Channel < 8) { 1094 /*******************************************/ 1095 /* Read port 0 (first digital output port) */ 1096 /*******************************************/ 1097 1098 pls_ReadData[0] = inl(devpriv->iobase + 80); 1099 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1; 1100 } else { 1101 /***********************/ 1102 /* Test if read port 1 */ 1103 /***********************/ 1104 1105 if ((b_Channel > 7) && (b_Channel < 16)) { 1106 /******************************************/ 1107 /* Read port 1 (first digital input port) */ 1108 /******************************************/ 1109 1110 pls_ReadData[0] = inl(devpriv->iobase + 64); 1111 pls_ReadData[0] = 1112 (pls_ReadData[0] >> (b_Channel - 1113 8)) & 1; 1114 } else { 1115 /***********************/ 1116 /* Test if read port 2 */ 1117 /***********************/ 1118 1119 if ((b_Channel > 15) && (b_Channel < 24)) { 1120 /************************/ 1121 /* Test if port 2 input */ 1122 /************************/ 1123 1124 if ((devpriv->ul_TTLPortConfiguration[0] 1125 & 0xFF) == 0) { 1126 pls_ReadData[0] = 1127 inl(devpriv->iobase + 1128 96); 1129 pls_ReadData[0] = 1130 (pls_ReadData[0] >> 1131 (b_Channel - 16)) & 1; 1132 } else { 1133 pls_ReadData[0] = 1134 inl(devpriv->iobase + 1135 112); 1136 pls_ReadData[0] = 1137 (pls_ReadData[0] >> 1138 (b_Channel - 16)) & 1; 1139 } 1140 } else { 1141 /***************************/ 1142 /* Channel selection error */ 1143 /***************************/ 1144 1145 i_ReturnValue = -3; 1146 printk("Channel %d selection error\n", 1147 b_Channel); 1148 } 1149 } 1150 } 1151 } else { 1152 /*******************/ 1153 /* Data size error */ 1154 /*******************/ 1155 1156 printk("Buffer size error\n"); 1157 i_ReturnValue = -101; 1158 } 1159 1160 return (i_ReturnValue); 1161} 1162 1163/* 1164+----------------------------------------------------------------------------+ 1165| TTL OUTPUT FUNCTIONS | 1166+----------------------------------------------------------------------------+ 1167*/ 1168 1169/* 1170+----------------------------------------------------------------------------+ 1171| Function Name : int i_APCI3XXX_InsnWriteTTLIO | 1172| (struct comedi_device *dev, | 1173| struct comedi_subdevice *s, | 1174| struct comedi_insn *insn, | 1175| unsigned int *data) | 1176+----------------------------------------------------------------------------+ 1177| Task : Set the state from TTL output channel | 1178+----------------------------------------------------------------------------+ 1179| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1180| b_State = data [0] | 1181+----------------------------------------------------------------------------+ 1182| Output Parameters : - | 1183+----------------------------------------------------------------------------+ 1184| Return Value : 0 : No error | 1185| -3 : Channel selection error | 1186| -101 : Data size error | 1187+----------------------------------------------------------------------------+ 1188*/ 1189 1190int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, 1191 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1192{ 1193 int i_ReturnValue = insn->n; 1194 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1195 unsigned char b_State = 0; 1196 unsigned int dw_Status = 0; 1197 1198 /************************/ 1199 /* Test the buffer size */ 1200 /************************/ 1201 1202 if (insn->n >= 1) { 1203 b_State = (unsigned char) data[0]; 1204 1205 /***********************/ 1206 /* Test if read port 0 */ 1207 /***********************/ 1208 1209 if (b_Channel < 8) { 1210 /*****************************************************************************/ 1211 /* Read port 0 (first digital output port) and set/reset the selcted channel */ 1212 /*****************************************************************************/ 1213 1214 dw_Status = inl(devpriv->iobase + 80); 1215 dw_Status = 1216 (dw_Status & (0xFF - 1217 (1 << b_Channel))) | ((b_State & 1) << 1218 b_Channel); 1219 outl(dw_Status, devpriv->iobase + 80); 1220 } else { 1221 /***********************/ 1222 /* Test if read port 2 */ 1223 /***********************/ 1224 1225 if ((b_Channel > 15) && (b_Channel < 24)) { 1226 /*************************/ 1227 /* Test if port 2 output */ 1228 /*************************/ 1229 1230 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) 1231 == 0xFF) { 1232 /*****************************************************************************/ 1233 /* Read port 2 (first digital output port) and set/reset the selcted channel */ 1234 /*****************************************************************************/ 1235 1236 dw_Status = inl(devpriv->iobase + 112); 1237 dw_Status = 1238 (dw_Status & (0xFF - 1239 (1 << (b_Channel - 1240 16)))) | 1241 ((b_State & 1) << (b_Channel - 1242 16)); 1243 outl(dw_Status, devpriv->iobase + 112); 1244 } else { 1245 /***************************/ 1246 /* Channel selection error */ 1247 /***************************/ 1248 1249 i_ReturnValue = -3; 1250 printk("Channel %d selection error\n", 1251 b_Channel); 1252 } 1253 } else { 1254 /***************************/ 1255 /* Channel selection error */ 1256 /***************************/ 1257 1258 i_ReturnValue = -3; 1259 printk("Channel %d selection error\n", 1260 b_Channel); 1261 } 1262 } 1263 } else { 1264 /*******************/ 1265 /* Data size error */ 1266 /*******************/ 1267 1268 printk("Buffer size error\n"); 1269 i_ReturnValue = -101; 1270 } 1271 1272 return (i_ReturnValue); 1273} 1274 1275/* 1276+----------------------------------------------------------------------------+ 1277| DIGITAL INPUT SUBDEVICE | 1278+----------------------------------------------------------------------------+ 1279*/ 1280 1281/* 1282+----------------------------------------------------------------------------+ 1283| Function name :int i_APCI3XXX_InsnReadDigitalInput | 1284| (struct comedi_device *dev, | 1285| struct comedi_subdevice *s, | 1286| struct comedi_insn *insn, | 1287| unsigned int *data) | 1288+----------------------------------------------------------------------------+ 1289| Task : Reads the value of the specified Digital input channel | 1290+----------------------------------------------------------------------------+ 1291| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) | 1292+----------------------------------------------------------------------------+ 1293| Output Parameters : data[0] : Channel value | 1294+----------------------------------------------------------------------------+ 1295| Return Value : 0 : No error | 1296| -3 : Channel selection error | 1297| -101 : Data size error | 1298+----------------------------------------------------------------------------+ 1299*/ 1300 1301int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, 1302 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1303{ 1304 int i_ReturnValue = insn->n; 1305 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1306 unsigned int dw_Temp = 0; 1307 1308 /***************************/ 1309 /* Test the channel number */ 1310 /***************************/ 1311 1312 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) { 1313 /************************/ 1314 /* Test the buffer size */ 1315 /************************/ 1316 1317 if (insn->n >= 1) { 1318 dw_Temp = inl(devpriv->iobase + 32); 1319 *data = (dw_Temp >> b_Channel) & 1; 1320 } else { 1321 /*******************/ 1322 /* Data size error */ 1323 /*******************/ 1324 1325 printk("Buffer size error\n"); 1326 i_ReturnValue = -101; 1327 } 1328 } else { 1329 /***************************/ 1330 /* Channel selection error */ 1331 /***************************/ 1332 1333 printk("Channel selection error\n"); 1334 i_ReturnValue = -3; 1335 } 1336 1337 return (i_ReturnValue); 1338} 1339 1340/* 1341+----------------------------------------------------------------------------+ 1342| Function name :int i_APCI3XXX_InsnBitsDigitalInput | 1343| (struct comedi_device *dev, | 1344| struct comedi_subdevice *s, | 1345| struct comedi_insn *insn, | 1346| unsigned int *data) | 1347+----------------------------------------------------------------------------+ 1348| Task : Reads the value of the Digital input Port i.e.4channels| 1349+----------------------------------------------------------------------------+ 1350| Input Parameters : - | 1351+----------------------------------------------------------------------------+ 1352| Output Parameters : data[0] : Port value | 1353+----------------------------------------------------------------------------+ 1354| Return Value :>0: No error | 1355| .... | 1356| -101 : Data size error | 1357+----------------------------------------------------------------------------+ 1358*/ 1359int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, 1360 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1361{ 1362 int i_ReturnValue = insn->n; 1363 unsigned int dw_Temp = 0; 1364 1365 /************************/ 1366 /* Test the buffer size */ 1367 /************************/ 1368 1369 if (insn->n >= 1) { 1370 dw_Temp = inl(devpriv->iobase + 32); 1371 *data = dw_Temp & 0xf; 1372 } else { 1373 /*******************/ 1374 /* Data size error */ 1375 /*******************/ 1376 1377 printk("Buffer size error\n"); 1378 i_ReturnValue = -101; 1379 } 1380 1381 return (i_ReturnValue); 1382} 1383 1384/* 1385+----------------------------------------------------------------------------+ 1386| DIGITAL OUTPUT SUBDEVICE | 1387+----------------------------------------------------------------------------+ 1388 1389*/ 1390 1391/* 1392+----------------------------------------------------------------------------+ 1393| Function name :int i_APCI3XXX_InsnBitsDigitalOutput | 1394| (struct comedi_device *dev, | 1395| struct comedi_subdevice *s, | 1396| struct comedi_insn *insn, | 1397| unsigned int *data) | 1398+----------------------------------------------------------------------------+ 1399| Task : Write the selected output mask and read the status from| 1400| all digital output channles | 1401+----------------------------------------------------------------------------+ 1402| Input Parameters : dw_ChannelMask = data [0]; | 1403| dw_BitMask = data [1]; | 1404+----------------------------------------------------------------------------+ 1405| Output Parameters : data[1] : All digital output channles states | 1406+----------------------------------------------------------------------------+ 1407| Return Value : >0 : No error | 1408| -4 : Channel mask error | 1409| -101 : Data size error | 1410+----------------------------------------------------------------------------+ 1411*/ 1412int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, 1413 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1414{ 1415 int i_ReturnValue = insn->n; 1416 unsigned char b_ChannelCpt = 0; 1417 unsigned int dw_ChannelMask = 0; 1418 unsigned int dw_BitMask = 0; 1419 unsigned int dw_Status = 0; 1420 1421 /************************/ 1422 /* Test the buffer size */ 1423 /************************/ 1424 1425 if (insn->n >= 2) { 1426 /*******************************/ 1427 /* Get the channe and bit mask */ 1428 /*******************************/ 1429 1430 dw_ChannelMask = data[0]; 1431 dw_BitMask = data[1]; 1432 1433 /*************************/ 1434 /* Test the channel mask */ 1435 /*************************/ 1436 1437 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) { 1438 /*********************************/ 1439 /* Test if set/reset any channel */ 1440 /*********************************/ 1441 1442 if (dw_ChannelMask & 0xF) { 1443 /********************************/ 1444 /* Read the digital output port */ 1445 /********************************/ 1446 1447 dw_Status = inl(devpriv->iobase + 48); 1448 1449 for (b_ChannelCpt = 0; b_ChannelCpt < 4; 1450 b_ChannelCpt++) { 1451 if ((dw_ChannelMask >> b_ChannelCpt) & 1452 1) { 1453 dw_Status = 1454 (dw_Status & (0xF - 1455 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 1456 } 1457 } 1458 1459 outl(dw_Status, devpriv->iobase + 48); 1460 } 1461 1462 /********************************/ 1463 /* Read the digital output port */ 1464 /********************************/ 1465 1466 data[1] = inl(devpriv->iobase + 48); 1467 } else { 1468 /************************/ 1469 /* Config command error */ 1470 /************************/ 1471 1472 printk("Channel mask error\n"); 1473 i_ReturnValue = -4; 1474 } 1475 } else { 1476 /*******************/ 1477 /* Data size error */ 1478 /*******************/ 1479 1480 printk("Buffer size error\n"); 1481 i_ReturnValue = -101; 1482 } 1483 1484 return (i_ReturnValue); 1485} 1486 1487/* 1488+----------------------------------------------------------------------------+ 1489| Function name :int i_APCI3XXX_InsnWriteDigitalOutput | 1490| (struct comedi_device *dev, | 1491| struct comedi_subdevice *s, | 1492| struct comedi_insn *insn, | 1493| unsigned int *data) | 1494+----------------------------------------------------------------------------+ 1495| Task : Set the state from digital output channel | 1496+----------------------------------------------------------------------------+ 1497| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1498| b_State = data [0] | 1499+----------------------------------------------------------------------------+ 1500| Output Parameters : - | 1501+----------------------------------------------------------------------------+ 1502| Return Value : >0 : No error | 1503| -3 : Channel selection error | 1504| -101 : Data size error | 1505+----------------------------------------------------------------------------+ 1506*/ 1507 1508int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, 1509 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1510{ 1511 int i_ReturnValue = insn->n; 1512 unsigned char b_Channel = CR_CHAN(insn->chanspec); 1513 unsigned char b_State = 0; 1514 unsigned int dw_Status = 0; 1515 1516 /************************/ 1517 /* Test the buffer size */ 1518 /************************/ 1519 1520 if (insn->n >= 1) { 1521 /***************************/ 1522 /* Test the channel number */ 1523 /***************************/ 1524 1525 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) { 1526 /*******************/ 1527 /* Get the command */ 1528 /*******************/ 1529 1530 b_State = (unsigned char) data[0]; 1531 1532 /********************************/ 1533 /* Read the digital output port */ 1534 /********************************/ 1535 1536 dw_Status = inl(devpriv->iobase + 48); 1537 1538 dw_Status = 1539 (dw_Status & (0xF - 1540 (1 << b_Channel))) | ((b_State & 1) << 1541 b_Channel); 1542 outl(dw_Status, devpriv->iobase + 48); 1543 } else { 1544 /***************************/ 1545 /* Channel selection error */ 1546 /***************************/ 1547 1548 printk("Channel selection error\n"); 1549 i_ReturnValue = -3; 1550 } 1551 } else { 1552 /*******************/ 1553 /* Data size error */ 1554 /*******************/ 1555 1556 printk("Buffer size error\n"); 1557 i_ReturnValue = -101; 1558 } 1559 1560 return (i_ReturnValue); 1561} 1562 1563/* 1564+----------------------------------------------------------------------------+ 1565| Function name :int i_APCI3XXX_InsnReadDigitalOutput | 1566| (struct comedi_device *dev, | 1567| struct comedi_subdevice *s, | 1568| struct comedi_insn *insn, | 1569| unsigned int *data) | 1570+----------------------------------------------------------------------------+ 1571| Task : Read the state from digital output channel | 1572+----------------------------------------------------------------------------+ 1573| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1574+----------------------------------------------------------------------------+ 1575| Output Parameters : b_State = data [0] | 1576+----------------------------------------------------------------------------+ 1577| Return Value : >0 : No error | 1578| -3 : Channel selection error | 1579| -101 : Data size error | 1580+----------------------------------------------------------------------------+ 1581*/ 1582 1583int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, 1584 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1585{ 1586 int i_ReturnValue = insn->n; 1587 unsigned char b_Channel = CR_CHAN(insn->chanspec); 1588 unsigned int dw_Status = 0; 1589 1590 /************************/ 1591 /* Test the buffer size */ 1592 /************************/ 1593 1594 if (insn->n >= 1) { 1595 /***************************/ 1596 /* Test the channel number */ 1597 /***************************/ 1598 1599 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) { 1600 /********************************/ 1601 /* Read the digital output port */ 1602 /********************************/ 1603 1604 dw_Status = inl(devpriv->iobase + 48); 1605 1606 dw_Status = (dw_Status >> b_Channel) & 1; 1607 *data = dw_Status; 1608 } else { 1609 /***************************/ 1610 /* Channel selection error */ 1611 /***************************/ 1612 1613 printk("Channel selection error\n"); 1614 i_ReturnValue = -3; 1615 } 1616 } else { 1617 /*******************/ 1618 /* Data size error */ 1619 /*******************/ 1620 1621 printk("Buffer size error\n"); 1622 i_ReturnValue = -101; 1623 } 1624 1625 return (i_ReturnValue); 1626} 1627 1628/* 1629+----------------------------------------------------------------------------+ 1630| Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+ 1631| Task :resets all the registers | 1632+----------------------------------------------------------------------------+ 1633| Input Parameters : struct comedi_device *dev | 1634+----------------------------------------------------------------------------+ 1635| Output Parameters : - | 1636+----------------------------------------------------------------------------+ 1637| Return Value : - | 1638+----------------------------------------------------------------------------+ 1639*/ 1640 1641int i_APCI3XXX_Reset(struct comedi_device *dev) 1642{ 1643 unsigned char b_Cpt = 0; 1644 1645 /*************************/ 1646 /* Disable the interrupt */ 1647 /*************************/ 1648 1649 disable_irq(dev->irq); 1650 1651 /****************************/ 1652 /* Reset the interrupt flag */ 1653 /****************************/ 1654 1655 devpriv->b_EocEosInterrupt = 0; 1656 1657 /***************************/ 1658 /* Clear the start command */ 1659 /***************************/ 1660 1661 writel(0, (void *)(devpriv->dw_AiBase + 8)); 1662 1663 /*****************************/ 1664 /* Reset the interrupt flags */ 1665 /*****************************/ 1666 1667 writel(readl((void *)(devpriv->dw_AiBase + 16)), 1668 (void *)(devpriv->dw_AiBase + 16)); 1669 1670 /*****************/ 1671 /* clear the EOS */ 1672 /*****************/ 1673 1674 readl((void *)(devpriv->dw_AiBase + 20)); 1675 1676 /******************/ 1677 /* Clear the FIFO */ 1678 /******************/ 1679 1680 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) { 1681 readl((void *)(devpriv->dw_AiBase + 28)); 1682 } 1683 1684 /************************/ 1685 /* Enable the interrupt */ 1686 /************************/ 1687 1688 enable_irq(dev->irq); 1689 1690 return 0; 1691} 1692