1/** 2@verbatim 3 4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 5 6 ADDI-DATA GmbH 7 Dieselstrasse 3 8 D-77833 Ottersweier 9 Tel: +19(0)7223/9493-0 10 Fax: +49(0)7223/9493-92 11 http://www.addi-data.com 12 info@addi-data.com 13 14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 15 16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20You should also find the complete GPL in the COPYING file accompanying this source code. 21 22@endverbatim 23*/ 24/* 25 26 +-----------------------------------------------------------------------+ 27 | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | 28 +-----------------------------------------------------------------------+ 29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | 30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | 31 +-----------------------------------------------------------------------+ 32 | Project : ADDI DATA | Compiler : GCC | 33 | Modulname : addi_eeprom.c | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : ADDI EEPROM Module | 38 +-----------------------------------------------------------------------+ 39 | UPDATE'S | 40 +-----------------------------------------------------------------------+ 41 | Date | Author | Description of updates | 42 +----------+-----------+------------------------------------------------+ 43 | | | | 44 | | | | 45 +----------+-----------+------------------------------------------------+ 46*/ 47 48#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ 49#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ 50#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ 51#define EE76_CMD_LEN 13 /* bits in instructions */ 52#define EE_READ 0x0180 /* 01 1000 0000 read instruction */ 53 54#define EEPROM_DIGITALINPUT 0 55#define EEPROM_DIGITALOUTPUT 1 56#define EEPROM_ANALOGINPUT 2 57#define EEPROM_ANALOGOUTPUT 3 58#define EEPROM_TIMER 4 59#define EEPROM_WATCHDOG 5 60#define EEPROM_TIMER_WATCHDOG_COUNTER 10 61 62struct str_Functionality { 63 unsigned char b_Type; 64 unsigned short w_Address; 65}; 66 67struct str_MainHeader { 68 unsigned short w_HeaderSize; 69 unsigned char b_Nfunctions; 70 struct str_Functionality s_Functions[7]; 71}; 72 73struct str_DigitalInputHeader { 74 unsigned short w_Nchannel; 75 unsigned char b_Interruptible; 76 unsigned short w_NinterruptLogic; 77}; 78 79struct str_DigitalOutputHeader { 80 81 unsigned short w_Nchannel; 82}; 83 84 85/* used for timer as well as watchdog */ 86 87struct str_TimerDetails { 88 89 unsigned short w_HeaderSize; 90 unsigned char b_Resolution; 91 unsigned char b_Mode; /* in case of Watchdog it is functionality */ 92 unsigned short w_MinTiming; 93 unsigned char b_TimeBase; 94}; 95 96struct str_TimerMainHeader { 97 98 99 unsigned short w_Ntimer; 100 struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ 101}; 102 103 104struct str_AnalogOutputHeader { 105 unsigned short w_Nchannel; 106 unsigned char b_Resolution; 107}; 108 109struct str_AnalogInputHeader { 110 unsigned short w_Nchannel; 111 unsigned short w_MinConvertTiming; 112 unsigned short w_MinDelayTiming; 113 unsigned char b_HasDma; 114 unsigned char b_Resolution; 115}; 116 117 118 /*****************************************/ 119 /* Read Header Functions */ 120 /*****************************************/ 121 122int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, 123 char *pc_PCIChipInformation, struct comedi_device *dev); 124 125int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, 126 char *pc_PCIChipInformation, unsigned short w_Address, 127 struct str_DigitalInputHeader *s_Header); 128 129int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, 130 char *pc_PCIChipInformation, unsigned short w_Address, 131 struct str_DigitalOutputHeader *s_Header); 132 133int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, 134 char *pc_PCIChipInformation, unsigned short w_Address, 135 struct str_TimerMainHeader *s_Header); 136 137int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, 138 char *pc_PCIChipInformation, unsigned short w_Address, 139 struct str_AnalogOutputHeader *s_Header); 140 141int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, 142 char *pc_PCIChipInformation, unsigned short w_Address, 143 struct str_AnalogInputHeader *s_Header); 144 145 /******************************************/ 146 /* Eeprom Specific Functions */ 147 /******************************************/ 148unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, 149 unsigned short w_EepromStartAddress); 150void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); 151void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); 152void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); 153void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, 154 unsigned char b_DataLengthInBits); 155void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); 156 157/* 158+----------------------------------------------------------------------------+ 159| Function Name : unsigned short w_EepromReadWord | 160| (unsigned short w_PCIBoardEepromAddress, | 161| char * pc_PCIChipInformation, | 162| unsigned short w_EepromStartAddress) | 163+----------------------------------------------------------------------------+ 164| Task : Read from eepromn a word | 165+----------------------------------------------------------------------------+ 166| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 167| | 168| char *pc_PCIChipInformation : PCI Chip Type. | 169| | 170| unsigned short w_EepromStartAddress : Selected eeprom address | 171+----------------------------------------------------------------------------+ 172| Output Parameters : - | 173+----------------------------------------------------------------------------+ 174| Return Value : Read word value from eeprom | 175+----------------------------------------------------------------------------+ 176*/ 177 178unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, 179 unsigned short w_EepromStartAddress) 180{ 181 182 unsigned char b_Counter = 0; 183 184 unsigned char b_ReadByte = 0; 185 186 unsigned char b_ReadLowByte = 0; 187 188 unsigned char b_ReadHighByte = 0; 189 190 unsigned char b_SelectedAddressLow = 0; 191 192 unsigned char b_SelectedAddressHigh = 0; 193 194 unsigned short w_ReadWord = 0; 195 196 /**************************/ 197 198 /* Test the PCI chip type */ 199 200 /**************************/ 201 202 if ((!strcmp(pc_PCIChipInformation, "S5920")) || 203 (!strcmp(pc_PCIChipInformation, "S5933"))) 204 { 205 206 for (b_Counter = 0; b_Counter < 2; b_Counter++) 207 { 208 209 b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ 210 211 b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ 212 213 /************************************/ 214 215 /* Select the load low address mode */ 216 217 /************************************/ 218 219 outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); 220 221 /****************/ 222 223 /* Wait on busy */ 224 225 /****************/ 226 227 v_EepromWaitBusy(w_PCIBoardEepromAddress); 228 229 /************************/ 230 231 /* Load the low address */ 232 233 /************************/ 234 235 outb(b_SelectedAddressLow, 236 w_PCIBoardEepromAddress + 0x3E); 237 238 /****************/ 239 240 /* Wait on busy */ 241 242 /****************/ 243 244 v_EepromWaitBusy(w_PCIBoardEepromAddress); 245 246 /*************************************/ 247 248 /* Select the load high address mode */ 249 250 /*************************************/ 251 252 outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); 253 254 /****************/ 255 256 /* Wait on busy */ 257 258 /****************/ 259 260 v_EepromWaitBusy(w_PCIBoardEepromAddress); 261 262 /*************************/ 263 264 /* Load the high address */ 265 266 /*************************/ 267 268 outb(b_SelectedAddressHigh, 269 w_PCIBoardEepromAddress + 0x3E); 270 271 /****************/ 272 273 /* Wait on busy */ 274 275 /****************/ 276 277 v_EepromWaitBusy(w_PCIBoardEepromAddress); 278 279 /************************/ 280 281 /* Select the READ mode */ 282 283 /************************/ 284 285 outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); 286 287 /****************/ 288 289 /* Wait on busy */ 290 291 /****************/ 292 293 v_EepromWaitBusy(w_PCIBoardEepromAddress); 294 295 /*****************************/ 296 297 /* Read data into the EEPROM */ 298 299 /*****************************/ 300 301 b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); 302 303 /****************/ 304 305 /* Wait on busy */ 306 307 /****************/ 308 309 v_EepromWaitBusy(w_PCIBoardEepromAddress); 310 311 /*********************************/ 312 313 /* Select the upper address part */ 314 315 /*********************************/ 316 317 if (b_Counter == 0) 318 { 319 320 b_ReadLowByte = b_ReadByte; 321 322 } /* if(b_Counter==0) */ 323 324 else 325 { 326 327 b_ReadHighByte = b_ReadByte; 328 329 } /* if(b_Counter==0) */ 330 331 } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ 332 333 w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); 334 335 } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */ 336 337 if (!strcmp(pc_PCIChipInformation, "93C76")) 338 { 339 340 /*************************************/ 341 342 /* Read 16 bit from the EEPROM 93C76 */ 343 344 /*************************************/ 345 346 v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, 347 &w_ReadWord); 348 349 } 350 351 return w_ReadWord; 352 353} 354 355/* 356 357+----------------------------------------------------------------------------+ 358 359| Function Name : void v_EepromWaitBusy | 360 361| (unsigned short w_PCIBoardEepromAddress) | 362 363+----------------------------------------------------------------------------+ 364 365| Task : Wait the busy flag from PCI controller | 366 367+----------------------------------------------------------------------------+ 368 369| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address | 370 371+----------------------------------------------------------------------------+ 372 373| Output Parameters : - | 374 375+----------------------------------------------------------------------------+ 376 377| Return Value : - | 378 379+----------------------------------------------------------------------------+ 380 381*/ 382 383void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) 384{ 385 386 unsigned char b_EepromBusy = 0; 387 388 do 389 { 390 391 /*************/ 392 393 /* IMPORTANT */ 394 395 /*************/ 396 397 /************************************************************************/ 398 399 /* An error has been written in the AMCC 5933 book at the page B-13 */ 400 401 /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ 402 403 /* the operator register is AMCC_OP_REG_MCSR+3 */ 404 405 /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ 406 407 /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ 408 409 /************************************************************************/ 410 411 b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); 412 b_EepromBusy = b_EepromBusy & 0x80; 413 414 } while (b_EepromBusy == 0x80); 415 416} 417 418/* 419 420+---------------------------------------------------------------------------------+ 421 422| Function Name : void v_EepromClock76(unsigned int dw_Address, | 423 424| unsigned int dw_RegisterValue) | 425 426+---------------------------------------------------------------------------------+ 427 428| Task : This function sends the clocking sequence to the EEPROM. | 429 430+---------------------------------------------------------------------------------+ 431 432| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 433 434| unsigned int dw_RegisterValue : PCI eeprom register value to write.| 435 436+---------------------------------------------------------------------------------+ 437 438| Output Parameters : - | 439 440+---------------------------------------------------------------------------------+ 441 442| Return Value : - | 443 444+---------------------------------------------------------------------------------+ 445 446*/ 447 448void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) 449{ 450 451 /************************/ 452 453 /* Set EEPROM clock Low */ 454 455 /************************/ 456 457 outl(dw_RegisterValue & 0x6, dw_Address); 458 459 /***************/ 460 461 /* Wait 0.1 ms */ 462 463 /***************/ 464 465 udelay(100); 466 467 /*************************/ 468 469 /* Set EEPROM clock High */ 470 471 /*************************/ 472 473 outl(dw_RegisterValue | 0x1, dw_Address); 474 475 /***************/ 476 477 /* Wait 0.1 ms */ 478 479 /***************/ 480 481 udelay(100); 482 483} 484 485/* 486 487+---------------------------------------------------------------------------------+ 488 489| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, | 490 491| unsigned int dw_EepromCommand, | 492 493| unsigned char b_DataLengthInBits) | 494 495+---------------------------------------------------------------------------------+ 496 497| Task : This function sends a Command to the EEPROM 93C76. | 498 499+---------------------------------------------------------------------------------+ 500 501| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 502 503| unsigned int dw_EepromCommand : PCI eeprom command to write. | 504 505| unsigned char b_DataLengthInBits : PCI eeprom command data length. | 506 507+---------------------------------------------------------------------------------+ 508 509| Output Parameters : - | 510 511+---------------------------------------------------------------------------------+ 512 513| Return Value : - | 514 515+---------------------------------------------------------------------------------+ 516 517*/ 518 519void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, 520 unsigned char b_DataLengthInBits) 521{ 522 523 char c_BitPos = 0; 524 525 unsigned int dw_RegisterValue = 0; 526 527 /*****************************/ 528 529 /* Enable EEPROM Chip Select */ 530 531 /*****************************/ 532 533 dw_RegisterValue = 0x2; 534 535 /********************************************************************/ 536 537 /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ 538 539 /********************************************************************/ 540 541 outl(dw_RegisterValue, dw_Address); 542 543 /***************/ 544 545 /* Wait 0.1 ms */ 546 547 /***************/ 548 549 udelay(100); 550 551 /*******************************************/ 552 553 /* Send EEPROM command - one bit at a time */ 554 555 /*******************************************/ 556 557 for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) 558 { 559 560 /**********************************/ 561 562 /* Check if current bit is 0 or 1 */ 563 564 /**********************************/ 565 566 if (dw_EepromCommand & (1 << c_BitPos)) 567 { 568 569 /***********/ 570 571 /* Write 1 */ 572 573 /***********/ 574 575 dw_RegisterValue = dw_RegisterValue | 0x4; 576 577 } 578 579 else 580 { 581 582 /***********/ 583 584 /* Write 0 */ 585 586 /***********/ 587 588 dw_RegisterValue = dw_RegisterValue & 0x3; 589 590 } 591 592 /*********************/ 593 594 /* Write the command */ 595 596 /*********************/ 597 598 outl(dw_RegisterValue, dw_Address); 599 600 /***************/ 601 602 /* Wait 0.1 ms */ 603 604 /***************/ 605 606 udelay(100); 607 608 /****************************/ 609 610 /* Trigger the EEPROM clock */ 611 612 /****************************/ 613 614 v_EepromClock76(dw_Address, dw_RegisterValue); 615 616 } 617 618} 619 620/* 621 622+---------------------------------------------------------------------------------+ 623 624| Function Name : void v_EepromCs76Read(unsigned int dw_Address, | 625 626| unsigned short w_offset, | 627 628| unsigned short * pw_Value) | 629 630+---------------------------------------------------------------------------------+ 631 632| Task : This function read a value from the EEPROM 93C76. | 633 634+---------------------------------------------------------------------------------+ 635 636| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 637 638| unsigned short w_offset : Offset of the address to read | 639 640| unsigned short * pw_Value : PCI eeprom 16 bit read value. | 641 642+---------------------------------------------------------------------------------+ 643 644| Output Parameters : - | 645 646+---------------------------------------------------------------------------------+ 647 648| Return Value : - | 649 650+---------------------------------------------------------------------------------+ 651 652*/ 653 654void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value) 655{ 656 657 char c_BitPos = 0; 658 659 unsigned int dw_RegisterValue = 0; 660 661 unsigned int dw_RegisterValueRead = 0; 662 663 /*************************************************/ 664 665 /* Send EEPROM read command and offset to EEPROM */ 666 667 /*************************************************/ 668 669 v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), 670 EE76_CMD_LEN); 671 672 /*******************************/ 673 674 /* Get the last register value */ 675 676 /*******************************/ 677 678 dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; 679 680 /*****************************/ 681 682 /* Set the 16-bit value of 0 */ 683 684 /*****************************/ 685 686 *pw_Value = 0; 687 688 /************************/ 689 690 /* Get the 16-bit value */ 691 692 /************************/ 693 694 for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) 695 { 696 697 /****************************/ 698 699 /* Trigger the EEPROM clock */ 700 701 /****************************/ 702 703 v_EepromClock76(dw_Address, dw_RegisterValue); 704 705 /**********************/ 706 707 /* Get the result bit */ 708 709 /**********************/ 710 711 dw_RegisterValueRead = inl(dw_Address); 712 713 /***************/ 714 715 /* Wait 0.1 ms */ 716 717 /***************/ 718 719 udelay(100); 720 721 /***************************************/ 722 723 /* Get bit value and shift into result */ 724 725 /***************************************/ 726 727 if (dw_RegisterValueRead & 0x8) 728 { 729 730 /**********/ 731 732 /* Read 1 */ 733 734 /**********/ 735 736 *pw_Value = (*pw_Value << 1) | 0x1; 737 738 } 739 740 else 741 { 742 743 /**********/ 744 745 /* Read 0 */ 746 747 /**********/ 748 749 *pw_Value = (*pw_Value << 1); 750 751 } 752 753 } 754 755 /*************************/ 756 757 /* Clear all EEPROM bits */ 758 759 /*************************/ 760 761 dw_RegisterValue = 0x0; 762 763 /********************************************************************/ 764 765 /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ 766 767 /********************************************************************/ 768 769 outl(dw_RegisterValue, dw_Address); 770 771 /***************/ 772 773 /* Wait 0.1 ms */ 774 775 /***************/ 776 777 udelay(100); 778 779} 780 781 /******************************************/ 782 /* EEPROM HEADER READ FUNCTIONS */ 783 /******************************************/ 784 785/* 786+----------------------------------------------------------------------------+ 787| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, | 788| char * pc_PCIChipInformation,struct comedi_device *dev) | 789+----------------------------------------------------------------------------+ 790| Task : Read from eeprom Main Header | 791+----------------------------------------------------------------------------+ 792| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 793| | 794| char *pc_PCIChipInformation : PCI Chip Type. | 795| | 796| struct comedi_device *dev : comedi device structure | 797| pointer | 798+----------------------------------------------------------------------------+ 799| Output Parameters : - | 800+----------------------------------------------------------------------------+ 801| Return Value : 0 | 802+----------------------------------------------------------------------------+ 803*/ 804 805int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, 806 char *pc_PCIChipInformation, struct comedi_device *dev) 807{ 808 unsigned short w_Temp, i, w_Count = 0; 809 unsigned int ui_Temp; 810 struct str_MainHeader s_MainHeader; 811 struct str_DigitalInputHeader s_DigitalInputHeader; 812 struct str_DigitalOutputHeader s_DigitalOutputHeader; 813 /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ 814 struct str_AnalogOutputHeader s_AnalogOutputHeader; 815 struct str_AnalogInputHeader s_AnalogInputHeader; 816 817 /* Read size */ 818 s_MainHeader.w_HeaderSize = 819 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 820 0x100 + 8); 821 822 /* Read nbr of functionality */ 823 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 824 pc_PCIChipInformation, 0x100 + 10); 825 s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; 826 827 /* Read functionality details */ 828 for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { 829 /* Read Type */ 830 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 831 pc_PCIChipInformation, 0x100 + 12 + w_Count); 832 s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; 833 w_Count = w_Count + 2; 834 /* Read Address */ 835 s_MainHeader.s_Functions[i].w_Address = 836 w_EepromReadWord(w_PCIBoardEepromAddress, 837 pc_PCIChipInformation, 0x100 + 12 + w_Count); 838 w_Count = w_Count + 2; 839 } 840 841 /* Display main header info */ 842 for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { 843 844 switch (s_MainHeader.s_Functions[i].b_Type) { 845 case EEPROM_DIGITALINPUT: 846 i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress, 847 pc_PCIChipInformation, 848 s_MainHeader.s_Functions[i].w_Address, 849 &s_DigitalInputHeader); 850 devpriv->s_EeParameters.i_NbrDiChannel = 851 s_DigitalInputHeader.w_Nchannel; 852 break; 853 854 case EEPROM_DIGITALOUTPUT: 855 i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress, 856 pc_PCIChipInformation, 857 s_MainHeader.s_Functions[i].w_Address, 858 &s_DigitalOutputHeader); 859 devpriv->s_EeParameters.i_NbrDoChannel = 860 s_DigitalOutputHeader.w_Nchannel; 861 ui_Temp = 0xffffffff; 862 devpriv->s_EeParameters.i_DoMaxdata = 863 ui_Temp >> (32 - 864 devpriv->s_EeParameters.i_NbrDoChannel); 865 break; 866 867 case EEPROM_ANALOGINPUT: 868 i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress, 869 pc_PCIChipInformation, 870 s_MainHeader.s_Functions[i].w_Address, 871 &s_AnalogInputHeader); 872 if (!(strcmp(this_board->pc_DriverName, "apci3200"))) 873 devpriv->s_EeParameters.i_NbrAiChannel = 874 s_AnalogInputHeader.w_Nchannel * 4; 875 else 876 devpriv->s_EeParameters.i_NbrAiChannel = 877 s_AnalogInputHeader.w_Nchannel; 878 devpriv->s_EeParameters.i_Dma = 879 s_AnalogInputHeader.b_HasDma; 880 devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = 881 (unsigned int) s_AnalogInputHeader.w_MinConvertTiming * 882 1000; 883 devpriv->s_EeParameters.ui_MinDelaytimeNs = 884 (unsigned int) s_AnalogInputHeader.w_MinDelayTiming * 885 1000; 886 ui_Temp = 0xffff; 887 devpriv->s_EeParameters.i_AiMaxdata = 888 ui_Temp >> (16 - 889 s_AnalogInputHeader.b_Resolution); 890 break; 891 892 case EEPROM_ANALOGOUTPUT: 893 i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress, 894 pc_PCIChipInformation, 895 s_MainHeader.s_Functions[i].w_Address, 896 &s_AnalogOutputHeader); 897 devpriv->s_EeParameters.i_NbrAoChannel = 898 s_AnalogOutputHeader.w_Nchannel; 899 ui_Temp = 0xffff; 900 devpriv->s_EeParameters.i_AoMaxdata = 901 ui_Temp >> (16 - 902 s_AnalogOutputHeader.b_Resolution); 903 break; 904 905 case EEPROM_TIMER: 906 /* Timer subdevice present */ 907 devpriv->s_EeParameters.i_Timer = 1; 908 break; 909 910 case EEPROM_WATCHDOG: 911 /* Timer subdevice present */ 912 devpriv->s_EeParameters.i_Timer = 1; 913 break; 914 915 case EEPROM_TIMER_WATCHDOG_COUNTER: 916 /* Timer subdevice present */ 917 devpriv->s_EeParameters.i_Timer = 1; 918 break; 919 } 920 } 921 922 return 0; 923} 924 925/* 926+----------------------------------------------------------------------------+ 927| Function Name : int i_EepromReadDigitalInputHeader(unsigned short | 928| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 929| unsigned short w_Address,struct str_DigitalInputHeader *s_Header) | 930| | 931+----------------------------------------------------------------------------+ 932| Task : Read Digital Input Header | 933+----------------------------------------------------------------------------+ 934| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 935| | 936| char *pc_PCIChipInformation : PCI Chip Type. | 937| | 938| struct str_DigitalInputHeader *s_Header: Digita Input Header | 939| Pointer | 940+----------------------------------------------------------------------------+ 941| Output Parameters : - | 942+----------------------------------------------------------------------------+ 943| Return Value : 0 | 944+----------------------------------------------------------------------------+ 945*/ 946int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, 947 char *pc_PCIChipInformation, unsigned short w_Address, 948 struct str_DigitalInputHeader *s_Header) 949{ 950 unsigned short w_Temp; 951 952 /* read nbr of channels */ 953 s_Header->w_Nchannel = 954 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 955 0x100 + w_Address + 6); 956 957 /* interruptible or not */ 958 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 959 pc_PCIChipInformation, 0x100 + w_Address + 8); 960 s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; 961 962/* How many interruptible logic */ 963 s_Header->w_NinterruptLogic = 964 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 965 0x100 + w_Address + 10); 966 967 return 0; 968} 969 970/* 971+----------------------------------------------------------------------------+ 972| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short | 973| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 974| unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) | 975| | 976+----------------------------------------------------------------------------+ 977| Task : Read Digital Output Header | 978+----------------------------------------------------------------------------+ 979| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 980| | 981| char *pc_PCIChipInformation : PCI Chip Type. | 982| | 983| struct str_DigitalOutputHeader *s_Header: Digital Output Header| 984| Pointer | 985+----------------------------------------------------------------------------+ 986| Output Parameters : - | 987+----------------------------------------------------------------------------+ 988| Return Value : 0 | 989+----------------------------------------------------------------------------+ 990*/ 991int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, 992 char *pc_PCIChipInformation, unsigned short w_Address, 993 struct str_DigitalOutputHeader *s_Header) 994{ 995/* Read Nbr channels */ 996 s_Header->w_Nchannel = 997 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 998 0x100 + w_Address + 6); 999 return 0; 1000} 1001 1002/* 1003+----------------------------------------------------------------------------+ 1004| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, | 1005| char *pc_PCIChipInformation,WORD w_Address, | 1006| struct str_TimerMainHeader *s_Header) | 1007+----------------------------------------------------------------------------+ 1008| Task : Read Timer or Watchdog Header | 1009+----------------------------------------------------------------------------+ 1010| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 1011| | 1012| char *pc_PCIChipInformation : PCI Chip Type. | 1013| | 1014| struct str_TimerMainHeader *s_Header: Timer Header | 1015| Pointer | 1016+----------------------------------------------------------------------------+ 1017| Output Parameters : - | 1018+----------------------------------------------------------------------------+ 1019| Return Value : 0 | 1020+----------------------------------------------------------------------------+ 1021*/ 1022int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, 1023 char *pc_PCIChipInformation, unsigned short w_Address, 1024 struct str_TimerMainHeader *s_Header) 1025{ 1026 1027 unsigned short i, w_Size = 0, w_Temp; 1028 1029/* Read No of Timer */ 1030 s_Header->w_Ntimer = 1031 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1032 0x100 + w_Address + 6); 1033/* Read header size */ 1034 1035 for (i = 0; i < s_Header->w_Ntimer; i++) { 1036 s_Header->s_TimerDetails[i].w_HeaderSize = 1037 w_EepromReadWord(w_PCIBoardEepromAddress, 1038 pc_PCIChipInformation, 1039 0x100 + w_Address + 8 + w_Size + 0); 1040 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1041 pc_PCIChipInformation, 1042 0x100 + w_Address + 8 + w_Size + 2); 1043 1044 /* Read Resolution */ 1045 s_Header->s_TimerDetails[i].b_Resolution = 1046 (unsigned char) (w_Temp >> 10) & 0x3F; 1047 1048 /* Read Mode */ 1049 s_Header->s_TimerDetails[i].b_Mode = 1050 (unsigned char) (w_Temp >> 4) & 0x3F; 1051 1052 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1053 pc_PCIChipInformation, 1054 0x100 + w_Address + 8 + w_Size + 4); 1055 1056 /* Read MinTiming */ 1057 s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; 1058 1059 /* Read Timebase */ 1060 s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; 1061 w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; 1062 } 1063 1064 return 0; 1065} 1066 1067/* 1068+----------------------------------------------------------------------------+ 1069| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short | 1070| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 1071| unsigned short w_Address,str_AnalogOutputHeader *s_Header) | 1072+----------------------------------------------------------------------------+ 1073| Task : Read Nalog Output Header | 1074+----------------------------------------------------------------------------+ 1075| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 1076| | 1077| char *pc_PCIChipInformation : PCI Chip Type. | 1078| | 1079| str_AnalogOutputHeader *s_Header:Anlog Output Header | 1080| Pointer | 1081+----------------------------------------------------------------------------+ 1082| Output Parameters : - | 1083+----------------------------------------------------------------------------+ 1084| Return Value : 0 | 1085+----------------------------------------------------------------------------+ 1086*/ 1087 1088int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, 1089 char *pc_PCIChipInformation, unsigned short w_Address, 1090 struct str_AnalogOutputHeader *s_Header) 1091{ 1092 unsigned short w_Temp; 1093 /* No of channels for 1st hard component */ 1094 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1095 pc_PCIChipInformation, 0x100 + w_Address + 10); 1096 s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; 1097 /* Resolution for 1st hard component */ 1098 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1099 pc_PCIChipInformation, 0x100 + w_Address + 16); 1100 s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; 1101 return 0; 1102} 1103 1104/* 1105+----------------------------------------------------------------------------+ 1106| Function Name : int i_EepromReadAnlogInputHeader(unsigned short | 1107| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 1108| unsigned short w_Address,struct str_AnalogInputHeader *s_Header) | 1109+----------------------------------------------------------------------------+ 1110| Task : Read Nalog Output Header | 1111+----------------------------------------------------------------------------+ 1112| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 1113| | 1114| char *pc_PCIChipInformation : PCI Chip Type. | 1115| | 1116| struct str_AnalogInputHeader *s_Header:Anlog Input Header | 1117| Pointer | 1118+----------------------------------------------------------------------------+ 1119| Output Parameters : - | 1120+----------------------------------------------------------------------------+ 1121| Return Value : 0 | 1122+----------------------------------------------------------------------------+ 1123*/ 1124 1125/* Reads only for ONE hardware component */ 1126int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, 1127 char *pc_PCIChipInformation, unsigned short w_Address, 1128 struct str_AnalogInputHeader *s_Header) 1129{ 1130 unsigned short w_Temp, w_Offset; 1131 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1132 pc_PCIChipInformation, 0x100 + w_Address + 10); 1133 s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; 1134 s_Header->w_MinConvertTiming = 1135 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1136 0x100 + w_Address + 16); 1137 s_Header->w_MinDelayTiming = 1138 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1139 0x100 + w_Address + 30); 1140 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1141 pc_PCIChipInformation, 0x100 + w_Address + 20); 1142 s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ 1143 1144 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ 1145 w_Temp = w_Temp & 0x00FF; 1146 if (w_Temp) /* Y>0 */ 1147 { 1148 w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ 1149 w_Offset = w_Offset + 2; /* resolution */ 1150 } else /* Y=0 */ 1151 { 1152 w_Offset = 74; 1153 w_Offset = w_Offset + 2; /* resolution */ 1154 } 1155 1156/* read Resolution */ 1157 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1158 pc_PCIChipInformation, 0x100 + w_Address + w_Offset); 1159 s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ 1160 1161 return 0; 1162} 1163