1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15
16 #include "odm_precomp.h"
17
18 #include <phy.h>
19
check_condition(struct adapter * adapt,const u32 condition)20 static bool check_condition(struct adapter *adapt, const u32 condition)
21 {
22 struct odm_dm_struct *odm = &adapt->HalData->odmpriv;
23 u32 _board = odm->BoardType;
24 u32 _platform = odm->SupportPlatform;
25 u32 _interface = odm->SupportInterface;
26 u32 cond = condition;
27
28 if (condition == 0xCDCDCDCD)
29 return true;
30
31 cond = condition & 0x000000FF;
32 if ((_board == cond) && cond != 0x00)
33 return false;
34
35 cond = condition & 0x0000FF00;
36 cond >>= 8;
37 if ((_interface & cond) == 0 && cond != 0x07)
38 return false;
39
40 cond = condition & 0x00FF0000;
41 cond >>= 16;
42 if ((_platform & cond) == 0 && cond != 0x0F)
43 return false;
44 return true;
45 }
46
47 /* RadioA_1T.TXT */
48
49 static u32 Array_RadioA_1T_8188E[] = {
50 0x000, 0x00030000,
51 0x008, 0x00084000,
52 0x018, 0x00000407,
53 0x019, 0x00000012,
54 0x01E, 0x00080009,
55 0x01F, 0x00000880,
56 0x02F, 0x0001A060,
57 0x03F, 0x00000000,
58 0x042, 0x000060C0,
59 0x057, 0x000D0000,
60 0x058, 0x000BE180,
61 0x067, 0x00001552,
62 0x083, 0x00000000,
63 0x0B0, 0x000FF8FC,
64 0x0B1, 0x00054400,
65 0x0B2, 0x000CCC19,
66 0x0B4, 0x00043003,
67 0x0B6, 0x0004953E,
68 0x0B7, 0x0001C718,
69 0x0B8, 0x000060FF,
70 0x0B9, 0x00080001,
71 0x0BA, 0x00040000,
72 0x0BB, 0x00000400,
73 0x0BF, 0x000C0000,
74 0x0C2, 0x00002400,
75 0x0C3, 0x00000009,
76 0x0C4, 0x00040C91,
77 0x0C5, 0x00099999,
78 0x0C6, 0x000000A3,
79 0x0C7, 0x00088820,
80 0x0C8, 0x00076C06,
81 0x0C9, 0x00000000,
82 0x0CA, 0x00080000,
83 0x0DF, 0x00000180,
84 0x0EF, 0x000001A0,
85 0x051, 0x0006B27D,
86 0xFF0F041F, 0xABCD,
87 0x052, 0x0007E4DD,
88 0xCDCDCDCD, 0xCDCD,
89 0x052, 0x0007E49D,
90 0xFF0F041F, 0xDEAD,
91 0x053, 0x00000073,
92 0x056, 0x00051FF3,
93 0x035, 0x00000086,
94 0x035, 0x00000186,
95 0x035, 0x00000286,
96 0x036, 0x00001C25,
97 0x036, 0x00009C25,
98 0x036, 0x00011C25,
99 0x036, 0x00019C25,
100 0x0B6, 0x00048538,
101 0x018, 0x00000C07,
102 0x05A, 0x0004BD00,
103 0x019, 0x000739D0,
104 0x034, 0x0000ADF3,
105 0x034, 0x00009DF0,
106 0x034, 0x00008DED,
107 0x034, 0x00007DEA,
108 0x034, 0x00006DE7,
109 0x034, 0x000054EE,
110 0x034, 0x000044EB,
111 0x034, 0x000034E8,
112 0x034, 0x0000246B,
113 0x034, 0x00001468,
114 0x034, 0x0000006D,
115 0x000, 0x00030159,
116 0x084, 0x00068200,
117 0x086, 0x000000CE,
118 0x087, 0x00048A00,
119 0x08E, 0x00065540,
120 0x08F, 0x00088000,
121 0x0EF, 0x000020A0,
122 0x03B, 0x000F02B0,
123 0x03B, 0x000EF7B0,
124 0x03B, 0x000D4FB0,
125 0x03B, 0x000CF060,
126 0x03B, 0x000B0090,
127 0x03B, 0x000A0080,
128 0x03B, 0x00090080,
129 0x03B, 0x0008F780,
130 0x03B, 0x000722B0,
131 0x03B, 0x0006F7B0,
132 0x03B, 0x00054FB0,
133 0x03B, 0x0004F060,
134 0x03B, 0x00030090,
135 0x03B, 0x00020080,
136 0x03B, 0x00010080,
137 0x03B, 0x0000F780,
138 0x0EF, 0x000000A0,
139 0x000, 0x00010159,
140 0x018, 0x0000F407,
141 0xFFE, 0x00000000,
142 0xFFE, 0x00000000,
143 0x01F, 0x00080003,
144 0xFFE, 0x00000000,
145 0xFFE, 0x00000000,
146 0x01E, 0x00000001,
147 0x01F, 0x00080000,
148 0x000, 0x00033E60,
149 };
150
151 #define READ_NEXT_PAIR(v1, v2, i) \
152 do { \
153 i += 2; v1 = array[i]; \
154 v2 = array[i+1]; \
155 } while (0)
156
157 #define RFREG_OFFSET_MASK 0xfffff
158 #define B3WIREADDREAALENGTH 0x400
159 #define B3WIREDATALENGTH 0x800
160 #define BRFSI_RFENV 0x10
161
rtl_rfreg_delay(struct adapter * adapt,enum rf_radio_path rfpath,u32 addr,u32 mask,u32 data)162 static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u32 addr, u32 mask, u32 data)
163 {
164 if (addr == 0xfe) {
165 mdelay(50);
166 } else if (addr == 0xfd) {
167 mdelay(5);
168 } else if (addr == 0xfc) {
169 mdelay(1);
170 } else if (addr == 0xfb) {
171 udelay(50);
172 } else if (addr == 0xfa) {
173 udelay(5);
174 } else if (addr == 0xf9) {
175 udelay(1);
176 } else {
177 phy_set_rf_reg(adapt, rfpath, addr, mask, data);
178 udelay(1);
179 }
180 }
181
rtl8188e_config_rf_reg(struct adapter * adapt,u32 addr,u32 data)182 static void rtl8188e_config_rf_reg(struct adapter *adapt,
183 u32 addr, u32 data)
184 {
185 u32 content = 0x1000; /*RF Content: radio_a_txt*/
186 u32 maskforphyset = content & 0xE000;
187
188 rtl_rfreg_delay(adapt, RF90_PATH_A, addr | maskforphyset,
189 RFREG_OFFSET_MASK,
190 data);
191 }
192
rtl88e_phy_config_rf_with_headerfile(struct adapter * adapt)193 static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt)
194 {
195 u32 i;
196 u32 array_len = ARRAY_SIZE(Array_RadioA_1T_8188E);
197 u32 *array = Array_RadioA_1T_8188E;
198
199 for (i = 0; i < array_len; i += 2) {
200 u32 v1 = array[i];
201 u32 v2 = array[i+1];
202
203 if (v1 < 0xCDCDCDCD) {
204 rtl8188e_config_rf_reg(adapt, v1, v2);
205 continue;
206 } else {
207 if (!check_condition(adapt, array[i])) {
208 READ_NEXT_PAIR(v1, v2, i);
209 while (v2 != 0xDEAD && v2 != 0xCDEF &&
210 v2 != 0xCDCD && i < array_len - 2)
211 READ_NEXT_PAIR(v1, v2, i);
212 i -= 2;
213 } else {
214 READ_NEXT_PAIR(v1, v2, i);
215 while (v2 != 0xDEAD && v2 != 0xCDEF &&
216 v2 != 0xCDCD && i < array_len - 2) {
217 rtl8188e_config_rf_reg(adapt, v1, v2);
218 READ_NEXT_PAIR(v1, v2, i);
219 }
220
221 while (v2 != 0xDEAD && i < array_len - 2)
222 READ_NEXT_PAIR(v1, v2, i);
223 }
224 }
225 }
226 return true;
227 }
228
rf6052_conf_para(struct adapter * adapt)229 static bool rf6052_conf_para(struct adapter *adapt)
230 {
231 struct hal_data_8188e *hal_data = adapt->HalData;
232 u32 u4val = 0;
233 u8 rfpath;
234 bool rtstatus = true;
235 struct bb_reg_def *pphyreg;
236
237 for (rfpath = 0; rfpath < hal_data->NumTotalRFPath; rfpath++) {
238 pphyreg = &hal_data->PHYRegDef[rfpath];
239
240 switch (rfpath) {
241 case RF90_PATH_A:
242 case RF90_PATH_C:
243 u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs,
244 BRFSI_RFENV);
245 break;
246 case RF90_PATH_B:
247 case RF90_PATH_D:
248 u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs,
249 BRFSI_RFENV << 16);
250 break;
251 }
252
253 phy_set_bb_reg(adapt, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
254 udelay(1);
255
256 phy_set_bb_reg(adapt, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
257 udelay(1);
258
259 phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2,
260 B3WIREADDREAALENGTH, 0x0);
261 udelay(1);
262
263 phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2,
264 B3WIREDATALENGTH, 0x0);
265 udelay(1);
266
267 switch (rfpath) {
268 case RF90_PATH_A:
269 rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt);
270 break;
271 case RF90_PATH_B:
272 rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt);
273 break;
274 case RF90_PATH_C:
275 break;
276 case RF90_PATH_D:
277 break;
278 }
279
280 switch (rfpath) {
281 case RF90_PATH_A:
282 case RF90_PATH_C:
283 phy_set_bb_reg(adapt, pphyreg->rfintfs,
284 BRFSI_RFENV, u4val);
285 break;
286 case RF90_PATH_B:
287 case RF90_PATH_D:
288 phy_set_bb_reg(adapt, pphyreg->rfintfs,
289 BRFSI_RFENV << 16, u4val);
290 break;
291 }
292
293 if (!rtstatus)
294 return false;
295 }
296
297 return rtstatus;
298 }
299
rtl88e_phy_rf6052_config(struct adapter * adapt)300 static bool rtl88e_phy_rf6052_config(struct adapter *adapt)
301 {
302 struct hal_data_8188e *hal_data = adapt->HalData;
303
304 hal_data->NumTotalRFPath = 1;
305
306 return rf6052_conf_para(adapt);
307 }
308
rtl88eu_phy_rf_config(struct adapter * adapt)309 bool rtl88eu_phy_rf_config(struct adapter *adapt)
310 {
311 return rtl88e_phy_rf6052_config(adapt);
312 }
313