hwdrv_apci3xxx.c revision dc8af06898c4326cee1739e2bc100bed2b601721
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 <= 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 } while (dw_Temp != 1); 539 540 /*************************/ 541 /* Read the analog value */ 542 /*************************/ 543 544 data[dw_AcquisitionCpt] 545 = 546 (unsigned int) 547 readl((void 548 *) 549 (devpriv-> 550 dw_AiBase 551 + 28)); 552 } 553 } else { 554 /************************/ 555 /* Start the conversion */ 556 /************************/ 557 558 writel(0x180000UL, 559 (void *)(devpriv-> 560 dw_AiBase + 8)); 561 } 562 } else { 563 /**************************/ 564 /* Any conversion started */ 565 /**************************/ 566 567 printk("Any conversion started\n"); 568 i_ReturnValue = -10; 569 } 570 } else { 571 /*******************/ 572 /* Data size error */ 573 /*******************/ 574 575 printk("Buffer size error\n"); 576 i_ReturnValue = -101; 577 } 578 } 579 } else { 580 /***************************/ 581 /* Channel selection error */ 582 /***************************/ 583 584 printk("Operating mode not configured\n"); 585 i_ReturnValue = -1; 586 } 587 return i_ReturnValue; 588} 589 590/* 591+----------------------------------------------------------------------------+ 592| Function name : void v_APCI3XXX_Interrupt (int irq, | 593| void *d) | 594+----------------------------------------------------------------------------+ 595| Task :Interrupt handler for APCI3XXX | 596| When interrupt occurs this gets called. | 597| First it finds which interrupt has been generated and | 598| handles corresponding interrupt | 599+----------------------------------------------------------------------------+ 600| Input Parameters : - | 601+----------------------------------------------------------------------------+ 602| Return Value : - | 603+----------------------------------------------------------------------------+ 604*/ 605 606void v_APCI3XXX_Interrupt(int irq, void *d) 607{ 608 struct comedi_device *dev = d; 609 unsigned char b_CopyCpt = 0; 610 unsigned int dw_Status = 0; 611 612 /***************************/ 613 /* Test if interrupt occur */ 614 /***************************/ 615 616 dw_Status = readl((void *)(devpriv->dw_AiBase + 16)); 617 if ( (dw_Status & 0x2UL) == 0x2UL) { 618 /***********************/ 619 /* Reset the interrupt */ 620 /***********************/ 621 622 writel(dw_Status, (void *)(devpriv->dw_AiBase + 16)); 623 624 /*****************************/ 625 /* Test if interrupt enabled */ 626 /*****************************/ 627 628 if (devpriv->b_EocEosInterrupt == 1) { 629 /********************************/ 630 /* Read all analog inputs value */ 631 /********************************/ 632 633 for (b_CopyCpt = 0; 634 b_CopyCpt < devpriv->ui_AiNbrofChannels; 635 b_CopyCpt++) { 636 devpriv->ui_AiReadData[b_CopyCpt] = 637 (unsigned int) readl((void *)(devpriv-> 638 dw_AiBase + 28)); 639 } 640 641 /**************************/ 642 /* Set the interrupt flag */ 643 /**************************/ 644 645 devpriv->b_EocEosInterrupt = 2; 646 647 /**********************************************/ 648 /* Send a signal to from kernel to user space */ 649 /**********************************************/ 650 651 send_sig(SIGIO, devpriv->tsk_Current, 0); 652 } 653 } 654} 655 656/* 657+----------------------------------------------------------------------------+ 658| ANALOG OUTPUT SUBDEVICE | 659+----------------------------------------------------------------------------+ 660*/ 661 662/* 663+----------------------------------------------------------------------------+ 664| Function Name : int i_APCI3XXX_InsnWriteAnalogOutput | 665| (struct comedi_device *dev, | 666| struct comedi_subdevice *s, | 667| struct comedi_insn *insn, | 668| unsigned int *data) | 669+----------------------------------------------------------------------------+ 670| Task Read 1 analog input | 671+----------------------------------------------------------------------------+ 672| Input Parameters : b_Range = CR_RANGE(insn->chanspec); | 673| b_Channel = CR_CHAN(insn->chanspec); | 674| data[0] = analog value; | 675+----------------------------------------------------------------------------+ 676| Output Parameters : - | 677+----------------------------------------------------------------------------+ 678| Return Value :>0: No error | 679| -3 : Channel selection error | 680| -4 : Configuration selelection error | 681| .... | 682| -101 : Data size error | 683+----------------------------------------------------------------------------+ 684*/ 685 686int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, 687 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 688{ 689 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec); 690 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 691 unsigned int dw_Status = 0; 692 int i_ReturnValue = insn->n; 693 694 /************************/ 695 /* Test the buffer size */ 696 /************************/ 697 698 if (insn->n >= 1) { 699 /***************************/ 700 /* Test the channel number */ 701 /***************************/ 702 703 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) { 704 /**********************************/ 705 /* Test the channel configuration */ 706 /**********************************/ 707 708 if (b_Range < 2) { 709 /***************************/ 710 /* Set the range selection */ 711 /***************************/ 712 713 writel(b_Range, 714 (void *)(devpriv->dw_AiBase + 96)); 715 716 /**************************************************/ 717 /* Write the analog value to the selected channel */ 718 /**************************************************/ 719 720 writel((data[0] << 8) | b_Channel, 721 (void *)(devpriv->dw_AiBase + 100)); 722 723 /****************************/ 724 /* Wait the end of transfer */ 725 /****************************/ 726 727 do { 728 dw_Status = 729 readl((void *)(devpriv-> 730 dw_AiBase + 96)); 731 } while ((dw_Status & 0x100) != 0x100); 732 } else { 733 /***************************/ 734 /* Channel not initialised */ 735 /***************************/ 736 737 i_ReturnValue = -4; 738 printk("Channel %d range %d selection error\n", 739 b_Channel, b_Range); 740 } 741 } else { 742 /***************************/ 743 /* Channel selection error */ 744 /***************************/ 745 746 i_ReturnValue = -3; 747 printk("Channel %d selection error\n", b_Channel); 748 } 749 } else { 750 /*******************/ 751 /* Data size error */ 752 /*******************/ 753 754 printk("Buffer size error\n"); 755 i_ReturnValue = -101; 756 } 757 758 return i_ReturnValue; 759} 760 761/* 762+----------------------------------------------------------------------------+ 763| TTL FUNCTIONS | 764+----------------------------------------------------------------------------+ 765*/ 766 767/* 768+----------------------------------------------------------------------------+ 769| Function Name : int i_APCI3XXX_InsnConfigInitTTLIO | 770| (struct comedi_device *dev, | 771| struct comedi_subdevice *s, | 772| struct comedi_insn *insn, | 773| unsigned int *data) | 774+----------------------------------------------------------------------------+ 775| Task You must calling this function be | 776| for you call any other function witch access of TTL. | 777| APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)| 778+----------------------------------------------------------------------------+ 779| Input Parameters : b_InitType = (unsigned char) data[0]; | 780| b_Port2Mode = (unsigned char) data[1]; | 781+----------------------------------------------------------------------------+ 782| Output Parameters : - | 783+----------------------------------------------------------------------------+ 784| Return Value :>0: No error | 785| -1: Port 2 mode selection is wrong | 786| .... | 787| -100 : Config command error | 788| -101 : Data size error | 789+----------------------------------------------------------------------------+ 790*/ 791 792int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, 793 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 794{ 795 int i_ReturnValue = insn->n; 796 unsigned char b_Command = 0; 797 798 /************************/ 799 /* Test the buffer size */ 800 /************************/ 801 802 if (insn->n >= 1) { 803 /*******************/ 804 /* Get the command */ 805 /* **************** */ 806 807 b_Command = (unsigned char) data[0]; 808 809 /********************/ 810 /* Test the command */ 811 /********************/ 812 813 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) { 814 /***************************************/ 815 /* Test the initialisation buffer size */ 816 /***************************************/ 817 818 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) 819 && (insn->n != 2)) { 820 /*******************/ 821 /* Data size error */ 822 /*******************/ 823 824 printk("Buffer size error\n"); 825 i_ReturnValue = -101; 826 } 827 } else { 828 /************************/ 829 /* Config command error */ 830 /************************/ 831 832 printk("Command selection error\n"); 833 i_ReturnValue = -100; 834 } 835 } else { 836 /*******************/ 837 /* Data size error */ 838 /*******************/ 839 840 printk("Buffer size error\n"); 841 i_ReturnValue = -101; 842 } 843 844 /*********************************************************************************/ 845 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */ 846 /*********************************************************************************/ 847 848 if ((i_ReturnValue >= 0) 849 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) { 850 /**********************/ 851 /* Test the direction */ 852 /**********************/ 853 854 if ((data[1] == 0) || (data[1] == 0xFF)) { 855 /**************************/ 856 /* Save the configuration */ 857 /**************************/ 858 859 devpriv->ul_TTLPortConfiguration[0] = 860 devpriv->ul_TTLPortConfiguration[0] | data[1]; 861 } else { 862 /************************/ 863 /* Port direction error */ 864 /************************/ 865 866 printk("Port 2 direction selection error\n"); 867 i_ReturnValue = -1; 868 } 869 } 870 871 /**************************/ 872 /* Test if no error occur */ 873 /**************************/ 874 875 if (i_ReturnValue >= 0) { 876 /***********************************/ 877 /* Test if TTL port initilaisation */ 878 /***********************************/ 879 880 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) { 881 /*************************/ 882 /* Set the configuration */ 883 /*************************/ 884 885 outl(data[1], devpriv->iobase + 224); 886 } 887 } 888 889 return i_ReturnValue; 890} 891 892/* 893+----------------------------------------------------------------------------+ 894| TTL INPUT FUNCTIONS | 895+----------------------------------------------------------------------------+ 896*/ 897 898/* 899+----------------------------------------------------------------------------+ 900| Function Name : int i_APCI3XXX_InsnBitsTTLIO | 901| (struct comedi_device *dev, | 902| struct comedi_subdevice *s, | 903| struct comedi_insn *insn, | 904| unsigned int *data) | 905+----------------------------------------------------------------------------+ 906| Task : Write the selected output mask and read the status from| 907| all TTL channles | 908+----------------------------------------------------------------------------+ 909| Input Parameters : dw_ChannelMask = data [0]; | 910| dw_BitMask = data [1]; | 911+----------------------------------------------------------------------------+ 912| Output Parameters : data[1] : All TTL channles states | 913+----------------------------------------------------------------------------+ 914| Return Value : >0 : No error | 915| -4 : Channel mask error | 916| -101 : Data size error | 917+----------------------------------------------------------------------------+ 918*/ 919 920int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, 921 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 922{ 923 int i_ReturnValue = insn->n; 924 unsigned char b_ChannelCpt = 0; 925 unsigned int dw_ChannelMask = 0; 926 unsigned int dw_BitMask = 0; 927 unsigned int dw_Status = 0; 928 929 /************************/ 930 /* Test the buffer size */ 931 /************************/ 932 933 if (insn->n >= 2) { 934 /*******************************/ 935 /* Get the channe and bit mask */ 936 /*******************************/ 937 938 dw_ChannelMask = data[0]; 939 dw_BitMask = data[1]; 940 941 /*************************/ 942 /* Test the channel mask */ 943 /*************************/ 944 945 if (((dw_ChannelMask & 0XFF00FF00) == 0) && 946 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF) 947 || (((devpriv->ul_TTLPortConfiguration[0] & 948 0xFF) == 0) 949 && ((dw_ChannelMask & 0XFF0000) == 950 0)))) { 951 /*********************************/ 952 /* Test if set/reset any channel */ 953 /*********************************/ 954 955 if (dw_ChannelMask) { 956 /****************************************/ 957 /* Test if set/rest any port 0 channels */ 958 /****************************************/ 959 960 if (dw_ChannelMask & 0xFF) { 961 /*******************************************/ 962 /* Read port 0 (first digital output port) */ 963 /*******************************************/ 964 965 dw_Status = inl(devpriv->iobase + 80); 966 967 for (b_ChannelCpt = 0; b_ChannelCpt < 8; 968 b_ChannelCpt++) { 969 if ((dw_ChannelMask >> 970 b_ChannelCpt) & 971 1) { 972 dw_Status = 973 (dw_Status & 974 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 975 } 976 } 977 978 outl(dw_Status, devpriv->iobase + 80); 979 } 980 981 /****************************************/ 982 /* Test if set/rest any port 2 channels */ 983 /****************************************/ 984 985 if (dw_ChannelMask & 0xFF0000) { 986 dw_BitMask = dw_BitMask >> 16; 987 dw_ChannelMask = dw_ChannelMask >> 16; 988 989 /********************************************/ 990 /* Read port 2 (second digital output port) */ 991 /********************************************/ 992 993 dw_Status = inl(devpriv->iobase + 112); 994 995 for (b_ChannelCpt = 0; b_ChannelCpt < 8; 996 b_ChannelCpt++) { 997 if ((dw_ChannelMask >> 998 b_ChannelCpt) & 999 1) { 1000 dw_Status = 1001 (dw_Status & 1002 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 1003 } 1004 } 1005 1006 outl(dw_Status, devpriv->iobase + 112); 1007 } 1008 } 1009 1010 /*******************************************/ 1011 /* Read port 0 (first digital output port) */ 1012 /*******************************************/ 1013 1014 data[1] = inl(devpriv->iobase + 80); 1015 1016 /******************************************/ 1017 /* Read port 1 (first digital input port) */ 1018 /******************************************/ 1019 1020 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8); 1021 1022 /************************/ 1023 /* Test if port 2 input */ 1024 /************************/ 1025 1026 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) { 1027 data[1] = 1028 data[1] | (inl(devpriv->iobase + 1029 96) << 16); 1030 } else { 1031 data[1] = 1032 data[1] | (inl(devpriv->iobase + 1033 112) << 16); 1034 } 1035 } else { 1036 /************************/ 1037 /* Config command error */ 1038 /************************/ 1039 1040 printk("Channel mask error\n"); 1041 i_ReturnValue = -4; 1042 } 1043 } else { 1044 /*******************/ 1045 /* Data size error */ 1046 /*******************/ 1047 1048 printk("Buffer size error\n"); 1049 i_ReturnValue = -101; 1050 } 1051 1052 return i_ReturnValue; 1053} 1054 1055/* 1056+----------------------------------------------------------------------------+ 1057| Function Name : int i_APCI3XXX_InsnReadTTLIO | 1058| (struct comedi_device *dev, | 1059| struct comedi_subdevice *s, | 1060| struct comedi_insn *insn, | 1061| unsigned int *data) | 1062+----------------------------------------------------------------------------+ 1063| Task : Read the status from selected channel | 1064+----------------------------------------------------------------------------+ 1065| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1066+----------------------------------------------------------------------------+ 1067| Output Parameters : data[0] : Selected TTL channel state | 1068+----------------------------------------------------------------------------+ 1069| Return Value : 0 : No error | 1070| -3 : Channel selection error | 1071| -101 : Data size error | 1072+----------------------------------------------------------------------------+ 1073*/ 1074 1075int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, 1076 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1077{ 1078 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1079 int i_ReturnValue = insn->n; 1080 unsigned int *pls_ReadData = data; 1081 1082 /************************/ 1083 /* Test the buffer size */ 1084 /************************/ 1085 1086 if (insn->n >= 1) { 1087 /***********************/ 1088 /* Test if read port 0 */ 1089 /***********************/ 1090 1091 if (b_Channel < 8) { 1092 /*******************************************/ 1093 /* Read port 0 (first digital output port) */ 1094 /*******************************************/ 1095 1096 pls_ReadData[0] = inl(devpriv->iobase + 80); 1097 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1; 1098 } else { 1099 /***********************/ 1100 /* Test if read port 1 */ 1101 /***********************/ 1102 1103 if ((b_Channel > 7) && (b_Channel < 16)) { 1104 /******************************************/ 1105 /* Read port 1 (first digital input port) */ 1106 /******************************************/ 1107 1108 pls_ReadData[0] = inl(devpriv->iobase + 64); 1109 pls_ReadData[0] = 1110 (pls_ReadData[0] >> (b_Channel - 1111 8)) & 1; 1112 } else { 1113 /***********************/ 1114 /* Test if read port 2 */ 1115 /***********************/ 1116 1117 if ((b_Channel > 15) && (b_Channel < 24)) { 1118 /************************/ 1119 /* Test if port 2 input */ 1120 /************************/ 1121 1122 if ((devpriv->ul_TTLPortConfiguration[0] 1123 & 0xFF) == 0) { 1124 pls_ReadData[0] = 1125 inl(devpriv->iobase + 1126 96); 1127 pls_ReadData[0] = 1128 (pls_ReadData[0] >> 1129 (b_Channel - 16)) & 1; 1130 } else { 1131 pls_ReadData[0] = 1132 inl(devpriv->iobase + 1133 112); 1134 pls_ReadData[0] = 1135 (pls_ReadData[0] >> 1136 (b_Channel - 16)) & 1; 1137 } 1138 } else { 1139 /***************************/ 1140 /* Channel selection error */ 1141 /***************************/ 1142 1143 i_ReturnValue = -3; 1144 printk("Channel %d selection error\n", 1145 b_Channel); 1146 } 1147 } 1148 } 1149 } else { 1150 /*******************/ 1151 /* Data size error */ 1152 /*******************/ 1153 1154 printk("Buffer size error\n"); 1155 i_ReturnValue = -101; 1156 } 1157 1158 return i_ReturnValue; 1159} 1160 1161/* 1162+----------------------------------------------------------------------------+ 1163| TTL OUTPUT FUNCTIONS | 1164+----------------------------------------------------------------------------+ 1165*/ 1166 1167/* 1168+----------------------------------------------------------------------------+ 1169| Function Name : int i_APCI3XXX_InsnWriteTTLIO | 1170| (struct comedi_device *dev, | 1171| struct comedi_subdevice *s, | 1172| struct comedi_insn *insn, | 1173| unsigned int *data) | 1174+----------------------------------------------------------------------------+ 1175| Task : Set the state from TTL output channel | 1176+----------------------------------------------------------------------------+ 1177| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1178| b_State = data [0] | 1179+----------------------------------------------------------------------------+ 1180| Output Parameters : - | 1181+----------------------------------------------------------------------------+ 1182| Return Value : 0 : No error | 1183| -3 : Channel selection error | 1184| -101 : Data size error | 1185+----------------------------------------------------------------------------+ 1186*/ 1187 1188int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, 1189 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1190{ 1191 int i_ReturnValue = insn->n; 1192 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1193 unsigned char b_State = 0; 1194 unsigned int dw_Status = 0; 1195 1196 /************************/ 1197 /* Test the buffer size */ 1198 /************************/ 1199 1200 if (insn->n >= 1) { 1201 b_State = (unsigned char) data[0]; 1202 1203 /***********************/ 1204 /* Test if read port 0 */ 1205 /***********************/ 1206 1207 if (b_Channel < 8) { 1208 /*****************************************************************************/ 1209 /* Read port 0 (first digital output port) and set/reset the selcted channel */ 1210 /*****************************************************************************/ 1211 1212 dw_Status = inl(devpriv->iobase + 80); 1213 dw_Status = 1214 (dw_Status & (0xFF - 1215 (1 << b_Channel))) | ((b_State & 1) << 1216 b_Channel); 1217 outl(dw_Status, devpriv->iobase + 80); 1218 } else { 1219 /***********************/ 1220 /* Test if read port 2 */ 1221 /***********************/ 1222 1223 if ((b_Channel > 15) && (b_Channel < 24)) { 1224 /*************************/ 1225 /* Test if port 2 output */ 1226 /*************************/ 1227 1228 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) 1229 == 0xFF) { 1230 /*****************************************************************************/ 1231 /* Read port 2 (first digital output port) and set/reset the selcted channel */ 1232 /*****************************************************************************/ 1233 1234 dw_Status = inl(devpriv->iobase + 112); 1235 dw_Status = 1236 (dw_Status & (0xFF - 1237 (1 << (b_Channel - 1238 16)))) | 1239 ((b_State & 1) << (b_Channel - 1240 16)); 1241 outl(dw_Status, devpriv->iobase + 112); 1242 } else { 1243 /***************************/ 1244 /* Channel selection error */ 1245 /***************************/ 1246 1247 i_ReturnValue = -3; 1248 printk("Channel %d selection error\n", 1249 b_Channel); 1250 } 1251 } else { 1252 /***************************/ 1253 /* Channel selection error */ 1254 /***************************/ 1255 1256 i_ReturnValue = -3; 1257 printk("Channel %d selection error\n", 1258 b_Channel); 1259 } 1260 } 1261 } else { 1262 /*******************/ 1263 /* Data size error */ 1264 /*******************/ 1265 1266 printk("Buffer size error\n"); 1267 i_ReturnValue = -101; 1268 } 1269 1270 return i_ReturnValue; 1271} 1272 1273/* 1274+----------------------------------------------------------------------------+ 1275| DIGITAL INPUT SUBDEVICE | 1276+----------------------------------------------------------------------------+ 1277*/ 1278 1279/* 1280+----------------------------------------------------------------------------+ 1281| Function name :int i_APCI3XXX_InsnReadDigitalInput | 1282| (struct comedi_device *dev, | 1283| struct comedi_subdevice *s, | 1284| struct comedi_insn *insn, | 1285| unsigned int *data) | 1286+----------------------------------------------------------------------------+ 1287| Task : Reads the value of the specified Digital input channel | 1288+----------------------------------------------------------------------------+ 1289| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) | 1290+----------------------------------------------------------------------------+ 1291| Output Parameters : data[0] : Channel value | 1292+----------------------------------------------------------------------------+ 1293| Return Value : 0 : No error | 1294| -3 : Channel selection error | 1295| -101 : Data size error | 1296+----------------------------------------------------------------------------+ 1297*/ 1298 1299int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, 1300 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1301{ 1302 int i_ReturnValue = insn->n; 1303 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); 1304 unsigned int dw_Temp = 0; 1305 1306 /***************************/ 1307 /* Test the channel number */ 1308 /***************************/ 1309 1310 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) { 1311 /************************/ 1312 /* Test the buffer size */ 1313 /************************/ 1314 1315 if (insn->n >= 1) { 1316 dw_Temp = inl(devpriv->iobase + 32); 1317 *data = (dw_Temp >> b_Channel) & 1; 1318 } else { 1319 /*******************/ 1320 /* Data size error */ 1321 /*******************/ 1322 1323 printk("Buffer size error\n"); 1324 i_ReturnValue = -101; 1325 } 1326 } else { 1327 /***************************/ 1328 /* Channel selection error */ 1329 /***************************/ 1330 1331 printk("Channel selection error\n"); 1332 i_ReturnValue = -3; 1333 } 1334 1335 return i_ReturnValue; 1336} 1337 1338/* 1339+----------------------------------------------------------------------------+ 1340| Function name :int i_APCI3XXX_InsnBitsDigitalInput | 1341| (struct comedi_device *dev, | 1342| struct comedi_subdevice *s, | 1343| struct comedi_insn *insn, | 1344| unsigned int *data) | 1345+----------------------------------------------------------------------------+ 1346| Task : Reads the value of the Digital input Port i.e.4channels| 1347+----------------------------------------------------------------------------+ 1348| Input Parameters : - | 1349+----------------------------------------------------------------------------+ 1350| Output Parameters : data[0] : Port value | 1351+----------------------------------------------------------------------------+ 1352| Return Value :>0: No error | 1353| .... | 1354| -101 : Data size error | 1355+----------------------------------------------------------------------------+ 1356*/ 1357int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, 1358 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1359{ 1360 int i_ReturnValue = insn->n; 1361 unsigned int dw_Temp = 0; 1362 1363 /************************/ 1364 /* Test the buffer size */ 1365 /************************/ 1366 1367 if (insn->n >= 1) { 1368 dw_Temp = inl(devpriv->iobase + 32); 1369 *data = dw_Temp & 0xf; 1370 } else { 1371 /*******************/ 1372 /* Data size error */ 1373 /*******************/ 1374 1375 printk("Buffer size error\n"); 1376 i_ReturnValue = -101; 1377 } 1378 1379 return i_ReturnValue; 1380} 1381 1382/* 1383+----------------------------------------------------------------------------+ 1384| DIGITAL OUTPUT SUBDEVICE | 1385+----------------------------------------------------------------------------+ 1386 1387*/ 1388 1389/* 1390+----------------------------------------------------------------------------+ 1391| Function name :int i_APCI3XXX_InsnBitsDigitalOutput | 1392| (struct comedi_device *dev, | 1393| struct comedi_subdevice *s, | 1394| struct comedi_insn *insn, | 1395| unsigned int *data) | 1396+----------------------------------------------------------------------------+ 1397| Task : Write the selected output mask and read the status from| 1398| all digital output channles | 1399+----------------------------------------------------------------------------+ 1400| Input Parameters : dw_ChannelMask = data [0]; | 1401| dw_BitMask = data [1]; | 1402+----------------------------------------------------------------------------+ 1403| Output Parameters : data[1] : All digital output channles states | 1404+----------------------------------------------------------------------------+ 1405| Return Value : >0 : No error | 1406| -4 : Channel mask error | 1407| -101 : Data size error | 1408+----------------------------------------------------------------------------+ 1409*/ 1410int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, 1411 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1412{ 1413 int i_ReturnValue = insn->n; 1414 unsigned char b_ChannelCpt = 0; 1415 unsigned int dw_ChannelMask = 0; 1416 unsigned int dw_BitMask = 0; 1417 unsigned int dw_Status = 0; 1418 1419 /************************/ 1420 /* Test the buffer size */ 1421 /************************/ 1422 1423 if (insn->n >= 2) { 1424 /*******************************/ 1425 /* Get the channe and bit mask */ 1426 /*******************************/ 1427 1428 dw_ChannelMask = data[0]; 1429 dw_BitMask = data[1]; 1430 1431 /*************************/ 1432 /* Test the channel mask */ 1433 /*************************/ 1434 1435 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) { 1436 /*********************************/ 1437 /* Test if set/reset any channel */ 1438 /*********************************/ 1439 1440 if (dw_ChannelMask & 0xF) { 1441 /********************************/ 1442 /* Read the digital output port */ 1443 /********************************/ 1444 1445 dw_Status = inl(devpriv->iobase + 48); 1446 1447 for (b_ChannelCpt = 0; b_ChannelCpt < 4; 1448 b_ChannelCpt++) { 1449 if ((dw_ChannelMask >> b_ChannelCpt) & 1450 1) { 1451 dw_Status = 1452 (dw_Status & (0xF - 1453 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); 1454 } 1455 } 1456 1457 outl(dw_Status, devpriv->iobase + 48); 1458 } 1459 1460 /********************************/ 1461 /* Read the digital output port */ 1462 /********************************/ 1463 1464 data[1] = inl(devpriv->iobase + 48); 1465 } else { 1466 /************************/ 1467 /* Config command error */ 1468 /************************/ 1469 1470 printk("Channel mask error\n"); 1471 i_ReturnValue = -4; 1472 } 1473 } else { 1474 /*******************/ 1475 /* Data size error */ 1476 /*******************/ 1477 1478 printk("Buffer size error\n"); 1479 i_ReturnValue = -101; 1480 } 1481 1482 return i_ReturnValue; 1483} 1484 1485/* 1486+----------------------------------------------------------------------------+ 1487| Function name :int i_APCI3XXX_InsnWriteDigitalOutput | 1488| (struct comedi_device *dev, | 1489| struct comedi_subdevice *s, | 1490| struct comedi_insn *insn, | 1491| unsigned int *data) | 1492+----------------------------------------------------------------------------+ 1493| Task : Set the state from digital output channel | 1494+----------------------------------------------------------------------------+ 1495| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1496| b_State = data [0] | 1497+----------------------------------------------------------------------------+ 1498| Output Parameters : - | 1499+----------------------------------------------------------------------------+ 1500| Return Value : >0 : No error | 1501| -3 : Channel selection error | 1502| -101 : Data size error | 1503+----------------------------------------------------------------------------+ 1504*/ 1505 1506int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, 1507 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1508{ 1509 int i_ReturnValue = insn->n; 1510 unsigned char b_Channel = CR_CHAN(insn->chanspec); 1511 unsigned char b_State = 0; 1512 unsigned int dw_Status = 0; 1513 1514 /************************/ 1515 /* Test the buffer size */ 1516 /************************/ 1517 1518 if (insn->n >= 1) { 1519 /***************************/ 1520 /* Test the channel number */ 1521 /***************************/ 1522 1523 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) { 1524 /*******************/ 1525 /* Get the command */ 1526 /*******************/ 1527 1528 b_State = (unsigned char) data[0]; 1529 1530 /********************************/ 1531 /* Read the digital output port */ 1532 /********************************/ 1533 1534 dw_Status = inl(devpriv->iobase + 48); 1535 1536 dw_Status = 1537 (dw_Status & (0xF - 1538 (1 << b_Channel))) | ((b_State & 1) << 1539 b_Channel); 1540 outl(dw_Status, devpriv->iobase + 48); 1541 } else { 1542 /***************************/ 1543 /* Channel selection error */ 1544 /***************************/ 1545 1546 printk("Channel selection error\n"); 1547 i_ReturnValue = -3; 1548 } 1549 } else { 1550 /*******************/ 1551 /* Data size error */ 1552 /*******************/ 1553 1554 printk("Buffer size error\n"); 1555 i_ReturnValue = -101; 1556 } 1557 1558 return i_ReturnValue; 1559} 1560 1561/* 1562+----------------------------------------------------------------------------+ 1563| Function name :int i_APCI3XXX_InsnReadDigitalOutput | 1564| (struct comedi_device *dev, | 1565| struct comedi_subdevice *s, | 1566| struct comedi_insn *insn, | 1567| unsigned int *data) | 1568+----------------------------------------------------------------------------+ 1569| Task : Read the state from digital output channel | 1570+----------------------------------------------------------------------------+ 1571| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | 1572+----------------------------------------------------------------------------+ 1573| Output Parameters : b_State = data [0] | 1574+----------------------------------------------------------------------------+ 1575| Return Value : >0 : No error | 1576| -3 : Channel selection error | 1577| -101 : Data size error | 1578+----------------------------------------------------------------------------+ 1579*/ 1580 1581int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, 1582 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1583{ 1584 int i_ReturnValue = insn->n; 1585 unsigned char b_Channel = CR_CHAN(insn->chanspec); 1586 unsigned int dw_Status = 0; 1587 1588 /************************/ 1589 /* Test the buffer size */ 1590 /************************/ 1591 1592 if (insn->n >= 1) { 1593 /***************************/ 1594 /* Test the channel number */ 1595 /***************************/ 1596 1597 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) { 1598 /********************************/ 1599 /* Read the digital output port */ 1600 /********************************/ 1601 1602 dw_Status = inl(devpriv->iobase + 48); 1603 1604 dw_Status = (dw_Status >> b_Channel) & 1; 1605 *data = dw_Status; 1606 } else { 1607 /***************************/ 1608 /* Channel selection error */ 1609 /***************************/ 1610 1611 printk("Channel selection error\n"); 1612 i_ReturnValue = -3; 1613 } 1614 } else { 1615 /*******************/ 1616 /* Data size error */ 1617 /*******************/ 1618 1619 printk("Buffer size error\n"); 1620 i_ReturnValue = -101; 1621 } 1622 1623 return i_ReturnValue; 1624} 1625 1626/* 1627+----------------------------------------------------------------------------+ 1628| Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+ 1629| Task :resets all the registers | 1630+----------------------------------------------------------------------------+ 1631| Input Parameters : struct comedi_device *dev | 1632+----------------------------------------------------------------------------+ 1633| Output Parameters : - | 1634+----------------------------------------------------------------------------+ 1635| Return Value : - | 1636+----------------------------------------------------------------------------+ 1637*/ 1638 1639int i_APCI3XXX_Reset(struct comedi_device *dev) 1640{ 1641 unsigned char b_Cpt = 0; 1642 1643 /*************************/ 1644 /* Disable the interrupt */ 1645 /*************************/ 1646 1647 disable_irq(dev->irq); 1648 1649 /****************************/ 1650 /* Reset the interrupt flag */ 1651 /****************************/ 1652 1653 devpriv->b_EocEosInterrupt = 0; 1654 1655 /***************************/ 1656 /* Clear the start command */ 1657 /***************************/ 1658 1659 writel(0, (void *)(devpriv->dw_AiBase + 8)); 1660 1661 /*****************************/ 1662 /* Reset the interrupt flags */ 1663 /*****************************/ 1664 1665 writel(readl((void *)(devpriv->dw_AiBase + 16)), 1666 (void *)(devpriv->dw_AiBase + 16)); 1667 1668 /*****************/ 1669 /* clear the EOS */ 1670 /*****************/ 1671 1672 readl((void *)(devpriv->dw_AiBase + 20)); 1673 1674 /******************/ 1675 /* Clear the FIFO */ 1676 /******************/ 1677 1678 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) { 1679 readl((void *)(devpriv->dw_AiBase + 28)); 1680 } 1681 1682 /************************/ 1683 /* Enable the interrupt */ 1684 /************************/ 1685 1686 enable_irq(dev->irq); 1687 1688 return 0; 1689} 1690