1 /******************************************************************************
3 * Copyright(c) 2007 - 2017 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 /******************************************************************************
28 *****************************************************************************/
29 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
32 #ifdef CONFIG_PSD_TOOL
33 u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi)
35 struct dm_struct *dm = (struct dm_struct *)dm_void;
36 struct psd_info *dm_psd_table = &dm->dm_psd_table;
39 odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff, psd_tone_idx);
41 odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), 1); /*PSD trigger start*/
43 odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), 0); /*PSD trigger stop*/
45 if (dm->support_ic_type & ODM_RTL8821C) {
46 psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg,
48 psd_report = psd_report >> 5;
50 psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg,
53 psd_report = odm_convert_to_db(psd_report) + igi;
58 u8 psd_result_cali_tone_8821[7] = {21, 28, 33, 93, 98, 105, 127};
59 u8 psd_result_cali_val_8821[7] = {67, 69, 71, 72, 71, 69, 67};
61 void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point)
63 struct dm_struct *dm = (struct dm_struct *)dm_void;
64 struct psd_info *dm_psd_table = &dm->dm_psd_table;
65 u32 i = 0, mod_tone_idx;
70 u16 psd_fc_channel = dm_psd_table->psd_fc_channel;
71 u8 ag_rf_mode_reg = 0;
73 u32 psd_result_tmp = 0;
75 u8 psd_result_cali_tone[7] = {0};
76 u8 psd_result_cali_val[7] = {0};
77 u8 noise_table_idx = 0;
80 if (dm->support_ic_type == ODM_RTL8821) {
81 odm_move_memory(dm, psd_result_cali_tone,
82 psd_result_cali_tone_8821, 7);
83 odm_move_memory(dm, psd_result_cali_val,
84 psd_result_cali_val_8821, 7);
87 dm_psd_table->psd_in_progress = 1;
90 dm->support_ability &= ~(ODM_BB_DIG);
91 dm->support_ability &= ~(ODM_BB_FA_CNT);
93 PHYDM_DBG(dm, ODM_COMP_API, "PSD Start =>\n");
95 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
96 psd_igi_a_reg = 0xc50;
97 psd_igi_b_reg = 0xe50;
99 psd_igi_a_reg = 0xc50;
100 psd_igi_b_reg = 0xc58;
104 dm_psd_table->initial_gain_backup = odm_get_bb_reg(dm, psd_igi_a_reg,
106 odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, 0x6e); /*@IGI target at 0dBm & make it can't CCA*/
107 odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, 0x6e); /*@IGI target at 0dBm & make it can't CCA*/
110 if (phydm_stop_ic_trx(dm, PHYDM_SET) == PHYDM_SET_FAIL) {
111 PHYDM_DBG(dm, ODM_COMP_API, "STOP_TRX_FAIL\n");
116 odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, igi);
117 odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, igi);
120 dm_psd_table->rf_0x18_bkp = odm_get_rf_reg(dm, RF_PATH_A, RF_0x18,
122 dm_psd_table->rf_0x18_bkp_b = odm_get_rf_reg(dm, RF_PATH_B, RF_0x18,
125 if (psd_fc_channel > 14) {
127 if (psd_fc_channel >= 36 && psd_fc_channel <= 64)
128 ag_rf_mode_reg = 0x1;
129 else if (psd_fc_channel >= 100 && psd_fc_channel <= 140)
130 ag_rf_mode_reg = 0x3;
131 else if (psd_fc_channel > 140)
132 ag_rf_mode_reg = 0x5;
136 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0xff, psd_fc_channel); /* Set RF fc*/
137 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x300, rf_reg18_9_8);
138 /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
139 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0xc00,
140 dm_psd_table->psd_bw_rf_reg);
141 /* Set RF ag fc mode*/
142 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0xf0000, ag_rf_mode_reg);
145 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0xff, psd_fc_channel); /* Set RF fc*/
146 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x300, rf_reg18_9_8);
147 /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
148 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0xc00,
149 dm_psd_table->psd_bw_rf_reg);
150 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0xf0000, ag_rf_mode_reg); /* Set RF ag fc mode*/
152 PHYDM_DBG(dm, ODM_COMP_API, "0xc50=((0x%x))\n",
153 odm_get_bb_reg(dm, R_0xc50, MASKDWORD));
155 /*PHYDM_DBG(dm, ODM_COMP_API, "RF0x0=((0x%x))\n", odm_get_rf_reg(dm, RF_PATH_A, RF_0x0, RFREGOFFSETMASK));*/
157 PHYDM_DBG(dm, ODM_COMP_API, "RF0x18=((0x%x))\n",
158 odm_get_rf_reg(dm, RF_PATH_A, RF_0x18, RFREGOFFSETMASK));
161 phydm_stop_3_wire(dm, PHYDM_SET);
165 if (stop_point > (dm_psd_table->fft_smp_point - 1))
166 stop_point = (dm_psd_table->fft_smp_point - 1);
168 if (start_point > (dm_psd_table->fft_smp_point - 1))
169 start_point = (dm_psd_table->fft_smp_point - 1);
171 if (start_point > stop_point)
172 stop_point = start_point;
174 for (i = start_point; i <= stop_point; i++) {
175 fft_max_half_bw = (dm_psd_table->fft_smp_point) >> 1;
177 if (i < fft_max_half_bw)
178 mod_tone_idx = i + fft_max_half_bw;
180 mod_tone_idx = i - fft_max_half_bw;
183 for (t = 0; t < dm_psd_table->sw_avg_time; t++)
184 psd_result_tmp += phydm_get_psd_data(dm, mod_tone_idx,
187 (u8)((psd_result_tmp / dm_psd_table->sw_avg_time)) -
188 dm_psd_table->psd_pwr_common_offset;
190 if (dm_psd_table->fft_smp_point == 128 &&
191 dm_psd_table->noise_k_en) {
192 if (i > psd_result_cali_tone[noise_table_idx])
195 if (noise_table_idx > 6)
198 if (psd_result >= psd_result_cali_val[noise_table_idx])
201 psd_result_cali_val[noise_table_idx];
205 dm_psd_table->psd_result[i] = psd_result;
208 PHYDM_DBG(dm, ODM_COMP_API, "[%d] N_cali = %d, PSD = %d\n",
209 mod_tone_idx, psd_result_cali_val[noise_table_idx],
214 phydm_stop_3_wire(dm, PHYDM_REVERT);
219 set_result = phydm_stop_ic_trx(dm, PHYDM_REVERT);
221 odm_set_bb_reg(dm, psd_igi_a_reg, 0xff,
222 dm_psd_table->initial_gain_backup);
223 odm_set_bb_reg(dm, psd_igi_b_reg, 0xff,
224 dm_psd_table->initial_gain_backup);
226 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREGOFFSETMASK,
227 dm_psd_table->rf_0x18_bkp);
228 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, RFREGOFFSETMASK,
229 dm_psd_table->rf_0x18_bkp_b);
231 PHYDM_DBG(dm, ODM_COMP_API, "PSD finished\n\n");
233 dm->support_ability |= ODM_BB_DIG;
234 dm->support_ability |= ODM_BB_FA_CNT;
235 dm_psd_table->psd_in_progress = 0;
238 void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time,
239 u8 hw_avg_time, u8 i_q_setting,
240 u16 fft_smp_point, u8 ant_sel,
241 u8 psd_input, u8 channel, u8 noise_k_en)
243 struct dm_struct *dm = (struct dm_struct *)dm_void;
244 struct psd_info *dm_psd_table = &dm->dm_psd_table;
245 u8 fft_smp_point_idx = 0;
247 dm_psd_table->fft_smp_point = fft_smp_point;
249 if (sw_avg_time == 0)
252 dm_psd_table->sw_avg_time = sw_avg_time;
253 dm_psd_table->psd_fc_channel = channel;
254 dm_psd_table->noise_k_en = noise_k_en;
256 if (fft_smp_point == 128)
257 fft_smp_point_idx = 0;
258 else if (fft_smp_point == 256)
259 fft_smp_point_idx = 1;
260 else if (fft_smp_point == 512)
261 fft_smp_point_idx = 2;
262 else if (fft_smp_point == 1024)
263 fft_smp_point_idx = 3;
265 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
266 odm_set_bb_reg(dm, R_0x910, BIT(11) | BIT(10), i_q_setting);
267 odm_set_bb_reg(dm, R_0x910, BIT(13) | BIT(12), hw_avg_time);
268 odm_set_bb_reg(dm, R_0x910, BIT(15) | BIT(14),
270 odm_set_bb_reg(dm, R_0x910, BIT(17) | BIT(16), ant_sel);
271 odm_set_bb_reg(dm, R_0x910, BIT(23), psd_input);
273 } else { /*ODM_IC_11N_SERIES*/
277 /*@bw = (*dm->band_width); //ODM_BW20M */
278 /*@channel = *(dm->channel);*/
281 void phydm_psd_init(void *dm_void)
283 struct dm_struct *dm = (struct dm_struct *)dm_void;
284 struct psd_info *dm_psd_table = &dm->dm_psd_table;
286 PHYDM_DBG(dm, ODM_COMP_API, "PSD para init\n");
288 dm_psd_table->psd_in_progress = false;
290 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
291 dm_psd_table->psd_reg = 0x910;
292 dm_psd_table->psd_report_reg = 0xF44;
294 if (ODM_IC_11AC_2_SERIES)
295 /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
296 dm_psd_table->psd_bw_rf_reg = 1;
298 /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
299 dm_psd_table->psd_bw_rf_reg = 2;
302 dm_psd_table->psd_reg = 0x808;
303 dm_psd_table->psd_report_reg = 0x8B4;
304 /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
305 dm_psd_table->psd_bw_rf_reg = 2;
308 dm_psd_table->psd_pwr_common_offset = 0;
310 phydm_psd_para_setting(dm, 1, 2, 3, 128, 0, 0, 7, 0);
312 /*phydm_psd(dm, 0x3c, 0, 127);*/ /* target at -50dBm */
316 void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used,
317 char *output, u32 *_out_len)
319 struct dm_struct *dm = (struct dm_struct *)dm_void;
323 u32 out_len = *_out_len;
326 if ((strcmp(input[1], help) == 0)) {
327 PDM_SNPF(out_len, used, output + used, out_len - used,
328 "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)} {path_sel 0~3} {0:ADC, 1:RXIQC} {CH} {noise_k}\n");
329 PDM_SNPF(out_len, used, output + used, out_len - used,
330 "{1} {IGI(hex)} {start_point} {stop_point}\n");
334 PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
337 for (i = 1; i < 10; i++) {
339 PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
343 PDM_SNPF(out_len, used, output + used, out_len - used,
344 "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n",
345 var1[1], var1[2], var1[3], var1[4], var1[5], var1[6],
346 (u8)var1[7], (u8)var1[8]);
347 phydm_psd_para_setting(dm, (u8)var1[1], (u8)var1[2],
348 (u8)var1[3], (u16)var1[4], (u8)var1[5],
349 (u8)var1[6], (u8)var1[7], (u8)var1[8]);
351 } else if (var1[0] == 1) {
352 PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]);
353 PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]);
354 PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]);
355 PDM_SNPF(out_len, used, output + used, out_len - used,
356 "IGI=((0x%x)), start_point=((%d)), stop_point=((%d))\n",
357 var1[1], var1[2], var1[3]);
358 dm->debug_components |= ODM_COMP_API;
359 phydm_psd(dm, var1[1], (u16)var1[2], (u16)var1[3]);
360 dm->debug_components &= (~ODM_COMP_API);
368 u8 phydm_get_psd_result_table(void *dm_void, int index)
370 struct dm_struct *dm = (struct dm_struct *)dm_void;
371 struct psd_info *dm_psd_table = &dm->dm_psd_table;
375 result = dm_psd_table->psd_result[index];