Merge branch 'fix/asoc' into for-linus
[linux-2.6] / drivers / staging / rt2860 / 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 // IRQL = PASSIVE_LEVEL
40 VOID RaiseClock(
41     IN  PRTMP_ADAPTER   pAd,
42     IN  UINT32 *x)
43 {
44     *x = *x | EESK;
45     RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
46     RTMPusecDelay(1);                           // Max frequency = 1MHz in Spec. definition
47 }
48
49 // IRQL = PASSIVE_LEVEL
50 VOID LowerClock(
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);
57 }
58
59 // IRQL = PASSIVE_LEVEL
60 USHORT ShiftInBits(
61     IN  PRTMP_ADAPTER   pAd)
62 {
63     UINT32              x,i;
64         USHORT      data=0;
65
66     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
67
68     x &= ~( EEDO | EEDI);
69
70     for(i=0; i<16; i++)
71     {
72         data = data << 1;
73         RaiseClock(pAd, &x);
74
75         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
76
77         x &= ~(EEDI);
78         if(x & EEDO)
79             data |= 1;
80
81         LowerClock(pAd, &x);
82     }
83
84     return data;
85 }
86
87 // IRQL = PASSIVE_LEVEL
88 VOID ShiftOutBits(
89     IN  PRTMP_ADAPTER   pAd,
90     IN  USHORT data,
91     IN  USHORT count)
92 {
93     UINT32       x,mask;
94
95     mask = 0x01 << (count - 1);
96     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
97
98     x &= ~(EEDO | EEDI);
99
100     do
101     {
102         x &= ~EEDI;
103         if(data & mask)         x |= EEDI;
104
105         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
106
107         RaiseClock(pAd, &x);
108         LowerClock(pAd, &x);
109
110         mask = mask >> 1;
111     } while(mask);
112
113     x &= ~EEDI;
114     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
115 }
116
117 // IRQL = PASSIVE_LEVEL
118 VOID EEpromCleanup(
119     IN  PRTMP_ADAPTER   pAd)
120 {
121     UINT32 x;
122
123     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
124
125     x &= ~(EECS | EEDI);
126     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
127
128     RaiseClock(pAd, &x);
129     LowerClock(pAd, &x);
130 }
131
132 VOID EWEN(
133         IN      PRTMP_ADAPTER   pAd)
134 {
135     UINT32      x;
136
137     // reset bits and set EECS
138     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
139     x &= ~(EEDI | EEDO | EESK);
140     x |= EECS;
141     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
142
143         // kick a pulse
144         RaiseClock(pAd, &x);
145         LowerClock(pAd, &x);
146
147     // output the read_opcode and six pulse in that order
148     ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
149     ShiftOutBits(pAd, 0, 6);
150
151     EEpromCleanup(pAd);
152 }
153
154 VOID EWDS(
155         IN      PRTMP_ADAPTER   pAd)
156 {
157     UINT32      x;
158
159     // reset bits and set EECS
160     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
161     x &= ~(EEDI | EEDO | EESK);
162     x |= EECS;
163     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
164
165         // kick a pulse
166         RaiseClock(pAd, &x);
167         LowerClock(pAd, &x);
168
169     // output the read_opcode and six pulse in that order
170     ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
171     ShiftOutBits(pAd, 0, 6);
172
173     EEpromCleanup(pAd);
174 }
175
176 // IRQL = PASSIVE_LEVEL
177 USHORT RTMP_EEPROM_READ16(
178     IN  PRTMP_ADAPTER   pAd,
179     IN  USHORT Offset)
180 {
181     UINT32              x;
182     USHORT              data;
183
184     Offset /= 2;
185     // reset bits and set EECS
186     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
187     x &= ~(EEDI | EEDO | EESK);
188     x |= EECS;
189     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
190
191         // kick a pulse
192         RaiseClock(pAd, &x);
193         LowerClock(pAd, &x);
194
195     // output the read_opcode and register number in that order
196     ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
197     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
198
199     // Now read the data (16 bits) in from the selected EEPROM word
200     data = ShiftInBits(pAd);
201
202     EEpromCleanup(pAd);
203
204     return data;
205 }       //ReadEEprom
206
207 VOID RTMP_EEPROM_WRITE16(
208     IN  PRTMP_ADAPTER   pAd,
209     IN  USHORT Offset,
210     IN  USHORT Data)
211 {
212     UINT32 x;
213
214         Offset /= 2;
215
216         EWEN(pAd);
217
218     // reset bits and set EECS
219     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
220     x &= ~(EEDI | EEDO | EESK);
221     x |= EECS;
222     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
223
224         // kick a pulse
225         RaiseClock(pAd, &x);
226         LowerClock(pAd, &x);
227
228     // output the read_opcode ,register number and data in that order
229     ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
230     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
231         ShiftOutBits(pAd, Data, 16);            // 16-bit access
232
233     // read DO status
234     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
235
236         EEpromCleanup(pAd);
237
238         RTMPusecDelay(10000);   //delay for twp(MAX)=10ms
239
240         EWDS(pAd);
241
242     EEpromCleanup(pAd);
243 }
244