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