3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 #include "odm_precomp.h"
21 /* 2010/04/25 MH Define the max tx power tracking tx agc power. */
22 #define ODM_TXPWRTRACK_MAX_IDX_88E 6
25 u8
ODM_GetRightChnlPlaceforIQK(u8 chnl
)
27 u8 channel_all
[ODM_TARGET_CHNL_NUM_2G_5G
] = {
28 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
29 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
30 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
31 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
32 155, 157, 159, 161, 163, 165
37 for (place
= 14; place
< sizeof(channel_all
); place
++) {
38 if (channel_all
[place
] == chnl
)
45 /* 3 Tx Power Tracking */
47 * Function: ODM_TxPwrTrackAdjust88E()
49 * Overview: 88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc.
50 * No matter OFDM & CCK use the same method.
54 * 04/23/2012 MHC Create Version 0.
55 * 04/23/2012 MHC Adjust TX agc directly not throughput BB digital.
58 void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct
*dm_odm
, u8 Type
,/* 0 = OFDM, 1 = CCK */
59 u8
*pDirection
, /* 1 = +(increase) 2 = -(decrease) */
60 u32
*pOutWriteVal
/* Tx tracking CCK/OFDM BB swing index adjust */
64 /* Tx power tracking BB swing table. */
65 /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
66 if (Type
== 0) { /* For OFDM afjust */
67 ODM_RT_TRACE(dm_odm
, ODM_COMP_TX_PWR_TRACK
, ODM_DBG_LOUD
,
68 ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
69 dm_odm
->BbSwingIdxOfdm
, dm_odm
->BbSwingFlagOfdm
));
71 if (dm_odm
->BbSwingIdxOfdm
<= dm_odm
->BbSwingIdxOfdmBase
) {
73 pwr_value
= (dm_odm
->BbSwingIdxOfdmBase
- dm_odm
->BbSwingIdxOfdm
);
76 pwr_value
= (dm_odm
->BbSwingIdxOfdm
- dm_odm
->BbSwingIdxOfdmBase
);
79 ODM_RT_TRACE(dm_odm
, ODM_COMP_TX_PWR_TRACK
, ODM_DBG_LOUD
,
80 ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
81 dm_odm
->BbSwingIdxOfdm
, dm_odm
->BbSwingFlagOfdm
));
82 } else if (Type
== 1) { /* For CCK adjust. */
83 ODM_RT_TRACE(dm_odm
, ODM_COMP_TX_PWR_TRACK
, ODM_DBG_LOUD
,
84 ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
85 dm_odm
->BbSwingIdxCck
, dm_odm
->BbSwingIdxCckBase
));
87 if (dm_odm
->BbSwingIdxCck
<= dm_odm
->BbSwingIdxCckBase
) {
89 pwr_value
= (dm_odm
->BbSwingIdxCckBase
- dm_odm
->BbSwingIdxCck
);
92 pwr_value
= (dm_odm
->BbSwingIdxCck
- dm_odm
->BbSwingIdxCckBase
);
97 /* 2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */
98 /* need to be less than 6 power index for 88E. */
100 if (pwr_value
>= ODM_TXPWRTRACK_MAX_IDX_88E
&& *pDirection
== 1)
101 pwr_value
= ODM_TXPWRTRACK_MAX_IDX_88E
;
103 *pOutWriteVal
= pwr_value
| (pwr_value
<<8) | (pwr_value
<<16) | (pwr_value
<<24);
104 } /* ODM_TxPwrTrackAdjust88E */
107 * Function: odm_TxPwrTrackSetPwr88E()
109 * Overview: 88E change all channel tx power accordign to flag.
110 * OFDM & CCK are all different.
112 static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct
*dm_odm
)
114 if (dm_odm
->BbSwingFlagOfdm
|| dm_odm
->BbSwingFlagCck
) {
115 ODM_RT_TRACE(dm_odm
, ODM_COMP_TX_PWR_TRACK
, ODM_DBG_LOUD
, ("odm_TxPwrTrackSetPwr88E CH=%d\n", *(dm_odm
->pChannel
)));
116 PHY_SetTxPowerLevel8188E(dm_odm
->Adapter
, *(dm_odm
->pChannel
));
117 dm_odm
->BbSwingFlagOfdm
= false;
118 dm_odm
->BbSwingFlagCck
= false;
120 } /* odm_TxPwrTrackSetPwr88E */
123 odm_TXPowerTrackingCallback_ThermalMeter_8188E(
124 struct adapter
*Adapter
127 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(Adapter
);
128 u8 ThermalValue
= 0, delta
, delta_LCK
, delta_IQK
, offset
;
129 u8 ThermalValue_AVG_count
= 0;
130 u32 ThermalValue_AVG
= 0;
131 s32 ele_A
= 0, ele_D
, TempCCk
, X
, value32
;
133 s8 OFDM_index
[2], CCK_index
= 0;
134 s8 OFDM_index_old
[2] = {0, 0}, CCK_index_old
= 0;
138 u8 OFDM_min_index
= 6, rf
; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
139 u8 Indexforchannel
= 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/;
140 s8 OFDM_index_mapping
[2][index_mapping_NUM_88E
] = {
141 {0, 0, 2, 3, 4, 4, /* 2.4G, decrease power */
143 10, 10, 11}, /* For lower temperature, 20120220 updated on 20120220. */
144 {0, 0, -1, -2, -3, -4, /* 2.4G, increase power */
145 -4, -4, -4, -5, -7, -8,
148 u8 Thermal_mapping
[2][index_mapping_NUM_88E
] = {
149 {0, 2, 4, 6, 8, 10, /* 2.4G, decrease power */
150 12, 14, 16, 18, 20, 22,
152 {0, 2, 4, 6, 8, 10, /* 2.4G,, increase power */
153 12, 14, 16, 18, 20, 22,
156 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
158 /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
159 odm_TxPwrTrackSetPwr88E(dm_odm
);
161 dm_odm
->RFCalibrateInfo
.TXPowerTrackingCallbackCnt
++; /* cosa add for debug */
162 dm_odm
->RFCalibrateInfo
.bTXPowerTrackingInit
= true;
164 /* <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */
165 dm_odm
->RFCalibrateInfo
.RegA24
= 0x090e1317;
167 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
168 ("===>dm_TXPowerTrackingCallback_ThermalMeter_8188E txpowercontrol %d\n",
169 dm_odm
->RFCalibrateInfo
.TxPowerTrackControl
));
171 ThermalValue
= (u8
)PHY_QueryRFReg(Adapter
, RF_PATH_A
, RF_T_METER_88E
, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
173 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
174 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",
175 ThermalValue
, dm_odm
->RFCalibrateInfo
.ThermalValue
, pHalData
->EEPROMThermalMeter
));
183 /* Query OFDM path A default setting */
184 ele_D
= PHY_QueryBBReg(Adapter
, rOFDM0_XATxIQImbalance
, bMaskDWord
)&bMaskOFDM_D
;
185 for (i
= 0; i
< OFDM_TABLE_SIZE_92D
; i
++) { /* find the index */
186 if (ele_D
== (OFDMSwingTable
[i
]&bMaskOFDM_D
)) {
187 OFDM_index_old
[0] = (u8
)i
;
188 dm_odm
->BbSwingIdxOfdmBase
= (u8
)i
;
189 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
190 ("Initial pathA ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
191 rOFDM0_XATxIQImbalance
, ele_D
, OFDM_index_old
[0]));
196 /* Query OFDM path B default setting */
198 ele_D
= PHY_QueryBBReg(Adapter
, rOFDM0_XBTxIQImbalance
, bMaskDWord
)&bMaskOFDM_D
;
199 for (i
= 0; i
< OFDM_TABLE_SIZE_92D
; i
++) { /* find the index */
200 if (ele_D
== (OFDMSwingTable
[i
]&bMaskOFDM_D
)) {
201 OFDM_index_old
[1] = (u8
)i
;
202 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
203 ("Initial pathB ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
204 rOFDM0_XBTxIQImbalance
, ele_D
, OFDM_index_old
[1]));
210 /* Query CCK default setting From 0xa24 */
211 TempCCk
= dm_odm
->RFCalibrateInfo
.RegA24
;
213 for (i
= 0; i
< CCK_TABLE_SIZE
; i
++) {
214 if (dm_odm
->RFCalibrateInfo
.bCCKinCH14
) {
215 if (memcmp(&TempCCk
, &CCKSwingTable_Ch14
[i
][2], 4)) {
216 CCK_index_old
= (u8
)i
;
217 dm_odm
->BbSwingIdxCckBase
= (u8
)i
;
218 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
219 ("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch 14 %d\n",
220 rCCK0_TxFilter2
, TempCCk
, CCK_index_old
, dm_odm
->RFCalibrateInfo
.bCCKinCH14
));
224 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
225 ("RegA24: 0x%X, CCKSwingTable_Ch1_Ch13[%d][2]: CCKSwingTable_Ch1_Ch13[i][2]: 0x%X\n",
226 TempCCk
, i
, CCKSwingTable_Ch1_Ch13
[i
][2]));
227 if (memcmp(&TempCCk
, &CCKSwingTable_Ch1_Ch13
[i
][2], 4)) {
228 CCK_index_old
= (u8
)i
;
229 dm_odm
->BbSwingIdxCckBase
= (u8
)i
;
230 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
231 ("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch14 %d\n",
232 rCCK0_TxFilter2
, TempCCk
, CCK_index_old
, dm_odm
->RFCalibrateInfo
.bCCKinCH14
));
238 if (!dm_odm
->RFCalibrateInfo
.ThermalValue
) {
239 dm_odm
->RFCalibrateInfo
.ThermalValue
= pHalData
->EEPROMThermalMeter
;
240 dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
= ThermalValue
;
241 dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
= ThermalValue
;
243 for (i
= 0; i
< rf
; i
++)
244 dm_odm
->RFCalibrateInfo
.OFDM_index
[i
] = OFDM_index_old
[i
];
245 dm_odm
->RFCalibrateInfo
.CCK_index
= CCK_index_old
;
248 if (dm_odm
->RFCalibrateInfo
.bReloadtxpowerindex
)
249 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
250 ("reload ofdm index for band switch\n"));
252 /* calculate average thermal meter */
253 dm_odm
->RFCalibrateInfo
.ThermalValue_AVG
[dm_odm
->RFCalibrateInfo
.ThermalValue_AVG_index
] = ThermalValue
;
254 dm_odm
->RFCalibrateInfo
.ThermalValue_AVG_index
++;
255 if (dm_odm
->RFCalibrateInfo
.ThermalValue_AVG_index
== AVG_THERMAL_NUM_88E
)
256 dm_odm
->RFCalibrateInfo
.ThermalValue_AVG_index
= 0;
258 for (i
= 0; i
< AVG_THERMAL_NUM_88E
; i
++) {
259 if (dm_odm
->RFCalibrateInfo
.ThermalValue_AVG
[i
]) {
260 ThermalValue_AVG
+= dm_odm
->RFCalibrateInfo
.ThermalValue_AVG
[i
];
261 ThermalValue_AVG_count
++;
265 if (ThermalValue_AVG_count
) {
266 ThermalValue
= (u8
)(ThermalValue_AVG
/ ThermalValue_AVG_count
);
267 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
268 ("AVG Thermal Meter = 0x%x\n", ThermalValue
));
271 if (dm_odm
->RFCalibrateInfo
.bReloadtxpowerindex
) {
272 delta
= ThermalValue
> pHalData
->EEPROMThermalMeter
?
273 (ThermalValue
- pHalData
->EEPROMThermalMeter
) :
274 (pHalData
->EEPROMThermalMeter
- ThermalValue
);
275 dm_odm
->RFCalibrateInfo
.bReloadtxpowerindex
= false;
276 dm_odm
->RFCalibrateInfo
.bDoneTxpower
= false;
277 } else if (dm_odm
->RFCalibrateInfo
.bDoneTxpower
) {
278 delta
= (ThermalValue
> dm_odm
->RFCalibrateInfo
.ThermalValue
) ?
279 (ThermalValue
- dm_odm
->RFCalibrateInfo
.ThermalValue
) :
280 (dm_odm
->RFCalibrateInfo
.ThermalValue
- ThermalValue
);
282 delta
= ThermalValue
> pHalData
->EEPROMThermalMeter
?
283 (ThermalValue
- pHalData
->EEPROMThermalMeter
) :
284 (pHalData
->EEPROMThermalMeter
- ThermalValue
);
286 delta_LCK
= (ThermalValue
> dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
) ?
287 (ThermalValue
- dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
) :
288 (dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
- ThermalValue
);
289 delta_IQK
= (ThermalValue
> dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
) ?
290 (ThermalValue
- dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
) :
291 (dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
- ThermalValue
);
292 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
293 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x delta 0x%x delta_LCK 0x%x delta_IQK 0x%x\n",
294 ThermalValue
, dm_odm
->RFCalibrateInfo
.ThermalValue
,
295 pHalData
->EEPROMThermalMeter
, delta
, delta_LCK
, delta_IQK
));
296 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
297 ("pre thermal meter LCK 0x%x pre thermal meter IQK 0x%x delta_LCK_bound 0x%x delta_IQK_bound 0x%x\n",
298 dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
,
299 dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
,
300 dm_odm
->RFCalibrateInfo
.Delta_LCK
,
301 dm_odm
->RFCalibrateInfo
.Delta_IQK
));
303 if ((delta_LCK
>= 8)) { /* Delta temperature is equal to or larger than 20 centigrade. */
304 dm_odm
->RFCalibrateInfo
.ThermalValue_LCK
= ThermalValue
;
305 PHY_LCCalibrate_8188E(Adapter
);
308 if (delta
> 0 && dm_odm
->RFCalibrateInfo
.TxPowerTrackControl
) {
309 delta
= ThermalValue
> pHalData
->EEPROMThermalMeter
?
310 (ThermalValue
- pHalData
->EEPROMThermalMeter
) :
311 (pHalData
->EEPROMThermalMeter
- ThermalValue
);
312 /* calculate new OFDM / CCK offset */
313 if (ThermalValue
> pHalData
->EEPROMThermalMeter
)
317 for (offset
= 0; offset
< index_mapping_NUM_88E
; offset
++) {
318 if (delta
< Thermal_mapping
[j
][offset
]) {
324 if (offset
>= index_mapping_NUM_88E
)
325 offset
= index_mapping_NUM_88E
-1
;
326 for (i
= 0; i
< rf
; i
++)
327 OFDM_index
[i
] = dm_odm
->RFCalibrateInfo
.OFDM_index
[i
] + OFDM_index_mapping
[j
][offset
];
328 CCK_index
= dm_odm
->RFCalibrateInfo
.CCK_index
+ OFDM_index_mapping
[j
][offset
];
331 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
332 ("temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
333 dm_odm
->RFCalibrateInfo
.OFDM_index
[0],
334 dm_odm
->RFCalibrateInfo
.OFDM_index
[1],
335 dm_odm
->RFCalibrateInfo
.CCK_index
));
337 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
338 ("temp OFDM_A_index=0x%x, CCK_index=0x%x\n",
339 dm_odm
->RFCalibrateInfo
.OFDM_index
[0],
340 dm_odm
->RFCalibrateInfo
.CCK_index
));
343 for (i
= 0; i
< rf
; i
++) {
344 if (OFDM_index
[i
] > OFDM_TABLE_SIZE_92D
-1)
345 OFDM_index
[i
] = OFDM_TABLE_SIZE_92D
-1;
346 else if (OFDM_index
[i
] < OFDM_min_index
)
347 OFDM_index
[i
] = OFDM_min_index
;
350 if (CCK_index
> CCK_TABLE_SIZE
-1)
351 CCK_index
= CCK_TABLE_SIZE
-1;
352 else if (CCK_index
< 0)
356 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
357 ("new OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
358 OFDM_index
[0], OFDM_index
[1], CCK_index
));
360 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
361 ("new OFDM_A_index=0x%x, CCK_index=0x%x\n",
362 OFDM_index
[0], CCK_index
));
365 /* 2 temporarily remove bNOPG */
366 /* Config by SwingTable */
367 if (dm_odm
->RFCalibrateInfo
.TxPowerTrackControl
) {
368 dm_odm
->RFCalibrateInfo
.bDoneTxpower
= true;
370 /* Adujst OFDM Ant_A according to IQK result */
371 ele_D
= (OFDMSwingTable
[(u8
)OFDM_index
[0]] & 0xFFC00000)>>22;
372 X
= dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].Value
[0][0];
373 Y
= dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].Value
[0][1];
375 /* Revse TX power table. */
376 dm_odm
->BbSwingIdxOfdm
= (u8
)OFDM_index
[0];
377 dm_odm
->BbSwingIdxCck
= (u8
)CCK_index
;
379 if (dm_odm
->BbSwingIdxOfdmCurrent
!= dm_odm
->BbSwingIdxOfdm
) {
380 dm_odm
->BbSwingIdxOfdmCurrent
= dm_odm
->BbSwingIdxOfdm
;
381 dm_odm
->BbSwingFlagOfdm
= true;
384 if (dm_odm
->BbSwingIdxCckCurrent
!= dm_odm
->BbSwingIdxCck
) {
385 dm_odm
->BbSwingIdxCckCurrent
= dm_odm
->BbSwingIdxCck
;
386 dm_odm
->BbSwingFlagCck
= true;
390 if ((X
& 0x00000200) != 0)
392 ele_A
= ((X
* ele_D
)>>8)&0x000003FF;
394 /* new element C = element D x Y */
395 if ((Y
& 0x00000200) != 0)
397 ele_C
= ((Y
* ele_D
)>>8)&0x000003FF;
399 /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
400 /* to increase TX power. Otherwise, EVM will be bad. */
403 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
404 ("TxPwrTracking for path A: X=0x%x, Y=0x%x ele_A=0x%x ele_C=0x%x ele_D=0x%x 0xe94=0x%x 0xe9c=0x%x\n",
405 (u32
)X
, (u32
)Y
, (u32
)ele_A
, (u32
)ele_C
, (u32
)ele_D
, (u32
)X
, (u32
)Y
));
408 ele_D
= (OFDMSwingTable
[(u8
)OFDM_index
[1]] & 0xFFC00000)>>22;
410 /* new element A = element D x X */
411 X
= dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].Value
[0][4];
412 Y
= dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].Value
[0][5];
414 if ((X
!= 0) && (*(dm_odm
->pBandType
) == ODM_BAND_2_4G
)) {
415 if ((X
& 0x00000200) != 0) /* consider minus */
417 ele_A
= ((X
* ele_D
)>>8)&0x000003FF;
419 /* new element C = element D x Y */
420 if ((Y
& 0x00000200) != 0)
422 ele_C
= ((Y
* ele_D
)>>8)&0x00003FF;
424 /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */
425 value32
= (ele_D
<<22) | ((ele_C
&0x3F)<<16) | ele_A
;
426 PHY_SetBBReg(Adapter
, rOFDM0_XBTxIQImbalance
, bMaskDWord
, value32
);
428 value32
= (ele_C
&0x000003C0)>>6;
429 PHY_SetBBReg(Adapter
, rOFDM0_XDTxAFE
, bMaskH4Bits
, value32
);
431 value32
= ((X
* ele_D
)>>7)&0x01;
432 PHY_SetBBReg(Adapter
, rOFDM0_ECCAThreshold
, BIT28
, value32
);
434 PHY_SetBBReg(Adapter
, rOFDM0_XBTxIQImbalance
, bMaskDWord
, OFDMSwingTable
[(u8
)OFDM_index
[1]]);
435 PHY_SetBBReg(Adapter
, rOFDM0_XDTxAFE
, bMaskH4Bits
, 0x00);
436 PHY_SetBBReg(Adapter
, rOFDM0_ECCAThreshold
, BIT28
, 0x00);
439 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
440 ("TxPwrTracking path B: X=0x%x, Y=0x%x ele_A=0x%x ele_C=0x%x ele_D=0x%x 0xeb4=0x%x 0xebc=0x%x\n",
441 (u32
)X
, (u32
)Y
, (u32
)ele_A
,
442 (u32
)ele_C
, (u32
)ele_D
, (u32
)X
, (u32
)Y
));
445 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
446 ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
447 PHY_QueryBBReg(Adapter
, 0xc80, bMaskDWord
), PHY_QueryBBReg(Adapter
,
448 0xc94, bMaskDWord
), PHY_QueryRFReg(Adapter
, RF_PATH_A
, 0x24, bRFRegOffsetMask
)));
452 if (delta_IQK
>= 8) { /* Delta temperature is equal to or larger than 20 centigrade. */
453 dm_odm
->RFCalibrateInfo
.ThermalValue_IQK
= ThermalValue
;
454 PHY_IQCalibrate_8188E(Adapter
, false);
456 /* update thermal meter value */
457 if (dm_odm
->RFCalibrateInfo
.TxPowerTrackControl
)
458 dm_odm
->RFCalibrateInfo
.ThermalValue
= ThermalValue
;
460 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
461 ("<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n"));
462 dm_odm
->RFCalibrateInfo
.TXPowercount
= 0;
466 #define MAX_TOLERANCE 5
468 static u8
/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
469 phy_PathA_IQK_8188E(struct adapter
*adapt
, bool configPathB
)
471 u32 regeac
, regE94
, regE9C
, regEA4
;
473 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
474 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
475 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A IQK!\n"));
478 /* path-A IQK setting */
479 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path-A IQK setting!\n"));
480 PHY_SetBBReg(adapt
, rTx_IQK_Tone_A
, bMaskDWord
, 0x10008c1c);
481 PHY_SetBBReg(adapt
, rRx_IQK_Tone_A
, bMaskDWord
, 0x30008c1c);
482 PHY_SetBBReg(adapt
, rTx_IQK_PI_A
, bMaskDWord
, 0x8214032a);
483 PHY_SetBBReg(adapt
, rRx_IQK_PI_A
, bMaskDWord
, 0x28160000);
485 /* LO calibration setting */
486 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("LO calibration setting!\n"));
487 PHY_SetBBReg(adapt
, rIQK_AGC_Rsp
, bMaskDWord
, 0x00462911);
489 /* One shot, path A LOK & IQK */
490 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("One shot, path A LOK & IQK!\n"));
491 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf9000000);
492 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf8000000);
495 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E
));
496 /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
497 mdelay(IQK_DELAY_TIME_88E
);
500 regeac
= PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_A_2
, bMaskDWord
);
501 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xeac = 0x%x\n", regeac
));
502 regE94
= PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_A
, bMaskDWord
);
503 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xe94 = 0x%x\n", regE94
));
504 regE9C
= PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_A
, bMaskDWord
);
505 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xe9c = 0x%x\n", regE9C
));
506 regEA4
= PHY_QueryBBReg(adapt
, rRx_Power_Before_IQK_A_2
, bMaskDWord
);
507 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xea4 = 0x%x\n", regEA4
));
509 if (!(regeac
& BIT28
) &&
510 (((regE94
& 0x03FF0000)>>16) != 0x142) &&
511 (((regE9C
& 0x03FF0000)>>16) != 0x42))
516 static u8
/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
517 phy_PathA_RxIQK(struct adapter
*adapt
, bool configPathB
)
519 u32 regeac
, regE94
, regE9C
, regEA4
, u4tmp
;
521 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
522 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
523 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A Rx IQK!\n"));
525 /* 1 Get TXIMR setting */
526 /* modify RXIQK mode table */
527 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path-A Rx IQK modify RXIQK mode table!\n"));
528 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x00000000);
529 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_WE_LUT
, bRFRegOffsetMask
, 0x800a0);
530 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_RCK_OS
, bRFRegOffsetMask
, 0x30000);
531 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_TXPA_G1
, bRFRegOffsetMask
, 0x0000f);
532 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_TXPA_G2
, bRFRegOffsetMask
, 0xf117B);
535 PHY_SetRFReg(adapt
, RF_PATH_A
, 0xdf, bRFRegOffsetMask
, 0x980);
536 PHY_SetRFReg(adapt
, RF_PATH_A
, 0x56, bRFRegOffsetMask
, 0x51000);
538 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x80800000);
541 PHY_SetBBReg(adapt
, rTx_IQK
, bMaskDWord
, 0x01007c00);
542 PHY_SetBBReg(adapt
, rRx_IQK
, bMaskDWord
, 0x81004800);
544 /* path-A IQK setting */
545 PHY_SetBBReg(adapt
, rTx_IQK_Tone_A
, bMaskDWord
, 0x10008c1c);
546 PHY_SetBBReg(adapt
, rRx_IQK_Tone_A
, bMaskDWord
, 0x30008c1c);
547 PHY_SetBBReg(adapt
, rTx_IQK_PI_A
, bMaskDWord
, 0x82160c1f);
548 PHY_SetBBReg(adapt
, rRx_IQK_PI_A
, bMaskDWord
, 0x28160000);
550 /* LO calibration setting */
551 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("LO calibration setting!\n"));
552 PHY_SetBBReg(adapt
, rIQK_AGC_Rsp
, bMaskDWord
, 0x0046a911);
554 /* One shot, path A LOK & IQK */
555 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("One shot, path A LOK & IQK!\n"));
556 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf9000000);
557 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf8000000);
560 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
561 ("Delay %d ms for One shot, path A LOK & IQK.\n",
562 IQK_DELAY_TIME_88E
));
563 mdelay(IQK_DELAY_TIME_88E
);
566 regeac
= PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_A_2
, bMaskDWord
);
567 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
568 ("0xeac = 0x%x\n", regeac
));
569 regE94
= PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_A
, bMaskDWord
);
570 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
571 ("0xe94 = 0x%x\n", regE94
));
572 regE9C
= PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_A
, bMaskDWord
);
573 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
574 ("0xe9c = 0x%x\n", regE9C
));
576 if (!(regeac
& BIT28
) &&
577 (((regE94
& 0x03FF0000)>>16) != 0x142) &&
578 (((regE9C
& 0x03FF0000)>>16) != 0x42))
580 else /* if Tx not OK, ignore Rx */
583 u4tmp
= 0x80007C00 | (regE94
&0x3FF0000) | ((regE9C
&0x3FF0000) >> 16);
584 PHY_SetBBReg(adapt
, rTx_IQK
, bMaskDWord
, u4tmp
);
585 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xe40 = 0x%x u4tmp = 0x%x\n", PHY_QueryBBReg(adapt
, rTx_IQK
, bMaskDWord
), u4tmp
));
588 /* modify RXIQK mode table */
589 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
590 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x00000000);
591 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_WE_LUT
, bRFRegOffsetMask
, 0x800a0);
592 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_RCK_OS
, bRFRegOffsetMask
, 0x30000);
593 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_TXPA_G1
, bRFRegOffsetMask
, 0x0000f);
594 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_TXPA_G2
, bRFRegOffsetMask
, 0xf7ffa);
595 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x80800000);
598 PHY_SetBBReg(adapt
, rRx_IQK
, bMaskDWord
, 0x01004800);
600 /* path-A IQK setting */
601 PHY_SetBBReg(adapt
, rTx_IQK_Tone_A
, bMaskDWord
, 0x38008c1c);
602 PHY_SetBBReg(adapt
, rRx_IQK_Tone_A
, bMaskDWord
, 0x18008c1c);
603 PHY_SetBBReg(adapt
, rTx_IQK_PI_A
, bMaskDWord
, 0x82160c05);
604 PHY_SetBBReg(adapt
, rRx_IQK_PI_A
, bMaskDWord
, 0x28160c1f);
606 /* LO calibration setting */
607 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("LO calibration setting!\n"));
608 PHY_SetBBReg(adapt
, rIQK_AGC_Rsp
, bMaskDWord
, 0x0046a911);
610 /* One shot, path A LOK & IQK */
611 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("One shot, path A LOK & IQK!\n"));
612 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf9000000);
613 PHY_SetBBReg(adapt
, rIQK_AGC_Pts
, bMaskDWord
, 0xf8000000);
616 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E
));
617 /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
618 mdelay(IQK_DELAY_TIME_88E
);
621 regeac
= PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_A_2
, bMaskDWord
);
622 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xeac = 0x%x\n", regeac
));
623 regE94
= PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_A
, bMaskDWord
);
624 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xe94 = 0x%x\n", regE94
));
625 regE9C
= PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_A
, bMaskDWord
);
626 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xe9c = 0x%x\n", regE9C
));
627 regEA4
= PHY_QueryBBReg(adapt
, rRx_Power_Before_IQK_A_2
, bMaskDWord
);
628 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("0xea4 = 0x%x\n", regEA4
));
631 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x00000000);
632 PHY_SetRFReg(adapt
, RF_PATH_A
, 0xdf, bRFRegOffsetMask
, 0x180);
634 if (!(regeac
& BIT27
) && /* if Tx is OK, check whether Rx is OK */
635 (((regEA4
& 0x03FF0000)>>16) != 0x132) &&
636 (((regeac
& 0x03FF0000)>>16) != 0x36))
639 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A Rx IQK fail!!\n"));
644 static u8
/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
645 phy_PathB_IQK_8188E(struct adapter
*adapt
)
647 u32 regeac
, regeb4
, regebc
, regec4
, regecc
;
649 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
650 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
651 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path B IQK!\n"));
653 /* One shot, path B LOK & IQK */
654 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("One shot, path A LOK & IQK!\n"));
655 PHY_SetBBReg(adapt
, rIQK_AGC_Cont
, bMaskDWord
, 0x00000002);
656 PHY_SetBBReg(adapt
, rIQK_AGC_Cont
, bMaskDWord
, 0x00000000);
659 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
660 ("Delay %d ms for One shot, path B LOK & IQK.\n",
661 IQK_DELAY_TIME_88E
));
662 mdelay(IQK_DELAY_TIME_88E
);
665 regeac
= PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_A_2
, bMaskDWord
);
666 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
667 ("0xeac = 0x%x\n", regeac
));
668 regeb4
= PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_B
, bMaskDWord
);
669 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
670 ("0xeb4 = 0x%x\n", regeb4
));
671 regebc
= PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_B
, bMaskDWord
);
672 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
673 ("0xebc = 0x%x\n", regebc
));
674 regec4
= PHY_QueryBBReg(adapt
, rRx_Power_Before_IQK_B_2
, bMaskDWord
);
675 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
676 ("0xec4 = 0x%x\n", regec4
));
677 regecc
= PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_B_2
, bMaskDWord
);
678 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
679 ("0xecc = 0x%x\n", regecc
));
681 if (!(regeac
& BIT31
) &&
682 (((regeb4
& 0x03FF0000)>>16) != 0x142) &&
683 (((regebc
& 0x03FF0000)>>16) != 0x42))
688 if (!(regeac
& BIT30
) &&
689 (((regec4
& 0x03FF0000)>>16) != 0x132) &&
690 (((regecc
& 0x03FF0000)>>16) != 0x36))
693 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path B Rx IQK fail!!\n"));
697 static void patha_fill_iqk(struct adapter
*adapt
, bool iqkok
, s32 result
[][8], u8 final_candidate
, bool txonly
)
699 u32 Oldval_0
, X
, TX0_A
, reg
;
701 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
702 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
703 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
704 ("Path A IQ Calibration %s !\n",
705 (iqkok
) ? "Success" : "Failed"));
707 if (final_candidate
== 0xFF) {
710 Oldval_0
= (PHY_QueryBBReg(adapt
, rOFDM0_XATxIQImbalance
, bMaskDWord
) >> 22) & 0x3FF;
712 X
= result
[final_candidate
][0];
713 if ((X
& 0x00000200) != 0)
715 TX0_A
= (X
* Oldval_0
) >> 8;
716 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
717 ("X = 0x%x, TX0_A = 0x%x, Oldval_0 0x%x\n",
718 X
, TX0_A
, Oldval_0
));
719 PHY_SetBBReg(adapt
, rOFDM0_XATxIQImbalance
, 0x3FF, TX0_A
);
721 PHY_SetBBReg(adapt
, rOFDM0_ECCAThreshold
, BIT(31), ((X
* Oldval_0
>>7) & 0x1));
723 Y
= result
[final_candidate
][1];
724 if ((Y
& 0x00000200) != 0)
727 TX0_C
= (Y
* Oldval_0
) >> 8;
728 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Y = 0x%x, TX = 0x%x\n", Y
, TX0_C
));
729 PHY_SetBBReg(adapt
, rOFDM0_XCTxAFE
, 0xF0000000, ((TX0_C
&0x3C0)>>6));
730 PHY_SetBBReg(adapt
, rOFDM0_XATxIQImbalance
, 0x003F0000, (TX0_C
&0x3F));
732 PHY_SetBBReg(adapt
, rOFDM0_ECCAThreshold
, BIT(29), ((Y
* Oldval_0
>>7) & 0x1));
735 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("patha_fill_iqk only Tx OK\n"));
739 reg
= result
[final_candidate
][2];
740 PHY_SetBBReg(adapt
, rOFDM0_XARxIQImbalance
, 0x3FF, reg
);
742 reg
= result
[final_candidate
][3] & 0x3F;
743 PHY_SetBBReg(adapt
, rOFDM0_XARxIQImbalance
, 0xFC00, reg
);
745 reg
= (result
[final_candidate
][3] >> 6) & 0xF;
746 PHY_SetBBReg(adapt
, rOFDM0_RxIQExtAnta
, 0xF0000000, reg
);
750 static void pathb_fill_iqk(struct adapter
*adapt
, bool iqkok
, s32 result
[][8], u8 final_candidate
, bool txonly
)
752 u32 Oldval_1
, X
, TX1_A
, reg
;
754 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
755 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
756 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
757 ("Path B IQ Calibration %s !\n",
758 (iqkok
) ? "Success" : "Failed"));
760 if (final_candidate
== 0xFF) {
763 Oldval_1
= (PHY_QueryBBReg(adapt
, rOFDM0_XBTxIQImbalance
, bMaskDWord
) >> 22) & 0x3FF;
765 X
= result
[final_candidate
][4];
766 if ((X
& 0x00000200) != 0)
768 TX1_A
= (X
* Oldval_1
) >> 8;
769 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("X = 0x%x, TX1_A = 0x%x\n", X
, TX1_A
));
770 PHY_SetBBReg(adapt
, rOFDM0_XBTxIQImbalance
, 0x3FF, TX1_A
);
772 PHY_SetBBReg(adapt
, rOFDM0_ECCAThreshold
, BIT(27), ((X
* Oldval_1
>>7) & 0x1));
774 Y
= result
[final_candidate
][5];
775 if ((Y
& 0x00000200) != 0)
778 TX1_C
= (Y
* Oldval_1
) >> 8;
779 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Y = 0x%x, TX1_C = 0x%x\n", Y
, TX1_C
));
780 PHY_SetBBReg(adapt
, rOFDM0_XDTxAFE
, 0xF0000000, ((TX1_C
&0x3C0)>>6));
781 PHY_SetBBReg(adapt
, rOFDM0_XBTxIQImbalance
, 0x003F0000, (TX1_C
&0x3F));
783 PHY_SetBBReg(adapt
, rOFDM0_ECCAThreshold
, BIT(25), ((Y
* Oldval_1
>>7) & 0x1));
788 reg
= result
[final_candidate
][6];
789 PHY_SetBBReg(adapt
, rOFDM0_XBRxIQImbalance
, 0x3FF, reg
);
791 reg
= result
[final_candidate
][7] & 0x3F;
792 PHY_SetBBReg(adapt
, rOFDM0_XBRxIQImbalance
, 0xFC00, reg
);
794 reg
= (result
[final_candidate
][7] >> 6) & 0xF;
795 PHY_SetBBReg(adapt
, rOFDM0_AGCRSSITable
, 0x0000F000, reg
);
799 void _PHY_SaveADDARegisters(struct adapter
*adapt
, u32
*ADDAReg
, u32
*ADDABackup
, u32 RegisterNum
)
802 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
803 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
805 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Save ADDA parameters.\n"));
806 for (i
= 0; i
< RegisterNum
; i
++) {
807 ADDABackup
[i
] = PHY_QueryBBReg(adapt
, ADDAReg
[i
], bMaskDWord
);
811 static void _PHY_SaveMACRegisters(
812 struct adapter
*adapt
,
818 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
819 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
820 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Save MAC parameters.\n"));
821 for (i
= 0; i
< (IQK_MAC_REG_NUM
- 1); i
++) {
822 MACBackup
[i
] = rtw_read8(adapt
, MACReg
[i
]);
824 MACBackup
[i
] = rtw_read32(adapt
, MACReg
[i
]);
827 static void reload_adda_reg(struct adapter
*adapt
, u32
*ADDAReg
, u32
*ADDABackup
, u32 RegiesterNum
)
830 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
831 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
833 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Reload ADDA power saving parameters !\n"));
834 for (i
= 0; i
< RegiesterNum
; i
++)
835 PHY_SetBBReg(adapt
, ADDAReg
[i
], bMaskDWord
, ADDABackup
[i
]);
839 _PHY_ReloadMACRegisters(
840 struct adapter
*adapt
,
846 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
847 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
849 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Reload MAC parameters !\n"));
850 for (i
= 0; i
< (IQK_MAC_REG_NUM
- 1); i
++) {
851 usb_write8(adapt
, MACReg
[i
], (u8
)MACBackup
[i
]);
853 usb_write32(adapt
, MACReg
[i
], MACBackup
[i
]);
858 struct adapter
*adapt
,
866 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
867 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
868 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("ADDA ON.\n"));
870 pathOn
= isPathAOn
? 0x04db25a4 : 0x0b1b25a4;
873 PHY_SetBBReg(adapt
, ADDAReg
[0], bMaskDWord
, 0x0b1b25a0);
875 PHY_SetBBReg(adapt
, ADDAReg
[0], bMaskDWord
, pathOn
);
878 for (i
= 1; i
< IQK_ADDA_REG_NUM
; i
++)
879 PHY_SetBBReg(adapt
, ADDAReg
[i
], bMaskDWord
, pathOn
);
883 _PHY_MACSettingCalibration(
884 struct adapter
*adapt
,
890 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
891 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
893 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("MAC settings for Calibration.\n"));
895 usb_write8(adapt
, MACReg
[i
], 0x3F);
897 for (i
= 1; i
< (IQK_MAC_REG_NUM
- 1); i
++) {
898 usb_write8(adapt
, MACReg
[i
], (u8
)(MACBackup
[i
]&(~BIT3
)));
900 usb_write8(adapt
, MACReg
[i
], (u8
)(MACBackup
[i
]&(~BIT5
)));
905 struct adapter
*adapt
908 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
909 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
911 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path-A standby mode!\n"));
913 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x0);
914 PHY_SetBBReg(adapt
, 0x840, bMaskDWord
, 0x00010000);
915 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x80800000);
918 static void _PHY_PIModeSwitch(
919 struct adapter
*adapt
,
924 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
925 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
927 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("BB Switch to %s mode!\n", (PIMode
? "PI" : "SI")));
929 mode
= PIMode
? 0x01000100 : 0x01000000;
930 PHY_SetBBReg(adapt
, rFPGA0_XA_HSSIParameter1
, bMaskDWord
, mode
);
931 PHY_SetBBReg(adapt
, rFPGA0_XB_HSSIParameter1
, bMaskDWord
, mode
);
934 static bool phy_SimularityCompare_8188E(
935 struct adapter
*adapt
,
941 u32 i
, j
, diff
, sim_bitmap
, bound
= 0;
942 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
943 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
944 u8 final_candidate
[2] = {0xFF, 0xFF}; /* for path A and path B */
947 s32 tmp1
= 0, tmp2
= 0;
949 if ((dm_odm
->RFType
== ODM_2T2R
) || (dm_odm
->RFType
== ODM_2T3R
) || (dm_odm
->RFType
== ODM_2T4R
))
959 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("===> IQK:phy_SimularityCompare_8188E c1 %d c2 %d!!!\n", c1
, c2
));
963 for (i
= 0; i
< bound
; i
++) {
964 if ((i
== 1) || (i
== 3) || (i
== 5) || (i
== 7)) {
965 if ((resulta
[c1
][i
] & 0x00000200) != 0)
966 tmp1
= resulta
[c1
][i
] | 0xFFFFFC00;
968 tmp1
= resulta
[c1
][i
];
970 if ((resulta
[c2
][i
] & 0x00000200) != 0)
971 tmp2
= resulta
[c2
][i
] | 0xFFFFFC00;
973 tmp2
= resulta
[c2
][i
];
975 tmp1
= resulta
[c1
][i
];
976 tmp2
= resulta
[c2
][i
];
979 diff
= (tmp1
> tmp2
) ? (tmp1
- tmp2
) : (tmp2
- tmp1
);
981 if (diff
> MAX_TOLERANCE
) {
982 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
983 ("IQK:phy_SimularityCompare_8188E differnece overflow index %d compare1 0x%x compare2 0x%x!!!\n",
984 i
, resulta
[c1
][i
], resulta
[c2
][i
]));
986 if ((i
== 2 || i
== 6) && !sim_bitmap
) {
987 if (resulta
[c1
][i
] + resulta
[c1
][i
+1] == 0)
988 final_candidate
[(i
/4)] = c2
;
989 else if (resulta
[c2
][i
] + resulta
[c2
][i
+1] == 0)
990 final_candidate
[(i
/4)] = c1
;
992 sim_bitmap
= sim_bitmap
| (1<<i
);
994 sim_bitmap
= sim_bitmap
| (1<<i
);
999 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK:phy_SimularityCompare_8188E sim_bitmap %d !!!\n", sim_bitmap
));
1001 if (sim_bitmap
== 0) {
1002 for (i
= 0; i
< (bound
/4); i
++) {
1003 if (final_candidate
[i
] != 0xFF) {
1004 for (j
= i
*4; j
< (i
+1)*4-2; j
++)
1005 resulta
[3][j
] = resulta
[final_candidate
[i
]][j
];
1011 if (!(sim_bitmap
& 0x03)) { /* path A TX OK */
1012 for (i
= 0; i
< 2; i
++)
1013 resulta
[3][i
] = resulta
[c1
][i
];
1015 if (!(sim_bitmap
& 0x0c)) { /* path A RX OK */
1016 for (i
= 2; i
< 4; i
++)
1017 resulta
[3][i
] = resulta
[c1
][i
];
1020 if (!(sim_bitmap
& 0x30)) { /* path B TX OK */
1021 for (i
= 4; i
< 6; i
++)
1022 resulta
[3][i
] = resulta
[c1
][i
];
1025 if (!(sim_bitmap
& 0xc0)) { /* path B RX OK */
1026 for (i
= 6; i
< 8; i
++)
1027 resulta
[3][i
] = resulta
[c1
][i
];
1033 static void phy_IQCalibrate_8188E(struct adapter
*adapt
, s32 result
[][8], u8 t
, bool is2t
)
1035 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
1036 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
1038 u8 PathAOK
, PathBOK
;
1039 u32 ADDA_REG
[IQK_ADDA_REG_NUM
] = {
1040 rFPGA0_XCD_SwitchControl
, rBlue_Tooth
,
1041 rRx_Wait_CCA
, rTx_CCK_RFON
,
1042 rTx_CCK_BBON
, rTx_OFDM_RFON
,
1043 rTx_OFDM_BBON
, rTx_To_Rx
,
1045 rRx_OFDM
, rRx_Wait_RIFS
,
1046 rRx_TO_Rx
, rStandby
,
1047 rSleep
, rPMPD_ANAEN
};
1048 u32 IQK_MAC_REG
[IQK_MAC_REG_NUM
] = {
1049 REG_TXPAUSE
, REG_BCN_CTRL
,
1050 REG_BCN_CTRL_1
, REG_GPIO_MUXCFG
};
1052 /* since 92C & 92D have the different define in IQK_BB_REG */
1053 u32 IQK_BB_REG_92C
[IQK_BB_REG_NUM
] = {
1054 rOFDM0_TRxPathEnable
, rOFDM0_TRMuxPar
,
1055 rFPGA0_XCD_RFInterfaceSW
, rConfig_AntA
, rConfig_AntB
,
1056 rFPGA0_XAB_RFInterfaceSW
, rFPGA0_XA_RFInterfaceOE
,
1057 rFPGA0_XB_RFInterfaceOE
, rFPGA0_RFMOD
1061 if (*(dm_odm
->mp_mode
) == 1)
1065 /* Note: IQ calibration must be performed after loading */
1066 /* PHY_REG.txt , and radio_a, radio_b.txt */
1069 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQ Calibration for %s for %d times\n", (is2t
? "2T2R" : "1T1R"), t
));
1071 /* Save ADDA parameters, turn Path A ADDA on */
1072 _PHY_SaveADDARegisters(adapt
, ADDA_REG
, dm_odm
->RFCalibrateInfo
.ADDA_backup
, IQK_ADDA_REG_NUM
);
1073 _PHY_SaveMACRegisters(adapt
, IQK_MAC_REG
, dm_odm
->RFCalibrateInfo
.IQK_MAC_backup
);
1074 _PHY_SaveADDARegisters(adapt
, IQK_BB_REG_92C
, dm_odm
->RFCalibrateInfo
.IQK_BB_backup
, IQK_BB_REG_NUM
);
1076 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQ Calibration for %s for %d times\n", (is2t
? "2T2R" : "1T1R"), t
));
1078 _PHY_PathADDAOn(adapt
, ADDA_REG
, true, is2t
);
1080 dm_odm
->RFCalibrateInfo
.bRfPiEnable
= (u8
)PHY_QueryBBReg(adapt
, rFPGA0_XA_HSSIParameter1
, BIT(8));
1082 if (!dm_odm
->RFCalibrateInfo
.bRfPiEnable
) {
1083 /* Switch BB to PI mode to do IQ Calibration. */
1084 _PHY_PIModeSwitch(adapt
, true);
1088 PHY_SetBBReg(adapt
, rFPGA0_RFMOD
, BIT24
, 0x00);
1089 PHY_SetBBReg(adapt
, rOFDM0_TRxPathEnable
, bMaskDWord
, 0x03a05600);
1090 PHY_SetBBReg(adapt
, rOFDM0_TRMuxPar
, bMaskDWord
, 0x000800e4);
1091 PHY_SetBBReg(adapt
, rFPGA0_XCD_RFInterfaceSW
, bMaskDWord
, 0x22204000);
1093 PHY_SetBBReg(adapt
, rFPGA0_XAB_RFInterfaceSW
, BIT10
, 0x01);
1094 PHY_SetBBReg(adapt
, rFPGA0_XAB_RFInterfaceSW
, BIT26
, 0x01);
1095 PHY_SetBBReg(adapt
, rFPGA0_XA_RFInterfaceOE
, BIT10
, 0x00);
1096 PHY_SetBBReg(adapt
, rFPGA0_XB_RFInterfaceOE
, BIT10
, 0x00);
1099 PHY_SetBBReg(adapt
, rFPGA0_XA_LSSIParameter
, bMaskDWord
, 0x00010000);
1100 PHY_SetBBReg(adapt
, rFPGA0_XB_LSSIParameter
, bMaskDWord
, 0x00010000);
1104 _PHY_MACSettingCalibration(adapt
, IQK_MAC_REG
, dm_odm
->RFCalibrateInfo
.IQK_MAC_backup
);
1108 PHY_SetBBReg(adapt
, rConfig_AntA
, bMaskDWord
, 0x0f600000);
1111 PHY_SetBBReg(adapt
, rConfig_AntB
, bMaskDWord
, 0x0f600000);
1113 /* IQ calibration setting */
1114 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK setting!\n"));
1115 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0x80800000);
1116 PHY_SetBBReg(adapt
, rTx_IQK
, bMaskDWord
, 0x01007c00);
1117 PHY_SetBBReg(adapt
, rRx_IQK
, bMaskDWord
, 0x81004800);
1119 for (i
= 0; i
< retryCount
; i
++) {
1120 PathAOK
= phy_PathA_IQK_8188E(adapt
, is2t
);
1121 if (PathAOK
== 0x01) {
1122 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A Tx IQK Success!!\n"));
1123 result
[t
][0] = (PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_A
, bMaskDWord
)&0x3FF0000)>>16;
1124 result
[t
][1] = (PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_A
, bMaskDWord
)&0x3FF0000)>>16;
1129 for (i
= 0; i
< retryCount
; i
++) {
1130 PathAOK
= phy_PathA_RxIQK(adapt
, is2t
);
1131 if (PathAOK
== 0x03) {
1132 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A Rx IQK Success!!\n"));
1133 result
[t
][2] = (PHY_QueryBBReg(adapt
, rRx_Power_Before_IQK_A_2
, bMaskDWord
)&0x3FF0000)>>16;
1134 result
[t
][3] = (PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_A_2
, bMaskDWord
)&0x3FF0000)>>16;
1137 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A Rx IQK Fail!!\n"));
1141 if (0x00 == PathAOK
) {
1142 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path A IQK failed!!\n"));
1146 _PHY_PathAStandBy(adapt
);
1148 /* Turn Path B ADDA on */
1149 _PHY_PathADDAOn(adapt
, ADDA_REG
, false, is2t
);
1151 for (i
= 0; i
< retryCount
; i
++) {
1152 PathBOK
= phy_PathB_IQK_8188E(adapt
);
1153 if (PathBOK
== 0x03) {
1154 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path B IQK Success!!\n"));
1155 result
[t
][4] = (PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_B
, bMaskDWord
)&0x3FF0000)>>16;
1156 result
[t
][5] = (PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_B
, bMaskDWord
)&0x3FF0000)>>16;
1157 result
[t
][6] = (PHY_QueryBBReg(adapt
, rRx_Power_Before_IQK_B_2
, bMaskDWord
)&0x3FF0000)>>16;
1158 result
[t
][7] = (PHY_QueryBBReg(adapt
, rRx_Power_After_IQK_B_2
, bMaskDWord
)&0x3FF0000)>>16;
1160 } else if (i
== (retryCount
- 1) && PathBOK
== 0x01) { /* Tx IQK OK */
1161 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path B Only Tx IQK Success!!\n"));
1162 result
[t
][4] = (PHY_QueryBBReg(adapt
, rTx_Power_Before_IQK_B
, bMaskDWord
)&0x3FF0000)>>16;
1163 result
[t
][5] = (PHY_QueryBBReg(adapt
, rTx_Power_After_IQK_B
, bMaskDWord
)&0x3FF0000)>>16;
1167 if (0x00 == PathBOK
) {
1168 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("Path B IQK failed!!\n"));
1172 /* Back to BB mode, load original value */
1173 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK:Back to BB mode, load original value!\n"));
1174 PHY_SetBBReg(adapt
, rFPGA0_IQK
, bMaskDWord
, 0);
1177 if (!dm_odm
->RFCalibrateInfo
.bRfPiEnable
) {
1178 /* Switch back BB to SI mode after finish IQ Calibration. */
1179 _PHY_PIModeSwitch(adapt
, false);
1182 /* Reload ADDA power saving parameters */
1183 reload_adda_reg(adapt
, ADDA_REG
, dm_odm
->RFCalibrateInfo
.ADDA_backup
, IQK_ADDA_REG_NUM
);
1185 /* Reload MAC parameters */
1186 _PHY_ReloadMACRegisters(adapt
, IQK_MAC_REG
, dm_odm
->RFCalibrateInfo
.IQK_MAC_backup
);
1188 reload_adda_reg(adapt
, IQK_BB_REG_92C
, dm_odm
->RFCalibrateInfo
.IQK_BB_backup
, IQK_BB_REG_NUM
);
1190 /* Restore RX initial gain */
1191 PHY_SetBBReg(adapt
, rFPGA0_XA_LSSIParameter
, bMaskDWord
, 0x00032ed3);
1193 PHY_SetBBReg(adapt
, rFPGA0_XB_LSSIParameter
, bMaskDWord
, 0x00032ed3);
1195 /* load 0xe30 IQC default value */
1196 PHY_SetBBReg(adapt
, rTx_IQK_Tone_A
, bMaskDWord
, 0x01008c00);
1197 PHY_SetBBReg(adapt
, rRx_IQK_Tone_A
, bMaskDWord
, 0x01008c00);
1199 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("phy_IQCalibrate_8188E() <==\n"));
1202 static void phy_LCCalibrate_8188E(struct adapter
*adapt
, bool is2t
)
1205 u32 RF_Amode
= 0, RF_Bmode
= 0, LC_Cal
;
1207 /* Check continuous TX and Packet TX */
1208 tmpreg
= rtw_read8(adapt
, 0xd03);
1210 if ((tmpreg
&0x70) != 0) /* Deal with contisuous TX case */
1211 usb_write8(adapt
, 0xd03, tmpreg
&0x8F); /* disable all continuous TX */
1212 else /* Deal with Packet TX case */
1213 usb_write8(adapt
, REG_TXPAUSE
, 0xFF); /* block all queues */
1215 if ((tmpreg
&0x70) != 0) {
1216 /* 1. Read original RF mode */
1218 RF_Amode
= PHY_QueryRFReg(adapt
, RF_PATH_A
, RF_AC
, bMask12Bits
);
1222 RF_Bmode
= PHY_QueryRFReg(adapt
, RF_PATH_B
, RF_AC
, bMask12Bits
);
1224 /* 2. Set RF mode = standby mode */
1226 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_AC
, bMask12Bits
, (RF_Amode
&0x8FFFF)|0x10000);
1230 PHY_SetRFReg(adapt
, RF_PATH_B
, RF_AC
, bMask12Bits
, (RF_Bmode
&0x8FFFF)|0x10000);
1233 /* 3. Read RF reg18 */
1234 LC_Cal
= PHY_QueryRFReg(adapt
, RF_PATH_A
, RF_CHNLBW
, bMask12Bits
);
1236 /* 4. Set LC calibration begin bit15 */
1237 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_CHNLBW
, bMask12Bits
, LC_Cal
|0x08000);
1241 /* Restore original situation */
1242 if ((tmpreg
&0x70) != 0) {
1243 /* Deal with continuous TX case */
1245 usb_write8(adapt
, 0xd03, tmpreg
);
1246 PHY_SetRFReg(adapt
, RF_PATH_A
, RF_AC
, bMask12Bits
, RF_Amode
);
1250 PHY_SetRFReg(adapt
, RF_PATH_B
, RF_AC
, bMask12Bits
, RF_Bmode
);
1252 /* Deal with Packet TX case */
1253 usb_write8(adapt
, REG_TXPAUSE
, 0x00);
1257 void PHY_IQCalibrate_8188E(struct adapter
*adapt
, bool recovery
)
1259 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
1260 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
1261 struct mpt_context
*pMptCtx
= &(adapt
->mppriv
.MptCtx
);
1262 s32 result
[4][8]; /* last is final result */
1263 u8 i
, final_candidate
, Indexforchannel
;
1264 bool pathaok
, pathbok
;
1265 s32 RegE94
, RegE9C
, RegEA4
, RegEAC
, RegEB4
, RegEBC
, RegEC4
, RegECC
;
1266 bool is12simular
, is13simular
, is23simular
;
1267 bool singletone
= false, carrier_sup
= false;
1268 u32 IQK_BB_REG_92C
[IQK_BB_REG_NUM
] = {
1269 rOFDM0_XARxIQImbalance
, rOFDM0_XBRxIQImbalance
,
1270 rOFDM0_ECCAThreshold
, rOFDM0_AGCRSSITable
,
1271 rOFDM0_XATxIQImbalance
, rOFDM0_XBTxIQImbalance
,
1272 rOFDM0_XCTxAFE
, rOFDM0_XDTxAFE
,
1273 rOFDM0_RxIQExtAnta
};
1276 is2t
= (dm_odm
->RFType
== ODM_2T2R
) ? true : false;
1278 if (!(dm_odm
->SupportAbility
& ODM_RF_CALIBRATION
))
1281 if (*(dm_odm
->mp_mode
) == 1) {
1282 singletone
= pMptCtx
->bSingleTone
;
1283 carrier_sup
= pMptCtx
->bCarrierSuppression
;
1286 /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1287 if (singletone
|| carrier_sup
)
1291 ODM_RT_TRACE(dm_odm
, ODM_COMP_INIT
, ODM_DBG_LOUD
, ("PHY_IQCalibrate_8188E: Return due to recovery!\n"));
1292 reload_adda_reg(adapt
, IQK_BB_REG_92C
, dm_odm
->RFCalibrateInfo
.IQK_BB_backup_recover
, 9);
1295 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK:Start!!!\n"));
1297 for (i
= 0; i
< 8; i
++) {
1301 if ((i
== 0) || (i
== 2) || (i
== 4) || (i
== 6))
1302 result
[3][i
] = 0x100;
1306 final_candidate
= 0xff;
1309 is12simular
= false;
1310 is23simular
= false;
1311 is13simular
= false;
1313 for (i
= 0; i
< 3; i
++) {
1314 phy_IQCalibrate_8188E(adapt
, result
, i
, is2t
);
1317 is12simular
= phy_SimularityCompare_8188E(adapt
, result
, 0, 1);
1319 final_candidate
= 0;
1320 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK: is12simular final_candidate is %x\n", final_candidate
));
1326 is13simular
= phy_SimularityCompare_8188E(adapt
, result
, 0, 2);
1328 final_candidate
= 0;
1329 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK: is13simular final_candidate is %x\n", final_candidate
));
1333 is23simular
= phy_SimularityCompare_8188E(adapt
, result
, 1, 2);
1335 final_candidate
= 1;
1336 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK: is23simular final_candidate is %x\n", final_candidate
));
1338 final_candidate
= 3;
1343 for (i
= 0; i
< 4; i
++) {
1344 RegE94
= result
[i
][0];
1345 RegE9C
= result
[i
][1];
1346 RegEA4
= result
[i
][2];
1347 RegEAC
= result
[i
][3];
1348 RegEB4
= result
[i
][4];
1349 RegEBC
= result
[i
][5];
1350 RegEC4
= result
[i
][6];
1351 RegECC
= result
[i
][7];
1352 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
1353 ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1354 RegE94
, RegE9C
, RegEA4
, RegEAC
, RegEB4
, RegEBC
, RegEC4
, RegECC
));
1357 if (final_candidate
!= 0xff) {
1358 RegE94
= result
[final_candidate
][0];
1359 RegE9C
= result
[final_candidate
][1];
1360 RegEA4
= result
[final_candidate
][2];
1361 RegEAC
= result
[final_candidate
][3];
1362 RegEB4
= result
[final_candidate
][4];
1363 RegEBC
= result
[final_candidate
][5];
1364 dm_odm
->RFCalibrateInfo
.RegE94
= RegE94
;
1365 dm_odm
->RFCalibrateInfo
.RegE9C
= RegE9C
;
1366 dm_odm
->RFCalibrateInfo
.RegEB4
= RegEB4
;
1367 dm_odm
->RFCalibrateInfo
.RegEBC
= RegEBC
;
1368 RegEC4
= result
[final_candidate
][6];
1369 RegECC
= result
[final_candidate
][7];
1370 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
1371 ("IQK: final_candidate is %x\n", final_candidate
));
1372 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
1373 ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1374 RegE94
, RegE9C
, RegEA4
, RegEAC
, RegEB4
, RegEBC
, RegEC4
, RegECC
));
1378 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK: FAIL use default value\n"));
1379 dm_odm
->RFCalibrateInfo
.RegE94
= 0x100;
1380 dm_odm
->RFCalibrateInfo
.RegEB4
= 0x100; /* X default value */
1381 dm_odm
->RFCalibrateInfo
.RegE9C
= 0x0;
1382 dm_odm
->RFCalibrateInfo
.RegEBC
= 0x0; /* Y default value */
1385 patha_fill_iqk(adapt
, pathaok
, result
, final_candidate
, (RegEA4
== 0));
1388 pathb_fill_iqk(adapt
, pathbok
, result
, final_candidate
, (RegEC4
== 0));
1391 Indexforchannel
= ODM_GetRightChnlPlaceforIQK(pHalData
->CurrentChannel
);
1393 /* To Fix BSOD when final_candidate is 0xff */
1394 /* by sherry 20120321 */
1395 if (final_candidate
< 4) {
1396 for (i
= 0; i
< IQK_Matrix_REG_NUM
; i
++)
1397 dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].Value
[0][i
] = result
[final_candidate
][i
];
1398 dm_odm
->RFCalibrateInfo
.IQKMatrixRegSetting
[Indexforchannel
].bIQKDone
= true;
1400 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("\nIQK OK Indexforchannel %d.\n", Indexforchannel
));
1402 _PHY_SaveADDARegisters(adapt
, IQK_BB_REG_92C
, dm_odm
->RFCalibrateInfo
.IQK_BB_backup_recover
, 9);
1404 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
, ("IQK finished\n"));
1407 void PHY_LCCalibrate_8188E(struct adapter
*adapt
)
1409 bool singletone
= false, carrier_sup
= false;
1410 u32 timeout
= 2000, timecount
= 0;
1411 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
1412 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
1413 struct mpt_context
*pMptCtx
= &(adapt
->mppriv
.MptCtx
);
1415 if (*(dm_odm
->mp_mode
) == 1) {
1416 singletone
= pMptCtx
->bSingleTone
;
1417 carrier_sup
= pMptCtx
->bCarrierSuppression
;
1419 if (!(dm_odm
->SupportAbility
& ODM_RF_CALIBRATION
))
1421 /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1422 if (singletone
|| carrier_sup
)
1425 while (*(dm_odm
->pbScanInProcess
) && timecount
< timeout
) {
1430 dm_odm
->RFCalibrateInfo
.bLCKInProgress
= true;
1432 if (dm_odm
->RFType
== ODM_2T2R
) {
1433 phy_LCCalibrate_8188E(adapt
, true);
1436 phy_LCCalibrate_8188E(adapt
, false);
1439 dm_odm
->RFCalibrateInfo
.bLCKInProgress
= false;
1441 ODM_RT_TRACE(dm_odm
, ODM_COMP_CALIBRATION
, ODM_DBG_LOUD
,
1442 ("LCK:Finish!!!interface %d\n", dm_odm
->InterfaceIndex
));
1445 static void phy_setrfpathswitch_8188e(struct adapter
*adapt
, bool main
, bool is2t
)
1447 if (!adapt
->hw_init_completed
) {
1449 u1btmp
= rtw_read8(adapt
, REG_LEDCFG2
) | BIT7
;
1450 usb_write8(adapt
, REG_LEDCFG2
, u1btmp
);
1451 PHY_SetBBReg(adapt
, rFPGA0_XAB_RFParameter
, BIT13
, 0x01);
1454 if (is2t
) { /* 92C */
1456 PHY_SetBBReg(adapt
, rFPGA0_XB_RFInterfaceOE
, BIT5
|BIT6
, 0x1); /* 92C_Path_A */
1458 PHY_SetBBReg(adapt
, rFPGA0_XB_RFInterfaceOE
, BIT5
|BIT6
, 0x2); /* BT */
1461 PHY_SetBBReg(adapt
, rFPGA0_XA_RFInterfaceOE
, BIT8
|BIT9
, 0x2); /* Main */
1463 PHY_SetBBReg(adapt
, rFPGA0_XA_RFInterfaceOE
, BIT8
|BIT9
, 0x1); /* Aux */
1467 void PHY_SetRFPathSwitch_8188E(struct adapter
*adapt
, bool main
)
1469 struct hal_data_8188e
*pHalData
= GET_HAL_DATA(adapt
);
1470 struct odm_dm_struct
*dm_odm
= &pHalData
->odmpriv
;
1472 if (dm_odm
->RFType
== ODM_2T2R
) {
1473 phy_setrfpathswitch_8188e(adapt
, main
, true);
1476 phy_setrfpathswitch_8188e(adapt
, main
, false);