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