]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
Merge branch 'core/urgent' into core/futexes
[mv-sheeva.git] / drivers / staging / comedi / drivers / addi-data / addi_amcc_S5920.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   | (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
69 INT 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 }