addi_eeprom.c revision 356cdbcb838ebcc234a43ec81621a39231fdcb7a
1/**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6	ADDI-DATA GmbH
7	Dieselstrasse 3
8	D-77833 Ottersweier
9	Tel: +19(0)7223/9493-0
10	Fax: +49(0)7223/9493-92
11	http://www.addi-data-com
12	info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You 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
62struct str_Functionality {
63	unsigned char b_Type;
64	unsigned short w_Address;
65};
66
67struct str_MainHeader {
68	unsigned short w_HeaderSize;
69	unsigned char b_Nfunctions;
70	struct str_Functionality s_Functions[7];
71};
72
73struct str_DigitalInputHeader {
74	unsigned short w_Nchannel;
75	unsigned char b_Interruptible;
76	unsigned short w_NinterruptLogic;
77};
78
79struct str_DigitalOutputHeader {
80
81	unsigned short w_Nchannel;
82};
83
84
85/* used for timer as well as watchdog */
86
87struct str_TimerDetails {
88
89	unsigned short w_HeaderSize;
90	unsigned char b_Resolution;
91	unsigned char b_Mode;		/*  in case of Watchdog it is functionality */
92	unsigned short w_MinTiming;
93	unsigned char b_TimeBase;
94};
95
96struct str_TimerMainHeader {
97
98
99	unsigned short w_Ntimer;
100	struct str_TimerDetails s_TimerDetails[4];	/*   supports 4 timers */
101};
102
103
104typedef struct {
105	unsigned short w_Nchannel;
106	unsigned char b_Resolution;
107} str_AnalogOutputHeader;
108
109struct str_AnalogInputHeader {
110	unsigned short w_Nchannel;
111	unsigned short w_MinConvertTiming;
112	unsigned short w_MinDelayTiming;
113	unsigned char b_HasDma;
114	unsigned char b_Resolution;
115};
116
117
118		/*****************************************/
119		/*            Read Header Functions              */
120		/*****************************************/
121
122int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
123	char *pc_PCIChipInformation, struct comedi_device *dev);
124
125int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
126	char *pc_PCIChipInformation, unsigned short w_Address,
127	struct str_DigitalInputHeader * s_Header);
128
129int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
130	char *pc_PCIChipInformation, unsigned short w_Address,
131	struct str_DigitalOutputHeader * s_Header);
132
133int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
134	char *pc_PCIChipInformation, unsigned short w_Address,
135	struct str_TimerMainHeader * s_Header);
136
137int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
138	char *pc_PCIChipInformation, unsigned short w_Address,
139	str_AnalogOutputHeader * s_Header);
140
141int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
142	char *pc_PCIChipInformation, unsigned short w_Address,
143	struct str_AnalogInputHeader * s_Header);
144
145		/******************************************/
146		/*      Eeprom Specific Functions                         */
147		/******************************************/
148unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
149	unsigned short w_EepromStartAddress);
150void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
151void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue);
152void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
153void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
154	unsigned char b_DataLengthInBits);
155void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value);
156
157/*
158+----------------------------------------------------------------------------+
159| Function   Name   : unsigned short w_EepromReadWord                                  |
160|				(unsigned short	w_PCIBoardEepromAddress,             		 |
161|				 char *	pc_PCIChipInformation,               		 |
162|				 unsigned short   w_EepromStartAddress)                		 |
163+----------------------------------------------------------------------------+
164| Task              : Read from eepromn a word                               |
165+----------------------------------------------------------------------------+
166| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
167|																	 |
168|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
169|																	 |
170|		      unsigned short w_EepromStartAddress    : Selected eeprom address |
171+----------------------------------------------------------------------------+
172| Output Parameters : -                                                      |
173+----------------------------------------------------------------------------+
174| Return Value      : Read word value from eeprom                            |
175+----------------------------------------------------------------------------+
176*/
177
178unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
179	unsigned short w_EepromStartAddress)
180{
181
182	unsigned char b_Counter = 0;
183
184	unsigned char b_ReadByte = 0;
185
186	unsigned char b_ReadLowByte = 0;
187
188	unsigned char b_ReadHighByte = 0;
189
190	unsigned char b_SelectedAddressLow = 0;
191
192	unsigned char b_SelectedAddressHigh = 0;
193
194	unsigned short w_ReadWord = 0;
195
196	/**************************/
197
198	/* Test the PCI chip type */
199
200	/**************************/
201
202	if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
203		(!strcmp(pc_PCIChipInformation, "S5933")))
204	{
205
206		for (b_Counter = 0; b_Counter < 2; b_Counter++)
207		{
208
209			b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256;	/* Read the low 8 bit part */
210
211			b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256;	/* Read the high 8 bit part */
212
213	      /************************************/
214
215			/* Select the load low address mode */
216
217	      /************************************/
218
219			outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
220
221	      /****************/
222
223			/* Wait on busy */
224
225	      /****************/
226
227			v_EepromWaitBusy(w_PCIBoardEepromAddress);
228
229	      /************************/
230
231			/* Load the low address */
232
233	      /************************/
234
235			outb(b_SelectedAddressLow,
236				w_PCIBoardEepromAddress + 0x3E);
237
238	      /****************/
239
240			/* Wait on busy */
241
242	      /****************/
243
244			v_EepromWaitBusy(w_PCIBoardEepromAddress);
245
246	      /*************************************/
247
248			/* Select the load high address mode */
249
250	      /*************************************/
251
252			outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
253
254	      /****************/
255
256			/* Wait on busy */
257
258	      /****************/
259
260			v_EepromWaitBusy(w_PCIBoardEepromAddress);
261
262	      /*************************/
263
264			/* Load the high address */
265
266	      /*************************/
267
268			outb(b_SelectedAddressHigh,
269				w_PCIBoardEepromAddress + 0x3E);
270
271	      /****************/
272
273			/* Wait on busy */
274
275	      /****************/
276
277			v_EepromWaitBusy(w_PCIBoardEepromAddress);
278
279	      /************************/
280
281			/* Select the READ mode */
282
283	      /************************/
284
285			outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
286
287	      /****************/
288
289			/* Wait on busy */
290
291	      /****************/
292
293			v_EepromWaitBusy(w_PCIBoardEepromAddress);
294
295	      /*****************************/
296
297			/* Read data into the EEPROM */
298
299	      /*****************************/
300
301			b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
302
303	      /****************/
304
305			/* Wait on busy */
306
307	      /****************/
308
309			v_EepromWaitBusy(w_PCIBoardEepromAddress);
310
311	      /*********************************/
312
313			/* Select the upper address part */
314
315	      /*********************************/
316
317			if (b_Counter == 0)
318			{
319
320				b_ReadLowByte = b_ReadByte;
321
322			}	/*  if(b_Counter==0) */
323
324			else
325			{
326
327				b_ReadHighByte = b_ReadByte;
328
329			}	/*  if(b_Counter==0) */
330
331		}		/*  for (b_Counter=0; b_Counter<2; b_Counter++) */
332
333		w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256));
334
335	}			/*  end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */
336
337	if (!strcmp(pc_PCIChipInformation, "93C76"))
338	{
339
340	   /*************************************/
341
342		/* Read 16 bit from the EEPROM 93C76 */
343
344	   /*************************************/
345
346		v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
347			&w_ReadWord);
348
349	}
350
351	return (w_ReadWord);
352
353}
354
355/*
356
357+----------------------------------------------------------------------------+
358
359| Function   Name   : void v_EepromWaitBusy                                  |
360
361|			(unsigned short	w_PCIBoardEepromAddress)                    	 |
362
363+----------------------------------------------------------------------------+
364
365| Task              : Wait the busy flag from PCI controller                 |
366
367+----------------------------------------------------------------------------+
368
369| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address |
370
371+----------------------------------------------------------------------------+
372
373| Output Parameters : -                                                      |
374
375+----------------------------------------------------------------------------+
376
377| Return Value      : -                                                      |
378
379+----------------------------------------------------------------------------+
380
381*/
382
383void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress)
384{
385
386	unsigned char b_EepromBusy = 0;
387
388	do
389	{
390
391	   /*************/
392
393		/* IMPORTANT */
394
395	   /*************/
396
397	   /************************************************************************/
398
399		/* An error has been written in the AMCC 5933 book at the page B-13 */
400
401		/* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and   */
402
403		/*      the operator register is AMCC_OP_REG_MCSR+3 */
404
405		/*      unsigned short read  EEPROM=0x8000 andAMCC_OP_REG_MCSR+2                  */
406
407		/*      unsigned int read  EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
408
409	   /************************************************************************/
410
411		b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
412		b_EepromBusy = b_EepromBusy & 0x80;
413
414	}
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
449void 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
520void 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
655void 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
806int 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*/
941int 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*/
986int 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*/
1017int 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
1083int 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 */
1121int 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}
1158