GNU Linux-libre 4.9.333-gnu1
[releases.git] / drivers / staging / rtl8188eu / hal / rf_cfg.c
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
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
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
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
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
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
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
309 bool rtl88eu_phy_rf_config(struct adapter *adapt)
310 {
311         return rtl88e_phy_rf6052_config(adapt);
312 }