Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
[pandora-kernel.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 should 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 /*|                                unsigned int dw_PCIBoardEepromAddress,             |*/
55 /*|                                unsigned short   w_EepromStartAddress,                |*/
56 /*|                                unsigned short * pw_DataRead)                          |*/
57 /*+----------------------------------------------------------------------------+*/
58 /*| Task              : Read word from the 5920 eeprom.                        |*/
59 /*+----------------------------------------------------------------------------+*/
60 /*| Input Parameters  : int    i_NbOfWordsToRead : Nbr. of word to read        |*/
61 /*|                     unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/
62 /*|                     unsigned short   w_EepromStartAddress : Eeprom strat address     |*/
63 /*+----------------------------------------------------------------------------+*/
64 /*| Output Parameters : unsigned short * pw_DataRead : Read data                          |*/
65 /*+----------------------------------------------------------------------------+*/
66 /*| Return Value      : -                                                      |*/
67 /*+----------------------------------------------------------------------------+*/
68
69 int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
70         unsigned int dw_PCIBoardEepromAddress,
71         unsigned short w_EepromStartAddress, unsigned short *pw_DataRead)
72 {
73         unsigned int dw_eeprom_busy = 0;
74         int i_Counter = 0;
75         int i_WordCounter;
76         int i;
77         unsigned char pb_ReadByte[1];
78         unsigned char b_ReadLowByte = 0;
79         unsigned char b_ReadHighByte = 0;
80         unsigned char b_SelectedAddressLow = 0;
81         unsigned char b_SelectedAddressHigh = 0;
82         unsigned short 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                 } while (dw_eeprom_busy == EEPROM_BUSY);
92
93                 for (i_Counter = 0; i_Counter < 2; i_Counter++) {
94                         b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256;        /* Read the low 8 bit part */
95                         b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256;       /* Read the high 8 bit part */
96
97                         /* Select the load low address mode */
98                         outb(NVCMD_LOAD_LOW,
99                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
100                                 3);
101
102                         /* Wait on busy */
103                         do {
104                                 dw_eeprom_busy =
105                                         inl(dw_PCIBoardEepromAddress +
106                                         AMCC_OP_REG_MCSR);
107                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
108                         } while (dw_eeprom_busy == EEPROM_BUSY);
109
110                         /* Load the low address */
111                         outb(b_SelectedAddressLow,
112                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
113                                 2);
114
115                         /* Wait on busy */
116                         do {
117                                 dw_eeprom_busy =
118                                         inl(dw_PCIBoardEepromAddress +
119                                         AMCC_OP_REG_MCSR);
120                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
121                         } while (dw_eeprom_busy == EEPROM_BUSY);
122
123                         /* Select the load high address mode */
124                         outb(NVCMD_LOAD_HIGH,
125                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
126                                 3);
127
128                         /* Wait on busy */
129                         do {
130                                 dw_eeprom_busy =
131                                         inl(dw_PCIBoardEepromAddress +
132                                         AMCC_OP_REG_MCSR);
133                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
134                         } while (dw_eeprom_busy == EEPROM_BUSY);
135
136                         /* Load the high address */
137                         outb(b_SelectedAddressHigh,
138                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
139                                 2);
140
141                         /* Wait on busy */
142                         do {
143                                 dw_eeprom_busy =
144                                         inl(dw_PCIBoardEepromAddress +
145                                         AMCC_OP_REG_MCSR);
146                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
147                         } while (dw_eeprom_busy == EEPROM_BUSY);
148
149                         /* Select the READ mode */
150                         outb(NVCMD_BEGIN_READ,
151                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
152                                 3);
153
154                         /* Wait on busy */
155                         do {
156                                 dw_eeprom_busy =
157                                         inl(dw_PCIBoardEepromAddress +
158                                         AMCC_OP_REG_MCSR);
159                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
160                         } while (dw_eeprom_busy == EEPROM_BUSY);
161
162                         /* Read data into the EEPROM */
163                         *pb_ReadByte =
164                                 inb(dw_PCIBoardEepromAddress +
165                                 AMCC_OP_REG_MCSR + 2);
166
167                         /* Wait on busy */
168                         do {
169                                 dw_eeprom_busy =
170                                         inl(dw_PCIBoardEepromAddress +
171                                         AMCC_OP_REG_MCSR);
172                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
173                         } while (dw_eeprom_busy == EEPROM_BUSY);
174
175                         /* Select the upper address part */
176                         if (i_Counter == 0)
177                                 b_ReadLowByte = pb_ReadByte[0];
178                         else
179                                 b_ReadHighByte = pb_ReadByte[0];
180
181                         /* Sleep */
182                         msleep(1);
183
184                 }
185                 w_ReadWord =
186                         (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
187                                 256));
188
189                 pw_DataRead[i_WordCounter] = w_ReadWord;
190
191                 w_EepromStartAddress += 2;      /*  to read the next word */
192
193         }                       /*  for (...) i_NbOfWordsToRead */
194         return 0;
195 }