1
2
3
4#include "../include/drv_types.h"
5
6
7
8#define ODM_TXPWRTRACK_MAX_IDX_88E 6
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,
34 u8 *pDirection,
35 u32 *pOutWriteVal
36 )
37{
38 u8 pwr_value = 0;
39
40
41 if (Type == 0) {
42 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
43 *pDirection = 1;
44 pwr_value = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm);
45 } else {
46 *pDirection = 2;
47 pwr_value = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase);
48 }
49 } else if (Type == 1) {
50 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
51 *pDirection = 1;
52 pwr_value = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck);
53 } else {
54 *pDirection = 2;
55 pwr_value = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase);
56 }
57 }
58
59
60
61
62
63 if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1)
64 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
65
66 *pOutWriteVal = pwr_value | (pwr_value << 8) | (pwr_value << 16) | (pwr_value << 24);
67}
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
87{
88 if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
89 PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *dm_odm->pChannel);
90 dm_odm->BbSwingFlagOfdm = false;
91 dm_odm->BbSwingFlagCck = false;
92 }
93}
94
95
96void
97odm_TXPowerTrackingCallback_ThermalMeter_8188E(
98 struct adapter *Adapter
99 )
100{
101 struct hal_data_8188e *pHalData = &Adapter->haldata;
102 u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset;
103 u8 ThermalValue_AVG_count = 0;
104 u32 ThermalValue_AVG = 0;
105 s32 ele_A = 0, ele_D, TempCCk, X, value32;
106 s32 Y, ele_C = 0;
107 s8 OFDM_index[2], CCK_index = 0;
108 s8 OFDM_index_old[2] = {0, 0}, CCK_index_old = 0;
109 u32 i = 0, j = 0;
110 bool is2t = false;
111
112 u8 OFDM_min_index = 6, rf;
113 s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = {
114 {0, 0, 2, 3, 4, 4,
115 5, 6, 7, 7, 8, 9,
116 10, 10, 11},
117 {0, 0, -1, -2, -3, -4,
118 -4, -4, -4, -5, -7, -8,
119 -9, -9, -10},
120 };
121 u8 Thermal_mapping[2][index_mapping_NUM_88E] = {
122 {0, 2, 4, 6, 8, 10,
123 12, 14, 16, 18, 20, 22,
124 24, 26, 27},
125 {0, 2, 4, 6, 8, 10,
126 12, 14, 16, 18, 20, 22,
127 25, 25, 25},
128 };
129 struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
130
131
132 odm_TxPwrTrackSetPwr88E(dm_odm);
133
134 dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
135 dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
136
137
138 dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
139
140 ThermalValue = (u8)rtl8188e_PHY_QueryRFReg(Adapter, RF_PATH_A, RF_T_METER_88E, 0xfc00);
141
142 if (is2t)
143 rf = 2;
144 else
145 rf = 1;
146
147 if (ThermalValue) {
148
149 ele_D = rtl8188e_PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord) & bMaskOFDM_D;
150 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
151 if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) {
152 OFDM_index_old[0] = (u8)i;
153 dm_odm->BbSwingIdxOfdmBase = (u8)i;
154 break;
155 }
156 }
157
158
159 if (is2t) {
160 ele_D = rtl8188e_PHY_QueryBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord) & bMaskOFDM_D;
161 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
162 if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) {
163 OFDM_index_old[1] = (u8)i;
164 break;
165 }
166 }
167 }
168
169
170 TempCCk = dm_odm->RFCalibrateInfo.RegA24;
171
172 for (i = 0; i < CCK_TABLE_SIZE; i++) {
173 if (dm_odm->RFCalibrateInfo.bCCKinCH14) {
174 if (memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4)) {
175 CCK_index_old = (u8)i;
176 dm_odm->BbSwingIdxCckBase = (u8)i;
177 break;
178 }
179 } else {
180 if (memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4)) {
181 CCK_index_old = (u8)i;
182 dm_odm->BbSwingIdxCckBase = (u8)i;
183 break;
184 }
185 }
186 }
187
188 if (!dm_odm->RFCalibrateInfo.ThermalValue) {
189 dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
190 dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
191 dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
192
193 for (i = 0; i < rf; i++)
194 dm_odm->RFCalibrateInfo.OFDM_index[i] = OFDM_index_old[i];
195 dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old;
196 }
197
198
199 dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
200 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
201 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
202 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
203
204 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
205 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
206 ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
207 ThermalValue_AVG_count++;
208 }
209 }
210
211 if (ThermalValue_AVG_count)
212 ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
213
214 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
215 delta = ThermalValue > pHalData->EEPROMThermalMeter ?
216 (ThermalValue - pHalData->EEPROMThermalMeter) :
217 (pHalData->EEPROMThermalMeter - ThermalValue);
218 dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
219 dm_odm->RFCalibrateInfo.bDoneTxpower = false;
220 } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) {
221 delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ?
222 (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) :
223 (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue);
224 } else {
225 delta = ThermalValue > pHalData->EEPROMThermalMeter ?
226 (ThermalValue - pHalData->EEPROMThermalMeter) :
227 (pHalData->EEPROMThermalMeter - ThermalValue);
228 }
229 delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ?
230 (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) :
231 (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
232 delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ?
233 (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) :
234 (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
235
236 if ((delta_LCK >= 8)) {
237 dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
238 PHY_LCCalibrate_8188E(Adapter);
239 }
240
241 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
242 delta = ThermalValue > pHalData->EEPROMThermalMeter ?
243 (ThermalValue - pHalData->EEPROMThermalMeter) :
244 (pHalData->EEPROMThermalMeter - ThermalValue);
245
246 if (ThermalValue > pHalData->EEPROMThermalMeter)
247 j = 1;
248 else
249 j = 0;
250 for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
251 if (delta < Thermal_mapping[j][offset]) {
252 if (offset != 0)
253 offset--;
254 break;
255 }
256 }
257 if (offset >= index_mapping_NUM_88E)
258 offset = index_mapping_NUM_88E - 1;
259 for (i = 0; i < rf; i++)
260 OFDM_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + OFDM_index_mapping[j][offset];
261 CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset];
262
263 for (i = 0; i < rf; i++) {
264 if (OFDM_index[i] > OFDM_TABLE_SIZE_92D - 1)
265 OFDM_index[i] = OFDM_TABLE_SIZE_92D - 1;
266 else if (OFDM_index[i] < OFDM_min_index)
267 OFDM_index[i] = OFDM_min_index;
268 }
269
270 if (CCK_index > CCK_TABLE_SIZE - 1)
271 CCK_index = CCK_TABLE_SIZE - 1;
272 else if (CCK_index < 0)
273 CCK_index = 0;
274
275
276
277 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
278 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
279
280
281 ele_D = (OFDMSwingTable[(u8)OFDM_index[0]] & 0xFFC00000) >> 22;
282 X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][0];
283 Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][1];
284
285
286 dm_odm->BbSwingIdxOfdm = (u8)OFDM_index[0];
287 dm_odm->BbSwingIdxCck = (u8)CCK_index;
288
289 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
290 dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
291 dm_odm->BbSwingFlagOfdm = true;
292 }
293
294 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
295 dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
296 dm_odm->BbSwingFlagCck = true;
297 }
298
299 if (X != 0) {
300 if ((X & 0x00000200) != 0)
301 X = X | 0xFFFFFC00;
302 ele_A = ((X * ele_D) >> 8) & 0x000003FF;
303
304
305 if ((Y & 0x00000200) != 0)
306 Y = Y | 0xFFFFFC00;
307 ele_C = ((Y * ele_D) >> 8) & 0x000003FF;
308
309
310
311 }
312
313 if (is2t) {
314 ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000) >> 22;
315
316
317 X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][4];
318 Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][5];
319
320 if (X != 0) {
321 if ((X & 0x00000200) != 0)
322 X = X | 0xFFFFFC00;
323 ele_A = ((X * ele_D) >> 8) & 0x000003FF;
324
325
326 if ((Y & 0x00000200) != 0)
327 Y = Y | 0xFFFFFC00;
328 ele_C = ((Y * ele_D) >> 8) & 0x00003FF;
329
330
331 value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
332 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
333
334 value32 = (ele_C & 0x000003C0) >> 6;
335 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
336
337 value32 = ((X * ele_D) >> 7) & 0x01;
338 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT(28), value32);
339 } else {
340 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)OFDM_index[1]]);
341 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
342 rtl8188e_PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT(28), 0x00);
343 }
344 }
345 }
346 }
347
348 if (delta_IQK >= 8) {
349 dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
350 PHY_IQCalibrate_8188E(Adapter, false);
351 }
352
353 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
354 dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue;
355 }
356 dm_odm->RFCalibrateInfo.TXPowercount = 0;
357}
358
359
360#define MAX_TOLERANCE 5
361#define IQK_DELAY_TIME 1
362
363static u8
364phy_PathA_IQK_8188E(struct adapter *adapt)
365{
366 u32 regeac, regE94, regE9C;
367 u8 result = 0x00;
368
369
370
371 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
372 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
373 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
374 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
375
376
377 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
378
379
380 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
381 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
382
383
384
385 mdelay(IQK_DELAY_TIME_88E);
386
387
388 regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
389 regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
390 regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
391
392 if (!(regeac & BIT(28)) &&
393 (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
394 (((regE9C & 0x03FF0000) >> 16) != 0x42))
395 result |= 0x01;
396 return result;
397}
398
399static u8
400phy_PathA_RxIQK(struct adapter *adapt)
401{
402 u32 regeac, regE94, regE9C, regEA4, u4tmp;
403 u8 result = 0x00;
404
405
406
407 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
408 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
409 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
410 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
411 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
412
413
414 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
415 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
416
417 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
418
419
420 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
421 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
422
423
424 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
425 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
426 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
427 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
428
429
430 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
431
432
433 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
434 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
435
436
437 mdelay(IQK_DELAY_TIME_88E);
438
439
440 regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
441 regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
442 regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
443
444 if (!(regeac & BIT(28)) &&
445 (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
446 (((regE9C & 0x03FF0000) >> 16) != 0x42))
447 result |= 0x01;
448 else
449 return result;
450
451 u4tmp = 0x80007C00 | (regE94 & 0x3FF0000) | ((regE9C & 0x3FF0000) >> 16);
452 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, u4tmp);
453
454
455
456 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
457 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
458 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
459 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
460 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
461 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
462
463
464 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
465
466
467 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
468 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
469 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
470 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
471
472
473 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
474
475
476 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
477 rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
478
479
480
481 mdelay(IQK_DELAY_TIME_88E);
482
483
484 regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
485 regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
486 regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
487 regEA4 = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
488
489
490 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
491 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
492
493 if (!(regeac & BIT(27)) &&
494 (((regEA4 & 0x03FF0000) >> 16) != 0x132) &&
495 (((regeac & 0x03FF0000) >> 16) != 0x36))
496 result |= 0x02;
497
498 return result;
499}
500
501static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
502{
503 u32 Oldval_0, X, TX0_A, reg;
504 s32 Y, TX0_C;
505
506 if (final_candidate == 0xFF) {
507 return;
508 } else if (iqkok) {
509 Oldval_0 = (rtl8188e_PHY_QueryBBReg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
510
511 X = result[final_candidate][0];
512 if ((X & 0x00000200) != 0)
513 X = X | 0xFFFFFC00;
514 TX0_A = (X * Oldval_0) >> 8;
515 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
516
517 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1));
518
519 Y = result[final_candidate][1];
520 if ((Y & 0x00000200) != 0)
521 Y = Y | 0xFFFFFC00;
522
523 TX0_C = (Y * Oldval_0) >> 8;
524 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6));
525 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F));
526
527 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1));
528
529 if (txonly)
530 return;
531
532 reg = result[final_candidate][2];
533 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
534
535 reg = result[final_candidate][3] & 0x3F;
536 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
537
538 reg = (result[final_candidate][3] >> 6) & 0xF;
539 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
540 }
541}
542
543void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum)
544{
545 u32 i;
546
547 for (i = 0; i < RegisterNum; i++) {
548 ADDABackup[i] = rtl8188e_PHY_QueryBBReg(adapt, ADDAReg[i], bMaskDWord);
549 }
550}
551
552static void _PHY_SaveMACRegisters(
553 struct adapter *adapt,
554 u32 *MACReg,
555 u32 *MACBackup
556 )
557{
558 u32 i;
559
560 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
561 MACBackup[i] = rtw_read8(adapt, MACReg[i]);
562
563 MACBackup[i] = rtw_read32(adapt, MACReg[i]);
564}
565
566static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
567{
568 u32 i;
569
570 for (i = 0; i < RegiesterNum; i++)
571 rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, ADDABackup[i]);
572}
573
574static void
575_PHY_ReloadMACRegisters(
576 struct adapter *adapt,
577 u32 *MACReg,
578 u32 *MACBackup
579 )
580{
581 u32 i;
582
583 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
584 rtw_write8(adapt, MACReg[i], (u8)MACBackup[i]);
585
586 rtw_write32(adapt, MACReg[i], MACBackup[i]);
587}
588
589static void
590_PHY_PathADDAOn(
591 struct adapter *adapt,
592 u32 *ADDAReg)
593{
594 u32 i;
595
596 rtl8188e_PHY_SetBBReg(adapt, ADDAReg[0], bMaskDWord, 0x0b1b25a0);
597
598 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
599 rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, 0x0bdb25a0);
600}
601
602void
603_PHY_MACSettingCalibration(
604 struct adapter *adapt,
605 u32 *MACReg,
606 u32 *MACBackup
607 )
608{
609 u32 i = 0;
610
611 rtw_write8(adapt, MACReg[i], 0x3F);
612
613 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
614 rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(3))));
615
616 rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(5))));
617}
618
619static void _PHY_PIModeSwitch(
620 struct adapter *adapt,
621 bool PIMode
622 )
623{
624 u32 mode;
625
626 mode = PIMode ? 0x01000100 : 0x01000000;
627 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
628 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
629}
630
631static bool phy_SimularityCompare_8188E(
632 struct adapter *adapt,
633 s32 resulta[][8],
634 u8 c1,
635 u8 c2
636 )
637{
638 u32 i, j, diff, sim_bitmap, bound = 0;
639 u8 final_candidate[2] = {0xFF, 0xFF};
640 bool result = true;
641 s32 tmp1 = 0, tmp2 = 0;
642
643 bound = 4;
644 sim_bitmap = 0;
645
646 for (i = 0; i < bound; i++) {
647 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
648 if ((resulta[c1][i] & 0x00000200) != 0)
649 tmp1 = resulta[c1][i] | 0xFFFFFC00;
650 else
651 tmp1 = resulta[c1][i];
652
653 if ((resulta[c2][i] & 0x00000200) != 0)
654 tmp2 = resulta[c2][i] | 0xFFFFFC00;
655 else
656 tmp2 = resulta[c2][i];
657 } else {
658 tmp1 = resulta[c1][i];
659 tmp2 = resulta[c2][i];
660 }
661
662 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
663
664 if (diff > MAX_TOLERANCE) {
665 if ((i == 2 || i == 6) && !sim_bitmap) {
666 if (resulta[c1][i] + resulta[c1][i + 1] == 0)
667 final_candidate[(i / 4)] = c2;
668 else if (resulta[c2][i] + resulta[c2][i + 1] == 0)
669 final_candidate[(i / 4)] = c1;
670 else
671 sim_bitmap = sim_bitmap | (1 << i);
672 } else {
673 sim_bitmap = sim_bitmap | (1 << i);
674 }
675 }
676 }
677
678 if (sim_bitmap == 0) {
679 for (i = 0; i < (bound / 4); i++) {
680 if (final_candidate[i] != 0xFF) {
681 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
682 resulta[3][j] = resulta[final_candidate[i]][j];
683 result = false;
684 }
685 }
686 return result;
687 } else {
688 if (!(sim_bitmap & 0x03)) {
689 for (i = 0; i < 2; i++)
690 resulta[3][i] = resulta[c1][i];
691 }
692 if (!(sim_bitmap & 0x0c)) {
693 for (i = 2; i < 4; i++)
694 resulta[3][i] = resulta[c1][i];
695 }
696
697 if (!(sim_bitmap & 0x30)) {
698 for (i = 4; i < 6; i++)
699 resulta[3][i] = resulta[c1][i];
700 }
701
702 if (!(sim_bitmap & 0xc0)) {
703 for (i = 6; i < 8; i++)
704 resulta[3][i] = resulta[c1][i];
705 }
706 return false;
707 }
708}
709
710static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t)
711{
712 struct hal_data_8188e *pHalData = &adapt->haldata;
713 struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
714 u32 i;
715 u8 PathAOK;
716 u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
717 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
718 rRx_Wait_CCA, rTx_CCK_RFON,
719 rTx_CCK_BBON, rTx_OFDM_RFON,
720 rTx_OFDM_BBON, rTx_To_Rx,
721 rTx_To_Tx, rRx_CCK,
722 rRx_OFDM, rRx_Wait_RIFS,
723 rRx_TO_Rx, rStandby,
724 rSleep, rPMPD_ANAEN };
725 u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
726 REG_TXPAUSE, REG_BCN_CTRL,
727 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
728
729
730 u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
731 rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
732 rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
733 rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
734 rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD
735 };
736 u32 retryCount = 2;
737
738
739
740 if (t == 0) {
741
742 _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
743 _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
744 _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
745 }
746
747 _PHY_PathADDAOn(adapt, ADDA_REG);
748 if (t == 0)
749 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8));
750
751 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
752
753 _PHY_PIModeSwitch(adapt, true);
754 }
755
756
757 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
758 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
759 rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
760 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
761
762 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
763 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
764 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
765 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
766
767
768 _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
769
770
771
772 rtl8188e_PHY_SetBBReg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
773
774
775
776 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
777 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
778 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
779
780 for (i = 0; i < retryCount; i++) {
781 PathAOK = phy_PathA_IQK_8188E(adapt);
782 if (PathAOK == 0x01) {
783 result[t][0] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
784 result[t][1] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
785 break;
786 }
787 }
788
789 for (i = 0; i < retryCount; i++) {
790 PathAOK = phy_PathA_RxIQK(adapt);
791 if (PathAOK == 0x03) {
792 result[t][2] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
793 result[t][3] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
794 break;
795 }
796 }
797
798
799 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0);
800
801 if (t != 0) {
802 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
803
804 _PHY_PIModeSwitch(adapt, false);
805 }
806
807
808 reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
809
810
811 _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
812
813 reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
814
815
816 rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3);
817
818
819 rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
820 rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
821 }
822}
823
824static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
825{
826 u8 tmpreg;
827 u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
828
829
830 tmpreg = rtw_read8(adapt, 0xd03);
831
832 if ((tmpreg & 0x70) != 0)
833 rtw_write8(adapt, 0xd03, tmpreg & 0x8F);
834 else
835 rtw_write8(adapt, REG_TXPAUSE, 0xFF);
836
837 if ((tmpreg & 0x70) != 0) {
838
839
840 RF_Amode = rtl8188e_PHY_QueryRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits);
841
842
843 if (is2t)
844 RF_Bmode = rtl8188e_PHY_QueryRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits);
845
846
847
848 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000);
849
850
851 if (is2t)
852 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode & 0x8FFFF) | 0x10000);
853 }
854
855
856 LC_Cal = rtl8188e_PHY_QueryRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
857
858
859 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000);
860
861 msleep(100);
862
863
864 if ((tmpreg & 0x70) != 0) {
865
866
867 rtw_write8(adapt, 0xd03, tmpreg);
868 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
869
870
871 if (is2t)
872 rtl8188e_PHY_SetRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
873 } else {
874
875 rtw_write8(adapt, REG_TXPAUSE, 0x00);
876 }
877}
878
879void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
880{
881 struct hal_data_8188e *pHalData = &adapt->haldata;
882 struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
883 s32 result[4][8];
884 u8 i, final_candidate;
885 bool pathaok;
886 s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC;
887 bool is12simular, is13simular, is23simular;
888 bool singletone = false, carrier_sup = false;
889 u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
890 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
891 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
892 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
893 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
894 rOFDM0_RxIQExtAnta};
895
896 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
897 return;
898
899
900 if (singletone || carrier_sup)
901 return;
902
903 if (recovery) {
904 reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
905 return;
906 }
907
908 for (i = 0; i < 8; i++) {
909 result[0][i] = 0;
910 result[1][i] = 0;
911 result[2][i] = 0;
912 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
913 result[3][i] = 0x100;
914 else
915 result[3][i] = 0;
916 }
917 final_candidate = 0xff;
918 pathaok = false;
919 is12simular = false;
920 is23simular = false;
921 is13simular = false;
922
923 for (i = 0; i < 3; i++) {
924 phy_IQCalibrate_8188E(adapt, result, i);
925
926 if (i == 1) {
927 is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1);
928 if (is12simular) {
929 final_candidate = 0;
930 break;
931 }
932 }
933
934 if (i == 2) {
935 is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2);
936 if (is13simular) {
937 final_candidate = 0;
938
939 break;
940 }
941 is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2);
942 if (is23simular) {
943 final_candidate = 1;
944 } else {
945 final_candidate = 3;
946 }
947 }
948 }
949
950 for (i = 0; i < 4; i++) {
951 RegE94 = result[i][0];
952 RegE9C = result[i][1];
953 RegEA4 = result[i][2];
954 RegEB4 = result[i][4];
955 RegEBC = result[i][5];
956 }
957
958 if (final_candidate != 0xff) {
959 RegE94 = result[final_candidate][0];
960 RegE9C = result[final_candidate][1];
961 RegEA4 = result[final_candidate][2];
962 RegEB4 = result[final_candidate][4];
963 RegEBC = result[final_candidate][5];
964 dm_odm->RFCalibrateInfo.RegE94 = RegE94;
965 dm_odm->RFCalibrateInfo.RegE9C = RegE9C;
966 dm_odm->RFCalibrateInfo.RegEB4 = RegEB4;
967 dm_odm->RFCalibrateInfo.RegEBC = RegEBC;
968 pathaok = true;
969 } else {
970 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
971 dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
972 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
973 dm_odm->RFCalibrateInfo.RegEBC = 0x0;
974 }
975 if (RegE94 != 0)
976 patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0));
977
978
979
980 if (final_candidate < 4) {
981 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
982 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][i] = result[final_candidate][i];
983 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.bIQKDone = true;
984 }
985
986 _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
987}
988
989void PHY_LCCalibrate_8188E(struct adapter *adapt)
990{
991 bool singletone = false, carrier_sup = false;
992 u32 timeout = 2000, timecount = 0;
993 struct hal_data_8188e *pHalData = &adapt->haldata;
994 struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
995
996 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
997 return;
998
999 if (singletone || carrier_sup)
1000 return;
1001
1002 while (*dm_odm->pbScanInProcess && timecount < timeout) {
1003 mdelay(50);
1004 timecount += 50;
1005 }
1006
1007 phy_LCCalibrate_8188E(adapt, false);
1008}
1009