]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/rt2860/common/ee_prom.c
Staging: rt28x0: run common/*.c files through Lindent
[net-next-2.6.git] / drivers / staging / rt2860 / common / ee_prom.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         ee_prom.c
29
30         Abstract:
31         Miniport generic portion header file
32
33         Revision History:
34         Who         When          What
35         --------    ----------    ----------------------------------------------
36 */
37
38 #include        "../rt_config.h"
39
40 // IRQL = PASSIVE_LEVEL
41 static inline VOID RaiseClock(IN PRTMP_ADAPTER pAd, IN UINT32 * x)
42 {
43         *x = *x | EESK;
44         RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
45         RTMPusecDelay(1);       // Max frequency = 1MHz in Spec. definition
46 }
47
48 // IRQL = PASSIVE_LEVEL
49 static inline VOID LowerClock(IN PRTMP_ADAPTER pAd, IN UINT32 * x)
50 {
51         *x = *x & ~EESK;
52         RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
53         RTMPusecDelay(1);
54 }
55
56 // IRQL = PASSIVE_LEVEL
57 static inline USHORT ShiftInBits(IN PRTMP_ADAPTER pAd)
58 {
59         UINT32 x, i;
60         USHORT data = 0;
61
62         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
63
64         x &= ~(EEDO | EEDI);
65
66         for (i = 0; i < 16; i++) {
67                 data = data << 1;
68                 RaiseClock(pAd, &x);
69
70                 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
71                 LowerClock(pAd, &x);    //prevent read failed
72
73                 x &= ~(EEDI);
74                 if (x & EEDO)
75                         data |= 1;
76         }
77
78         return data;
79 }
80
81 // IRQL = PASSIVE_LEVEL
82 static inline VOID ShiftOutBits(IN PRTMP_ADAPTER pAd,
83                                 IN USHORT data, IN USHORT count)
84 {
85         UINT32 x, mask;
86
87         mask = 0x01 << (count - 1);
88         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
89
90         x &= ~(EEDO | EEDI);
91
92         do {
93                 x &= ~EEDI;
94                 if (data & mask)
95                         x |= EEDI;
96
97                 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
98
99                 RaiseClock(pAd, &x);
100                 LowerClock(pAd, &x);
101
102                 mask = mask >> 1;
103         } while (mask);
104
105         x &= ~EEDI;
106         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
107 }
108
109 // IRQL = PASSIVE_LEVEL
110 static inline VOID EEpromCleanup(IN PRTMP_ADAPTER pAd)
111 {
112         UINT32 x;
113
114         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
115
116         x &= ~(EECS | EEDI);
117         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
118
119         RaiseClock(pAd, &x);
120         LowerClock(pAd, &x);
121 }
122
123 static inline VOID EWEN(IN PRTMP_ADAPTER pAd)
124 {
125         UINT32 x;
126
127         // reset bits and set EECS
128         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
129         x &= ~(EEDI | EEDO | EESK);
130         x |= EECS;
131         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
132
133         // kick a pulse
134         RaiseClock(pAd, &x);
135         LowerClock(pAd, &x);
136
137         // output the read_opcode and six pulse in that order
138         ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
139         ShiftOutBits(pAd, 0, 6);
140
141         EEpromCleanup(pAd);
142 }
143
144 static inline VOID EWDS(IN PRTMP_ADAPTER pAd)
145 {
146         UINT32 x;
147
148         // reset bits and set EECS
149         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
150         x &= ~(EEDI | EEDO | EESK);
151         x |= EECS;
152         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
153
154         // kick a pulse
155         RaiseClock(pAd, &x);
156         LowerClock(pAd, &x);
157
158         // output the read_opcode and six pulse in that order
159         ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
160         ShiftOutBits(pAd, 0, 6);
161
162         EEpromCleanup(pAd);
163 }
164
165 // IRQL = PASSIVE_LEVEL
166 int rtmp_ee_prom_read16(IN PRTMP_ADAPTER pAd,
167                         IN USHORT Offset, OUT USHORT * pValue)
168 {
169         UINT32 x;
170         USHORT data;
171
172         Offset /= 2;
173         // reset bits and set EECS
174         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
175         x &= ~(EEDI | EEDO | EESK);
176         x |= EECS;
177         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
178
179         // patch can not access e-Fuse issue
180         if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
181                 // kick a pulse
182                 RaiseClock(pAd, &x);
183                 LowerClock(pAd, &x);
184         }
185         // output the read_opcode and register number in that order
186         ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
187         ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
188
189         // Now read the data (16 bits) in from the selected EEPROM word
190         data = ShiftInBits(pAd);
191
192         EEpromCleanup(pAd);
193
194         *pValue = data;
195
196         return NDIS_STATUS_SUCCESS;
197 }