1 /******************************************************************************
3 * Copyright(c) 2007 - 2016 Realtek Corporation.
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 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
26 #include "../mp_precomp.h"
27 #include "../phydm_precomp.h"
29 static void phydm_dynamic_switch_htstf_mumimo_8822b(struct phy_dm_struct *dm)
31 /*if rssi > 40dBm, enable HT-STF gain controller,
32 *otherwise, if rssi < 40dBm, disable the controller
34 /*add by Chun-Hung Ho 20160711 */
35 if (dm->rssi_min >= 40)
36 odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x1);
37 else if (dm->rssi_min < 35)
38 odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x0);
40 ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s, rssi_min = %d\n", __func__,
44 static void _set_tx_a_cali_value(struct phy_dm_struct *dm, u8 rf_path,
45 u8 offset, u8 tx_a_bias_offset)
47 u32 modi_tx_a_value = 0;
49 bool is_minus = false;
54 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10124);
57 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10524);
60 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10924);
63 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10D24);
66 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30164);
69 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30564);
72 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30964);
75 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30D64);
78 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50195);
81 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50595);
84 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50995);
87 odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50D95);
90 ODM_RT_TRACE(dm, ODM_COMP_COMMON,
91 "Invalid TxA band offset...\n");
96 modi_tx_a_value = odm_get_rf_reg(dm, rf_path, 0x61, 0xFFFFF);
97 tmp1_byte = (u8)modi_tx_a_value & (BIT(3) | BIT(2) | BIT(1) | BIT(0));
99 /* check how much need to calibration */
100 switch (tx_a_bias_offset) {
136 /* do nothing case */
139 ODM_RT_TRACE(dm, ODM_COMP_COMMON,
140 "No need to do TxA bias current calibration\n");
144 /* calc correct value to calibrate */
146 if (tmp1_byte >= comp_value) {
147 tmp1_byte -= comp_value;
148 /*modi_tx_a_value += tmp1_byte;*/
153 tmp1_byte += comp_value;
158 /* Write back to RF reg */
159 odm_set_rf_reg(dm, rf_path, 0x30, 0xFFFF,
160 (offset << 12 | (modi_tx_a_value & 0xFF0) | tmp1_byte));
163 static void _txa_bias_cali_4_each_path(struct phy_dm_struct *dm, u8 rf_path,
166 /* switch on set TxA bias */
167 odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x200);
169 /* Set 12 sets of TxA value */
170 _set_tx_a_cali_value(dm, rf_path, 0x0, efuse_value);
171 _set_tx_a_cali_value(dm, rf_path, 0x1, efuse_value);
172 _set_tx_a_cali_value(dm, rf_path, 0x2, efuse_value);
173 _set_tx_a_cali_value(dm, rf_path, 0x3, efuse_value);
174 _set_tx_a_cali_value(dm, rf_path, 0x4, efuse_value);
175 _set_tx_a_cali_value(dm, rf_path, 0x5, efuse_value);
176 _set_tx_a_cali_value(dm, rf_path, 0x6, efuse_value);
177 _set_tx_a_cali_value(dm, rf_path, 0x7, efuse_value);
178 _set_tx_a_cali_value(dm, rf_path, 0x8, efuse_value);
179 _set_tx_a_cali_value(dm, rf_path, 0x9, efuse_value);
180 _set_tx_a_cali_value(dm, rf_path, 0xa, efuse_value);
181 _set_tx_a_cali_value(dm, rf_path, 0xb, efuse_value);
183 /* switch off set TxA bias */
184 odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x0);
188 * for 8822B PCIE D-cut patch only
189 * Normal driver and MP driver need this patch
192 void phydm_txcurrentcalibration(struct phy_dm_struct *dm)
194 u8 efuse0x3D8, efuse0x3D7;
195 u32 orig_rf0x18_path_a = 0, orig_rf0x18_path_b = 0;
197 /* save original 0x18 value */
198 orig_rf0x18_path_a = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF);
199 orig_rf0x18_path_b = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF);
201 /* define efuse content */
202 efuse0x3D8 = dm->efuse0x3d8;
203 efuse0x3D7 = dm->efuse0x3d7;
205 /* check efuse content to judge whether need to calibration or not */
206 if (efuse0x3D7 == 0xFF) {
209 "efuse content 0x3D7 == 0xFF, No need to do TxA cali\n");
213 /* write RF register for calibration */
214 _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_A, efuse0x3D7);
215 _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_B, efuse0x3D8);
217 /* restore original 0x18 value */
218 odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF, orig_rf0x18_path_a);
219 odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF, orig_rf0x18_path_b);
222 void phydm_hwsetting_8822b(struct phy_dm_struct *dm)
224 phydm_dynamic_switch_htstf_mumimo_8822b(dm);