addi_amcc_S5920.c revision c995fe9475e062bab6f5a45ed28cd2d3d955ef43
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  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
27  +-----------------------------------------------------------------------+
28  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
29  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
30  +-------------------------------+---------------------------------------+
31  | Project : ADDI HEADER READ WRITER |     Compiler   : Visual C++       |
32  | Module name : S5920.cpp           |     Version    : 6.0              |
33  +-------------------------------+---------------------------------------+
34  | Author : E. LIBS                      Date : 02/05/2002               |
35  +-----------------------------------------------------------------------+
36  | Description   : DLL with the S5920 PCI Controller functions           |
37  +-----------------------------------------------------------------------+
38  |                             UPDATE'S                                  |
39  +-----------------------------------------------------------------------+
40  |   Date   |   Author  |          Description of updates                |
41  +----------+-----------+------------------------------------------------+
42  | 28/08/02 | LIBS Eric | Add return codes each time a function of the   |
43  |          |           | Addi Library is called                         |
44  +-----------------------------------------------------------------------+
45  | 31/07/03 | KRAUTH J. | Changes for the MSX-Box                        |
46  +-----------------------------------------------------------------------+
47*/
48
49#include "addi_amcc_S5920.h"
50
51/*+----------------------------------------------------------------------------+*/
52/*| Function   Name   : INT i_AddiHeaderRW_ReadEeprom                          |*/
53/*|                               (INT    i_NbOfWordsToRead,                   |*/
54/*|                                DWORD dw_PCIBoardEepromAddress,             |*/
55/*|                                WORD   w_EepromStartAddress,                |*/
56/*|                                PWORD pw_DataRead)                          |*/
57/*+----------------------------------------------------------------------------+*/
58/*| Task              : Read word from the 5920 eeprom.                        |*/
59/*+----------------------------------------------------------------------------+*/
60/*| Input Parameters  : INT    i_NbOfWordsToRead : Nbr. of word to read        |*/
61/*|                     DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
62/*|                     WORD   w_EepromStartAddress : Eeprom strat address     |*/
63/*+----------------------------------------------------------------------------+*/
64/*| Output Parameters : PWORD pw_DataRead : Read data                          |*/
65/*+----------------------------------------------------------------------------+*/
66/*| Return Value      : -                                                      |*/
67/*+----------------------------------------------------------------------------+*/
68
69INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
70	DWORD dw_PCIBoardEepromAddress,
71	WORD w_EepromStartAddress, PWORD pw_DataRead)
72{
73	DWORD dw_eeprom_busy = 0;
74	INT i_Counter = 0;
75	INT i_WordCounter;
76	INT i;
77	BYTE pb_ReadByte[1];
78	BYTE b_ReadLowByte = 0;
79	BYTE b_ReadHighByte = 0;
80	BYTE b_SelectedAddressLow = 0;
81	BYTE b_SelectedAddressHigh = 0;
82	WORD w_ReadWord = 0;
83
84	for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
85		i_WordCounter++) {
86		do {
87			dw_eeprom_busy =
88				inl(dw_PCIBoardEepromAddress +
89				AMCC_OP_REG_MCSR);
90			dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
91		}
92		while (dw_eeprom_busy == EEPROM_BUSY);
93
94		for (i_Counter = 0; i_Counter < 2; i_Counter++) {
95			b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256;	//Read the low 8 bit part
96			b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256;	//Read the high 8 bit part
97
98			//Select the load low address mode
99			outb(NVCMD_LOAD_LOW,
100				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
101				3);
102
103			//Wait on busy
104			do {
105				dw_eeprom_busy =
106					inl(dw_PCIBoardEepromAddress +
107					AMCC_OP_REG_MCSR);
108				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
109			}
110			while (dw_eeprom_busy == EEPROM_BUSY);
111
112			//Load the low address
113			outb(b_SelectedAddressLow,
114				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
115				2);
116
117			//Wait on busy
118			do {
119				dw_eeprom_busy =
120					inl(dw_PCIBoardEepromAddress +
121					AMCC_OP_REG_MCSR);
122				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
123			}
124			while (dw_eeprom_busy == EEPROM_BUSY);
125
126			//Select the load high address mode
127			outb(NVCMD_LOAD_HIGH,
128				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
129				3);
130
131			//Wait on busy
132			do {
133				dw_eeprom_busy =
134					inl(dw_PCIBoardEepromAddress +
135					AMCC_OP_REG_MCSR);
136				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
137			}
138			while (dw_eeprom_busy == EEPROM_BUSY);
139
140			//Load the high address
141			outb(b_SelectedAddressHigh,
142				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
143				2);
144
145			//Wait on busy
146			do {
147				dw_eeprom_busy =
148					inl(dw_PCIBoardEepromAddress +
149					AMCC_OP_REG_MCSR);
150				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
151			}
152			while (dw_eeprom_busy == EEPROM_BUSY);
153
154			//Select the READ mode
155			outb(NVCMD_BEGIN_READ,
156				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
157				3);
158
159			//Wait on busy
160			do {
161				dw_eeprom_busy =
162					inl(dw_PCIBoardEepromAddress +
163					AMCC_OP_REG_MCSR);
164				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
165			}
166			while (dw_eeprom_busy == EEPROM_BUSY);
167
168			//Read data into the EEPROM
169			*pb_ReadByte =
170				inb(dw_PCIBoardEepromAddress +
171				AMCC_OP_REG_MCSR + 2);
172
173			//Wait on busy
174			do {
175				dw_eeprom_busy =
176					inl(dw_PCIBoardEepromAddress +
177					AMCC_OP_REG_MCSR);
178				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
179			}
180			while (dw_eeprom_busy == EEPROM_BUSY);
181
182			//Select the upper address part
183			if (i_Counter == 0) {
184				b_ReadLowByte = pb_ReadByte[0];
185			} else {
186				b_ReadHighByte = pb_ReadByte[0];
187			}
188
189			//Sleep
190			for (i = 0; i < 10000; i++) ;
191
192		}
193		w_ReadWord =
194			(b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
195				256));
196
197		pw_DataRead[i_WordCounter] = w_ReadWord;
198
199		w_EepromStartAddress += 2;	// to read the next word
200
201	}			// for (...) i_NbOfWordsToRead
202	return (0);
203}
204