GNU Linux-libre 4.14.266-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         bool rtstatus = true;
234         struct bb_reg_def *pphyreg;
235
236         pphyreg = &hal_data->PHYRegDef[RF90_PATH_A];
237         u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs, BRFSI_RFENV);
238
239         phy_set_bb_reg(adapt, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
240         udelay(1);
241
242         phy_set_bb_reg(adapt, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
243         udelay(1);
244
245         phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, B3WIREADDREAALENGTH, 0x0);
246         udelay(1);
247
248         phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, B3WIREDATALENGTH, 0x0);
249         udelay(1);
250
251         rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt);
252
253         phy_set_bb_reg(adapt, pphyreg->rfintfs, BRFSI_RFENV, u4val);
254
255         return rtstatus;
256 }
257
258 static bool rtl88e_phy_rf6052_config(struct adapter *adapt)
259 {
260         return rf6052_conf_para(adapt);
261 }
262
263 bool rtl88eu_phy_rf_config(struct adapter *adapt)
264 {
265         return rtl88e_phy_rf6052_config(adapt);
266 }