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