xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723bs/hal/phydm/phydm_math_lib.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 
16 /* ************************************************************
17  * include files
18  * ************************************************************ */
19 
20 #include "mp_precomp.h"
21 #include "phydm_precomp.h"
22 
23 const u16 db_invert_table[12][8] = {
24 	{	1,		1,		1,		2,		2,		2,		2,		3},
25 	{	3,		3,		4,		4,		4,		5,		6,		6},
26 	{	7,		8,		9,		10,		11,		13,		14,		16},
27 	{	18,		20,		22,		25,		28,		32,		35,		40},
28 	{	45,		50,		56,		63,		71,		79,		89,		100},
29 	{	112,		126,		141,		158,		178,		200,		224,		251},
30 	{	282,		316,		355,		398,		447,		501,		562,		631},
31 	{	708,		794,		891,		1000,	1122,	1259,	1413,	1585},
32 	{	1778,	1995,	2239,	2512,	2818,	3162,	3548,	3981},
33 	{	4467,	5012,	5623,	6310,	7079,	7943,	8913,	10000},
34 	{	11220,	12589,	14125,	15849,	17783,	19953,	22387,	25119},
35 	{	28184,	31623,	35481,	39811,	44668,	50119,	56234,	65535}
36 };
37 
38 
39 /*Y = 10*log(X)*/
40 s32
odm_pwdb_conversion(s32 X,u32 total_bit,u32 decimal_bit)41 odm_pwdb_conversion(
42 	s32 X,
43 	u32 total_bit,
44 	u32 decimal_bit
45 )
46 {
47 	s32 Y, integer = 0, decimal = 0;
48 	u32 i;
49 
50 	if (X == 0)
51 		X = 1; /* log2(x), x can't be 0 */
52 
53 	for (i = (total_bit - 1); i > 0; i--) {
54 		if (X & BIT(i)) {
55 			integer = i;
56 			if (i > 0)
57 				decimal = (X & BIT(i - 1)) ? 2 : 0; /* decimal is 0.5dB*3=1.5dB~=2dB */
58 			break;
59 		}
60 	}
61 
62 	Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
63 
64 	return Y;
65 }
66 
67 s32
odm_sign_conversion(s32 value,u32 total_bit)68 odm_sign_conversion(
69 	s32 value,
70 	u32 total_bit
71 )
72 {
73 	if (value & BIT(total_bit - 1))
74 		value -= BIT(total_bit);
75 
76 	return value;
77 }
78 
79 void
phydm_seq_sorting(void * p_dm_void,u32 * p_value,u32 * rank_idx,u32 * p_idx_out,u8 seq_length)80 phydm_seq_sorting(
81 	void	*p_dm_void,
82 	u32	*p_value,
83 	u32	*rank_idx,
84 	u32	*p_idx_out,
85 	u8	seq_length
86 )
87 {
88 	u8		i = 0, j = 0;
89 	u32		tmp_a, tmp_b;
90 	u32		tmp_idx_a, tmp_idx_b;
91 
92 	for (i = 0; i < seq_length; i++) {
93 		rank_idx[i] = i;
94 		/**/
95 	}
96 
97 	for (i = 0; i < (seq_length - 1); i++) {
98 
99 		for (j = 0; j < (seq_length - 1 - i); j++) {
100 
101 			tmp_a = p_value[j];
102 			tmp_b = p_value[j + 1];
103 
104 			tmp_idx_a = rank_idx[j];
105 			tmp_idx_b = rank_idx[j + 1];
106 
107 			if (tmp_a < tmp_b) {
108 				p_value[j] = tmp_b;
109 				p_value[j + 1] = tmp_a;
110 
111 				rank_idx[j] = tmp_idx_b;
112 				rank_idx[j + 1] = tmp_idx_a;
113 			}
114 		}
115 	}
116 
117 	for (i = 0; i < seq_length; i++) {
118 		p_idx_out[rank_idx[i]] = i + 1;
119 		/**/
120 	}
121 }
122 
123 u32
odm_convert_to_db(u32 value)124 odm_convert_to_db(
125 	u32	value)
126 {
127 	u8 i;
128 	u8 j;
129 	u32 dB;
130 
131 	value = value & 0xFFFF;
132 
133 	for (i = 0; i < 12; i++) {
134 		if (value <= db_invert_table[i][7])
135 			break;
136 	}
137 
138 	if (i >= 12) {
139 		return 96;	/* maximum 96 dB */
140 	}
141 
142 	for (j = 0; j < 8; j++) {
143 		if (value <= db_invert_table[i][j])
144 			break;
145 	}
146 
147 	dB = (i << 3) + j + 1;
148 
149 	return dB;
150 }
151 
152 u32
odm_convert_to_linear(u32 value)153 odm_convert_to_linear(
154 	u32	value)
155 {
156 	u8 i;
157 	u8 j;
158 	u32 linear;
159 
160 	/* 1dB~96dB */
161 
162 	value = value & 0xFF;
163 
164 	i = (u8)((value - 1) >> 3);
165 	j = (u8)(value - 1) - (i << 3);
166 
167 	linear = db_invert_table[i][j];
168 
169 	return linear;
170 }
171 
172