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