Staging: comedi: more remove C99 comments
[pandora-kernel.git] / 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 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
62 struct str_Functionality {
63         unsigned char b_Type;
64         unsigned short w_Address;
65 };
66
67 struct str_MainHeader {
68         unsigned short w_HeaderSize;
69         unsigned char b_Nfunctions;
70         struct str_Functionality s_Functions[7];
71 };
72
73 struct str_DigitalInputHeader {
74         unsigned short w_Nchannel;
75         unsigned char b_Interruptible;
76         unsigned short w_NinterruptLogic;
77 };
78
79 struct str_DigitalOutputHeader {
80
81         unsigned short w_Nchannel;
82 };
83
84
85 /* used for timer as well as watchdog */
86
87 struct 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
96 struct str_TimerMainHeader {
97
98
99         unsigned short w_Ntimer;
100         struct str_TimerDetails s_TimerDetails[4];      /*   supports 4 timers */
101 };
102
103
104 typedef struct {
105         unsigned short w_Nchannel;
106         unsigned char b_Resolution;
107 } str_AnalogOutputHeader;
108
109 struct 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
122 int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
123         char *pc_PCIChipInformation, struct comedi_device *dev);
124
125 int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
126         char *pc_PCIChipInformation, unsigned short w_Address,
127         struct str_DigitalInputHeader * s_Header);
128
129 int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
130         char *pc_PCIChipInformation, unsigned short w_Address,
131         struct str_DigitalOutputHeader * s_Header);
132
133 int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
134         char *pc_PCIChipInformation, unsigned short w_Address,
135         struct str_TimerMainHeader * s_Header);
136
137 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
138         char *pc_PCIChipInformation, unsigned short w_Address,
139         str_AnalogOutputHeader * s_Header);
140
141 int 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                 /******************************************/
148 unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
149         unsigned short w_EepromStartAddress);
150 void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
151 void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue);
152 void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
153 void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
154         unsigned char b_DataLengthInBits);
155 void 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
178 unsigned 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
383 void 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         }
415         while (b_EepromBusy == 0x80);
416
417 }
418
419 /*
420
421 +---------------------------------------------------------------------------------+
422
423 | Function   Name   : void v_EepromClock76(unsigned int dw_Address,                      |
424
425 |                                          unsigned int dw_RegisterValue)                                         |
426
427 +---------------------------------------------------------------------------------+
428
429 | Task              : This function sends the clocking sequence to the EEPROM.    |
430
431 +---------------------------------------------------------------------------------+
432
433 | Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
434
435 |                     unsigned int dw_RegisterValue : PCI eeprom register value to write.|
436
437 +---------------------------------------------------------------------------------+
438
439 | Output Parameters : -                                                           |
440
441 +---------------------------------------------------------------------------------+
442
443 | Return Value      : -                                                           |
444
445 +---------------------------------------------------------------------------------+
446
447 */
448
449 void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue)
450 {
451
452    /************************/
453
454         /* Set EEPROM clock Low */
455
456    /************************/
457
458         outl(dw_RegisterValue & 0x6, dw_Address);
459
460    /***************/
461
462         /* Wait 0.1 ms */
463
464    /***************/
465
466         udelay(100);
467
468    /*************************/
469
470         /* Set EEPROM clock High */
471
472    /*************************/
473
474         outl(dw_RegisterValue | 0x1, dw_Address);
475
476    /***************/
477
478         /* Wait 0.1 ms */
479
480    /***************/
481
482         udelay(100);
483
484 }
485
486 /*
487
488 +---------------------------------------------------------------------------------+
489
490 | Function   Name   : void v_EepromSendCommand76(unsigned int dw_Address,                |
491
492 |                                          unsigned int   dw_EepromCommand,                               |
493
494 |                                          unsigned char    b_DataLengthInBits)                        |
495
496 +---------------------------------------------------------------------------------+
497
498 | Task              : This function sends a Command to the EEPROM 93C76.          |
499
500 +---------------------------------------------------------------------------------+
501
502 | Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
503
504 |                     unsigned int dw_EepromCommand : PCI eeprom command to write.       |
505
506 |                     unsigned char  b_DataLengthInBits : PCI eeprom command data length.  |
507
508 +---------------------------------------------------------------------------------+
509
510 | Output Parameters : -                                                           |
511
512 +---------------------------------------------------------------------------------+
513
514 | Return Value      : -                                                           |
515
516 +---------------------------------------------------------------------------------+
517
518 */
519
520 void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
521         unsigned char b_DataLengthInBits)
522 {
523
524         char c_BitPos = 0;
525
526         unsigned int dw_RegisterValue = 0;
527
528    /*****************************/
529
530         /* Enable EEPROM Chip Select */
531
532    /*****************************/
533
534         dw_RegisterValue = 0x2;
535
536    /********************************************************************/
537
538         /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
539
540    /********************************************************************/
541
542         outl(dw_RegisterValue, dw_Address);
543
544    /***************/
545
546         /* Wait 0.1 ms */
547
548    /***************/
549
550         udelay(100);
551
552    /*******************************************/
553
554         /* Send EEPROM command - one bit at a time */
555
556    /*******************************************/
557
558         for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
559         {
560
561       /**********************************/
562
563                 /* Check if current bit is 0 or 1 */
564
565       /**********************************/
566
567                 if (dw_EepromCommand & (1 << c_BitPos))
568                 {
569
570          /***********/
571
572                         /* Write 1 */
573
574          /***********/
575
576                         dw_RegisterValue = dw_RegisterValue | 0x4;
577
578                 }
579
580                 else
581                 {
582
583          /***********/
584
585                         /* Write 0 */
586
587          /***********/
588
589                         dw_RegisterValue = dw_RegisterValue & 0x3;
590
591                 }
592
593       /*********************/
594
595                 /* Write the command */
596
597       /*********************/
598
599                 outl(dw_RegisterValue, dw_Address);
600
601       /***************/
602
603                 /* Wait 0.1 ms */
604
605       /***************/
606
607                 udelay(100);
608
609       /****************************/
610
611                 /* Trigger the EEPROM clock */
612
613       /****************************/
614
615                 v_EepromClock76(dw_Address, dw_RegisterValue);
616
617         }
618
619 }
620
621 /*
622
623 +---------------------------------------------------------------------------------+
624
625 | Function   Name   : void v_EepromCs76Read(unsigned int dw_Address,                     |
626
627 |                                          unsigned short    w_offset,                                            |
628
629 |                                          unsigned short *   pw_Value)                                           |
630
631 +---------------------------------------------------------------------------------+
632
633 | Task              : This function read a value from the EEPROM 93C76.           |
634
635 +---------------------------------------------------------------------------------+
636
637 | Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
638
639 |                     unsigned short    w_offset : Offset of the adress to read             |
640
641 |                     unsigned short *   pw_Value : PCI eeprom 16 bit read value.            |
642
643 +---------------------------------------------------------------------------------+
644
645 | Output Parameters : -                                                           |
646
647 +---------------------------------------------------------------------------------+
648
649 | Return Value      : -                                                           |
650
651 +---------------------------------------------------------------------------------+
652
653 */
654
655 void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value)
656 {
657
658         char c_BitPos = 0;
659
660         unsigned int dw_RegisterValue = 0;
661
662         unsigned int dw_RegisterValueRead = 0;
663
664    /*************************************************/
665
666         /* Send EEPROM read command and offset to EEPROM */
667
668    /*************************************************/
669
670         v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
671                 EE76_CMD_LEN);
672
673    /*******************************/
674
675         /* Get the last register value */
676
677    /*******************************/
678
679         dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
680
681    /*****************************/
682
683         /* Set the 16-bit value of 0 */
684
685    /*****************************/
686
687         *pw_Value = 0;
688
689    /************************/
690
691         /* Get the 16-bit value */
692
693    /************************/
694
695         for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
696         {
697
698       /****************************/
699
700                 /* Trigger the EEPROM clock */
701
702       /****************************/
703
704                 v_EepromClock76(dw_Address, dw_RegisterValue);
705
706       /**********************/
707
708                 /* Get the result bit */
709
710       /**********************/
711
712                 dw_RegisterValueRead = inl(dw_Address);
713
714       /***************/
715
716                 /* Wait 0.1 ms */
717
718       /***************/
719
720                 udelay(100);
721
722       /***************************************/
723
724                 /* Get bit value and shift into result */
725
726       /***************************************/
727
728                 if (dw_RegisterValueRead & 0x8)
729                 {
730
731          /**********/
732
733                         /* Read 1 */
734
735          /**********/
736
737                         *pw_Value = (*pw_Value << 1) | 0x1;
738
739                 }
740
741                 else
742                 {
743
744          /**********/
745
746                         /* Read 0 */
747
748          /**********/
749
750                         *pw_Value = (*pw_Value << 1);
751
752                 }
753
754         }
755
756    /*************************/
757
758         /* Clear all EEPROM bits */
759
760    /*************************/
761
762         dw_RegisterValue = 0x0;
763
764    /********************************************************************/
765
766         /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
767
768    /********************************************************************/
769
770         outl(dw_RegisterValue, dw_Address);
771
772    /***************/
773
774         /* Wait 0.1 ms */
775
776    /***************/
777
778         udelay(100);
779
780 }
781
782         /******************************************/
783         /*      EEPROM HEADER READ FUNCTIONS      */
784         /******************************************/
785
786 /*
787 +----------------------------------------------------------------------------+
788 | Function Name  : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,  |
789 |                               char *  pc_PCIChipInformation,struct comedi_device *dev)    |
790 +----------------------------------------------------------------------------+
791 | Task              : Read from eeprom Main Header                           |
792 +----------------------------------------------------------------------------+
793 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
794 |                                                                                                                                        |
795 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
796 |                                                                                                                                        |
797 |                         struct comedi_device *dev                : comedi device structure |
798 |                                                                                        pointer                                 |
799 +----------------------------------------------------------------------------+
800 | Output Parameters : -                                                      |
801 +----------------------------------------------------------------------------+
802 | Return Value      : 0                                                                              |
803 +----------------------------------------------------------------------------+
804 */
805
806 int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
807         char *pc_PCIChipInformation, struct comedi_device *dev)
808 {
809         unsigned short w_Temp, i, w_Count = 0;
810         unsigned int ui_Temp;
811         struct str_MainHeader s_MainHeader;
812         struct str_DigitalInputHeader s_DigitalInputHeader;
813         struct str_DigitalOutputHeader s_DigitalOutputHeader;
814         /* struct str_TimerMainHeader     s_TimerMainHeader,s_WatchdogMainHeader; */
815         str_AnalogOutputHeader s_AnalogOutputHeader;
816         struct str_AnalogInputHeader s_AnalogInputHeader;
817
818         /* Read size */
819         s_MainHeader.w_HeaderSize =
820                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
821                 0x100 + 8);
822
823         /* Read nbr of functionality */
824         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
825                 pc_PCIChipInformation, 0x100 + 10);
826         s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF;
827
828         /* Read functionality details */
829         for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
830                 /* Read Type */
831                 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
832                         pc_PCIChipInformation, 0x100 + 12 + w_Count);
833                 s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F;
834                 w_Count = w_Count + 2;
835                 /* Read Address */
836                 s_MainHeader.s_Functions[i].w_Address =
837                         w_EepromReadWord(w_PCIBoardEepromAddress,
838                         pc_PCIChipInformation, 0x100 + 12 + w_Count);
839                 w_Count = w_Count + 2;
840         }
841
842         /* Display main header info */
843         for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
844
845                 switch (s_MainHeader.s_Functions[i].b_Type) {
846                 case EEPROM_DIGITALINPUT:
847                         i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
848                                 pc_PCIChipInformation,
849                                 s_MainHeader.s_Functions[i].w_Address,
850                                 &s_DigitalInputHeader);
851                         this_board->i_NbrDiChannel =
852                                 s_DigitalInputHeader.w_Nchannel;
853                         break;
854
855                 case EEPROM_DIGITALOUTPUT:
856                         i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
857                                 pc_PCIChipInformation,
858                                 s_MainHeader.s_Functions[i].w_Address,
859                                 &s_DigitalOutputHeader);
860                         this_board->i_NbrDoChannel =
861                                 s_DigitalOutputHeader.w_Nchannel;
862                         ui_Temp = 0xffffffff;
863                         this_board->i_DoMaxdata =
864                                 ui_Temp >> (32 - this_board->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                                 this_board->i_NbrAiChannel =
874                                         s_AnalogInputHeader.w_Nchannel * 4;
875                         else
876                                 this_board->i_NbrAiChannel =
877                                         s_AnalogInputHeader.w_Nchannel;
878                         this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
879                         this_board->ui_MinAcquisitiontimeNs =
880                                 (unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
881                                 1000;
882                         this_board->ui_MinDelaytimeNs =
883                                 (unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
884                                 1000;
885                         ui_Temp = 0xffff;
886                         this_board->i_AiMaxdata =
887                                 ui_Temp >> (16 -
888                                 s_AnalogInputHeader.b_Resolution);
889                         break;
890
891                 case EEPROM_ANALOGOUTPUT:
892                         i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
893                                 pc_PCIChipInformation,
894                                 s_MainHeader.s_Functions[i].w_Address,
895                                 &s_AnalogOutputHeader);
896                         this_board->i_NbrAoChannel =
897                                 s_AnalogOutputHeader.w_Nchannel;
898                         ui_Temp = 0xffff;
899                         this_board->i_AoMaxdata =
900                                 ui_Temp >> (16 -
901                                 s_AnalogOutputHeader.b_Resolution);
902                         break;
903
904                 case EEPROM_TIMER:
905                         this_board->i_Timer = 1;        /* Timer subdevice present */
906                         break;
907
908                 case EEPROM_WATCHDOG:
909                         this_board->i_Timer = 1;        /* Timer subdevice present */
910                         break;
911
912                 case EEPROM_TIMER_WATCHDOG_COUNTER:
913                         this_board->i_Timer = 1;        /* Timer subdevice present */
914                 }
915         }
916
917         return 0;
918 }
919
920 /*
921 +----------------------------------------------------------------------------+
922 | Function Name  : int i_EepromReadDigitalInputHeader(unsigned short                                     |
923 |                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
924 |                       unsigned short w_Address,struct str_DigitalInputHeader *s_Header)                |
925 |                                                                                                                                        |
926 +----------------------------------------------------------------------------+
927 | Task              : Read Digital Input Header                              |
928 +----------------------------------------------------------------------------+
929 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
930 |                                                                                                                                        |
931 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
932 |                                                                                                                                        |
933 |                        struct str_DigitalInputHeader *s_Header: Digita Input Header   |
934 |                                                                                                  Pointer                       |
935 +----------------------------------------------------------------------------+
936 | Output Parameters : -                                                      |
937 +----------------------------------------------------------------------------+
938 | Return Value      : 0                                                                              |
939 +----------------------------------------------------------------------------+
940 */
941 int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
942         char *pc_PCIChipInformation, unsigned short w_Address,
943         struct str_DigitalInputHeader *s_Header)
944 {
945         unsigned short w_Temp;
946
947         /*  read nbr of channels */
948         s_Header->w_Nchannel =
949                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
950                 0x100 + w_Address + 6);
951
952         /*  interruptible or not */
953         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
954                 pc_PCIChipInformation, 0x100 + w_Address + 8);
955         s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01;
956
957 /* How many interruptible logic */
958         s_Header->w_NinterruptLogic =
959                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
960                 0x100 + w_Address + 10);
961
962         return 0;
963 }
964
965 /*
966 +----------------------------------------------------------------------------+
967 | Function Name  : int i_EepromReadDigitalOutputHeader(unsigned short                            |
968 |                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
969 |                       unsigned short w_Address,struct str_DigitalOutputHeader *s_Header)           |
970 |                                                                                                                                        |
971 +----------------------------------------------------------------------------+
972 | Task              : Read Digital Output Header                             |
973 +----------------------------------------------------------------------------+
974 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
975 |                                                                                                                                        |
976 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
977 |                                                                                                                                        |
978 |                        struct str_DigitalOutputHeader *s_Header: Digital Output Header|
979 |                                                                                          Pointer                               |
980 +----------------------------------------------------------------------------+
981 | Output Parameters : -                                                      |
982 +----------------------------------------------------------------------------+
983 | Return Value      : 0                                                                              |
984 +----------------------------------------------------------------------------+
985 */
986 int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
987         char *pc_PCIChipInformation, unsigned short w_Address,
988         struct str_DigitalOutputHeader *s_Header)
989 {
990 /* Read Nbr channels */
991         s_Header->w_Nchannel =
992                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
993                 0x100 + w_Address + 6);
994         return 0;
995 }
996
997 /*
998 +----------------------------------------------------------------------------+
999 | Function Name  : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, |
1000 |                       char *pc_PCIChipInformation,WORD w_Address,                              |
1001 |                       struct str_TimerMainHeader *s_Header)                                                    |
1002 +----------------------------------------------------------------------------+
1003 | Task              : Read Timer or Watchdog Header                          |
1004 +----------------------------------------------------------------------------+
1005 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
1006 |                                                                                                                                        |
1007 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
1008 |                                                                                                                                        |
1009 |                        struct str_TimerMainHeader *s_Header: Timer Header                      |
1010 |                                                                                          Pointer                               |
1011 +----------------------------------------------------------------------------+
1012 | Output Parameters : -                                                      |
1013 +----------------------------------------------------------------------------+
1014 | Return Value      : 0                                                                              |
1015 +----------------------------------------------------------------------------+
1016 */
1017 int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
1018         char *pc_PCIChipInformation, unsigned short w_Address,
1019         struct str_TimerMainHeader *s_Header)
1020 {
1021
1022         unsigned short i, w_Size = 0, w_Temp;
1023
1024 /* Read No of Timer */
1025         s_Header->w_Ntimer =
1026                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
1027                 0x100 + w_Address + 6);
1028 /* Read header size */
1029
1030         for (i = 0; i < s_Header->w_Ntimer; i++) {
1031                 s_Header->s_TimerDetails[i].w_HeaderSize =
1032                         w_EepromReadWord(w_PCIBoardEepromAddress,
1033                         pc_PCIChipInformation,
1034                         0x100 + w_Address + 8 + w_Size + 0);
1035                 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1036                         pc_PCIChipInformation,
1037                         0x100 + w_Address + 8 + w_Size + 2);
1038
1039                 /* Read Resolution */
1040                 s_Header->s_TimerDetails[i].b_Resolution =
1041                         (unsigned char) (w_Temp >> 10) & 0x3F;
1042
1043                 /* Read Mode */
1044                 s_Header->s_TimerDetails[i].b_Mode =
1045                         (unsigned char) (w_Temp >> 4) & 0x3F;
1046
1047                 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1048                         pc_PCIChipInformation,
1049                         0x100 + w_Address + 8 + w_Size + 4);
1050
1051                 /* Read MinTiming */
1052                 s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
1053
1054                 /* Read Timebase */
1055                 s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F;
1056                 w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
1057         }
1058
1059         return 0;
1060 }
1061
1062 /*
1063 +----------------------------------------------------------------------------+
1064 | Function Name  : int i_EepromReadAnlogOutputHeader(unsigned short                                      |
1065 |                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
1066 |                       unsigned short w_Address,str_AnalogOutputHeader *s_Header)         |
1067 +----------------------------------------------------------------------------+
1068 | Task              : Read Nalog Output  Header                              |
1069 +----------------------------------------------------------------------------+
1070 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
1071 |                                                                                                                                        |
1072 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
1073 |                                                                                                                                        |
1074 |                        str_AnalogOutputHeader *s_Header:Anlog Output Header    |
1075 |                                                                                          Pointer                               |
1076 +----------------------------------------------------------------------------+
1077 | Output Parameters : -                                                      |
1078 +----------------------------------------------------------------------------+
1079 | Return Value      : 0                                                                              |
1080 +----------------------------------------------------------------------------+
1081 */
1082
1083 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
1084         char *pc_PCIChipInformation, unsigned short w_Address,
1085         str_AnalogOutputHeader * s_Header)
1086 {
1087         unsigned short w_Temp;
1088         /*  No of channels for 1st hard component */
1089         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1090                 pc_PCIChipInformation, 0x100 + w_Address + 10);
1091         s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
1092         /*  Resolution for 1st hard component */
1093         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1094                 pc_PCIChipInformation, 0x100 + w_Address + 16);
1095         s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF;
1096         return 0;
1097 }
1098
1099 /*
1100 +----------------------------------------------------------------------------+
1101 | Function Name  : int i_EepromReadAnlogInputHeader(unsigned short                                       |
1102 |                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
1103 |                       unsigned short w_Address,struct str_AnalogInputHeader *s_Header)          |
1104 +----------------------------------------------------------------------------+
1105 | Task              : Read Nalog Output  Header                              |
1106 +----------------------------------------------------------------------------+
1107 | Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
1108 |                                                                                                                                        |
1109 |                     char *pc_PCIChipInformation  : PCI Chip Type.          |
1110 |                                                                                                                                        |
1111 |                        struct str_AnalogInputHeader *s_Header:Anlog Input Header      |
1112 |                                                                                          Pointer                               |
1113 +----------------------------------------------------------------------------+
1114 | Output Parameters : -                                                      |
1115 +----------------------------------------------------------------------------+
1116 | Return Value      : 0                                                                              |
1117 +----------------------------------------------------------------------------+
1118 */
1119
1120 /* Reads only for ONE  hardware component */
1121 int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
1122         char *pc_PCIChipInformation, unsigned short w_Address,
1123         struct str_AnalogInputHeader *s_Header)
1124 {
1125         unsigned short w_Temp, w_Offset;
1126         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1127                 pc_PCIChipInformation, 0x100 + w_Address + 10);
1128         s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
1129         s_Header->w_MinConvertTiming =
1130                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
1131                 0x100 + w_Address + 16);
1132         s_Header->w_MinDelayTiming =
1133                 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
1134                 0x100 + w_Address + 30);
1135         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1136                 pc_PCIChipInformation, 0x100 + w_Address + 20);
1137         s_Header->b_HasDma = (w_Temp >> 13) & 0x01;     /*  whether dma present or not */
1138
1139         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72);      /*  reading Y */
1140         w_Temp = w_Temp & 0x00FF;
1141         if (w_Temp)             /* Y>0 */
1142         {
1143                 w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16)));      /*  offset of first analog input single header */
1144                 w_Offset = w_Offset + 2;        /*  resolution */
1145         } else                  /* Y=0 */
1146         {
1147                 w_Offset = 74;
1148                 w_Offset = w_Offset + 2;        /*  resolution */
1149         }
1150
1151 /* read Resolution */
1152         w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
1153                 pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
1154         s_Header->b_Resolution = w_Temp & 0x001F;       /*  last 5 bits */
1155
1156         return 0;
1157 }