Merge commit 'v2.6.29-rc1' into timers/hrtimers
[linux-2.6] / drivers / staging / rt2870 / common / eeprom.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         eeprom.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         Name            Date                    Modification logs
36 */
37 #include "../rt_config.h"
38
39 #if 0
40 #define EEPROM_SIZE                                                             0x200
41 #define NVRAM_OFFSET                    0x30000
42 #define RF_OFFSET                               0x40000
43
44 static UCHAR init_flag = 0;
45 static PUCHAR nv_ee_start = 0;
46
47 static UCHAR EeBuffer[EEPROM_SIZE];
48 #endif
49 // IRQL = PASSIVE_LEVEL
50 VOID RaiseClock(
51     IN  PRTMP_ADAPTER   pAd,
52     IN  UINT32 *x)
53 {
54     *x = *x | EESK;
55     RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
56     RTMPusecDelay(1);                           // Max frequency = 1MHz in Spec. definition
57 }
58
59 // IRQL = PASSIVE_LEVEL
60 VOID LowerClock(
61     IN  PRTMP_ADAPTER   pAd,
62     IN  UINT32 *x)
63 {
64     *x = *x & ~EESK;
65     RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
66     RTMPusecDelay(1);
67 }
68
69 // IRQL = PASSIVE_LEVEL
70 USHORT ShiftInBits(
71     IN  PRTMP_ADAPTER   pAd)
72 {
73     UINT32              x,i;
74         USHORT      data=0;
75
76     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
77
78     x &= ~( EEDO | EEDI);
79
80     for(i=0; i<16; i++)
81     {
82         data = data << 1;
83         RaiseClock(pAd, &x);
84
85         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
86
87         x &= ~(EEDI);
88         if(x & EEDO)
89             data |= 1;
90
91         LowerClock(pAd, &x);
92     }
93
94     return data;
95 }
96
97 // IRQL = PASSIVE_LEVEL
98 VOID ShiftOutBits(
99     IN  PRTMP_ADAPTER   pAd,
100     IN  USHORT data,
101     IN  USHORT count)
102 {
103     UINT32       x,mask;
104
105     mask = 0x01 << (count - 1);
106     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
107
108     x &= ~(EEDO | EEDI);
109
110     do
111     {
112         x &= ~EEDI;
113         if(data & mask)         x |= EEDI;
114
115         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
116
117         RaiseClock(pAd, &x);
118         LowerClock(pAd, &x);
119
120         mask = mask >> 1;
121     } while(mask);
122
123     x &= ~EEDI;
124     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
125 }
126
127 // IRQL = PASSIVE_LEVEL
128 VOID EEpromCleanup(
129     IN  PRTMP_ADAPTER   pAd)
130 {
131     UINT32 x;
132
133     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
134
135     x &= ~(EECS | EEDI);
136     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
137
138     RaiseClock(pAd, &x);
139     LowerClock(pAd, &x);
140 }
141
142 VOID EWEN(
143         IN      PRTMP_ADAPTER   pAd)
144 {
145     UINT32      x;
146
147     // reset bits and set EECS
148     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
149     x &= ~(EEDI | EEDO | EESK);
150     x |= EECS;
151     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
152
153         // kick a pulse
154         RaiseClock(pAd, &x);
155         LowerClock(pAd, &x);
156
157     // output the read_opcode and six pulse in that order
158     ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
159     ShiftOutBits(pAd, 0, 6);
160
161     EEpromCleanup(pAd);
162 }
163
164 VOID EWDS(
165         IN      PRTMP_ADAPTER   pAd)
166 {
167     UINT32      x;
168
169     // reset bits and set EECS
170     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
171     x &= ~(EEDI | EEDO | EESK);
172     x |= EECS;
173     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
174
175         // kick a pulse
176         RaiseClock(pAd, &x);
177         LowerClock(pAd, &x);
178
179     // output the read_opcode and six pulse in that order
180     ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
181     ShiftOutBits(pAd, 0, 6);
182
183     EEpromCleanup(pAd);
184 }
185
186 // IRQL = PASSIVE_LEVEL
187 USHORT RTMP_EEPROM_READ16(
188     IN  PRTMP_ADAPTER   pAd,
189     IN  USHORT Offset)
190 {
191     UINT32              x;
192     USHORT              data;
193
194     Offset /= 2;
195     // reset bits and set EECS
196     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
197     x &= ~(EEDI | EEDO | EESK);
198     x |= EECS;
199     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
200
201         // kick a pulse
202         RaiseClock(pAd, &x);
203         LowerClock(pAd, &x);
204
205     // output the read_opcode and register number in that order
206     ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
207     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
208
209     // Now read the data (16 bits) in from the selected EEPROM word
210     data = ShiftInBits(pAd);
211
212     EEpromCleanup(pAd);
213
214     return data;
215 }       //ReadEEprom
216
217 VOID RTMP_EEPROM_WRITE16(
218     IN  PRTMP_ADAPTER   pAd,
219     IN  USHORT Offset,
220     IN  USHORT Data)
221 {
222     UINT32 x;
223
224         Offset /= 2;
225
226         EWEN(pAd);
227
228     // reset bits and set EECS
229     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
230     x &= ~(EEDI | EEDO | EESK);
231     x |= EECS;
232     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
233
234         // kick a pulse
235         RaiseClock(pAd, &x);
236         LowerClock(pAd, &x);
237
238     // output the read_opcode ,register number and data in that order
239     ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
240     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
241         ShiftOutBits(pAd, Data, 16);            // 16-bit access
242
243     // read DO status
244     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
245
246         EEpromCleanup(pAd);
247
248         RTMPusecDelay(10000);   //delay for twp(MAX)=10ms
249
250         EWDS(pAd);
251
252     EEpromCleanup(pAd);
253 }
254