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