1*6d67aabdSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2*6d67aabdSBjoern A. Zeeb /* Copyright(c) 2024 Realtek Corporation 3*6d67aabdSBjoern A. Zeeb */ 4*6d67aabdSBjoern A. Zeeb 5*6d67aabdSBjoern A. Zeeb #include "util.h" 6*6d67aabdSBjoern A. Zeeb 7*6d67aabdSBjoern A. Zeeb #define FRAC_ROWS 3 8*6d67aabdSBjoern A. Zeeb #define FRAC_ROW_MAX (FRAC_ROWS - 1) 9*6d67aabdSBjoern A. Zeeb #define NORM_ROW_MIN FRAC_ROWS 10*6d67aabdSBjoern A. Zeeb 11*6d67aabdSBjoern A. Zeeb static const u32 db_invert_table[12][8] = { 12*6d67aabdSBjoern A. Zeeb /* rows 0~2 in unit of U(32,3) */ 13*6d67aabdSBjoern A. Zeeb {10, 13, 16, 20, 25, 32, 40, 50}, 14*6d67aabdSBjoern A. Zeeb {64, 80, 101, 128, 160, 201, 256, 318}, 15*6d67aabdSBjoern A. Zeeb {401, 505, 635, 800, 1007, 1268, 1596, 2010}, 16*6d67aabdSBjoern A. Zeeb /* rows 3~11 in unit of U(32,0) */ 17*6d67aabdSBjoern A. Zeeb {316, 398, 501, 631, 794, 1000, 1259, 1585}, 18*6d67aabdSBjoern A. Zeeb {1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000}, 19*6d67aabdSBjoern A. Zeeb {12589, 15849, 19953, 25119, 31623, 39811, 50119, 63098}, 20*6d67aabdSBjoern A. Zeeb {79433, 100000, 125893, 158489, 199526, 251189, 316228, 398107}, 21*6d67aabdSBjoern A. Zeeb {501187, 630957, 794328, 1000000, 1258925, 1584893, 1995262, 2511886}, 22*6d67aabdSBjoern A. Zeeb {3162278, 3981072, 5011872, 6309573, 7943282, 1000000, 12589254, 23*6d67aabdSBjoern A. Zeeb 15848932}, 24*6d67aabdSBjoern A. Zeeb {19952623, 25118864, 31622777, 39810717, 50118723, 63095734, 79432823, 25*6d67aabdSBjoern A. Zeeb 100000000}, 26*6d67aabdSBjoern A. Zeeb {125892541, 158489319, 199526232, 251188643, 316227766, 398107171, 27*6d67aabdSBjoern A. Zeeb 501187234, 630957345}, 28*6d67aabdSBjoern A. Zeeb {794328235, 1000000000, 1258925412, 1584893192, 1995262315, 2511886432U, 29*6d67aabdSBjoern A. Zeeb 3162277660U, 3981071706U}, 30*6d67aabdSBjoern A. Zeeb }; 31*6d67aabdSBjoern A. Zeeb 32*6d67aabdSBjoern A. Zeeb u32 rtw89_linear_2_db(u64 val) 33*6d67aabdSBjoern A. Zeeb { 34*6d67aabdSBjoern A. Zeeb u8 i, j; 35*6d67aabdSBjoern A. Zeeb u32 dB; 36*6d67aabdSBjoern A. Zeeb 37*6d67aabdSBjoern A. Zeeb for (i = 0; i < 12; i++) { 38*6d67aabdSBjoern A. Zeeb for (j = 0; j < 8; j++) { 39*6d67aabdSBjoern A. Zeeb if (i <= FRAC_ROW_MAX && 40*6d67aabdSBjoern A. Zeeb (val << RTW89_LINEAR_FRAC_BITS) <= db_invert_table[i][j]) 41*6d67aabdSBjoern A. Zeeb goto cnt; 42*6d67aabdSBjoern A. Zeeb else if (i > FRAC_ROW_MAX && val <= db_invert_table[i][j]) 43*6d67aabdSBjoern A. Zeeb goto cnt; 44*6d67aabdSBjoern A. Zeeb } 45*6d67aabdSBjoern A. Zeeb } 46*6d67aabdSBjoern A. Zeeb 47*6d67aabdSBjoern A. Zeeb return 96; /* maximum 96 dB */ 48*6d67aabdSBjoern A. Zeeb 49*6d67aabdSBjoern A. Zeeb cnt: 50*6d67aabdSBjoern A. Zeeb /* special cases */ 51*6d67aabdSBjoern A. Zeeb if (j == 0 && i == 0) 52*6d67aabdSBjoern A. Zeeb goto end; 53*6d67aabdSBjoern A. Zeeb 54*6d67aabdSBjoern A. Zeeb if (i == NORM_ROW_MIN && j == 0) { 55*6d67aabdSBjoern A. Zeeb if (db_invert_table[NORM_ROW_MIN][0] - val > 56*6d67aabdSBjoern A. Zeeb val - (db_invert_table[FRAC_ROW_MAX][7] >> RTW89_LINEAR_FRAC_BITS)) { 57*6d67aabdSBjoern A. Zeeb i = FRAC_ROW_MAX; 58*6d67aabdSBjoern A. Zeeb j = 7; 59*6d67aabdSBjoern A. Zeeb } 60*6d67aabdSBjoern A. Zeeb goto end; 61*6d67aabdSBjoern A. Zeeb } 62*6d67aabdSBjoern A. Zeeb 63*6d67aabdSBjoern A. Zeeb if (i <= FRAC_ROW_MAX) 64*6d67aabdSBjoern A. Zeeb val <<= RTW89_LINEAR_FRAC_BITS; 65*6d67aabdSBjoern A. Zeeb 66*6d67aabdSBjoern A. Zeeb /* compare difference to get precise dB */ 67*6d67aabdSBjoern A. Zeeb if (j == 0) { 68*6d67aabdSBjoern A. Zeeb if (db_invert_table[i][j] - val > 69*6d67aabdSBjoern A. Zeeb val - db_invert_table[i - 1][7]) { 70*6d67aabdSBjoern A. Zeeb i--; 71*6d67aabdSBjoern A. Zeeb j = 7; 72*6d67aabdSBjoern A. Zeeb } 73*6d67aabdSBjoern A. Zeeb } else { 74*6d67aabdSBjoern A. Zeeb if (db_invert_table[i][j] - val > 75*6d67aabdSBjoern A. Zeeb val - db_invert_table[i][j - 1]) { 76*6d67aabdSBjoern A. Zeeb j--; 77*6d67aabdSBjoern A. Zeeb } 78*6d67aabdSBjoern A. Zeeb } 79*6d67aabdSBjoern A. Zeeb end: 80*6d67aabdSBjoern A. Zeeb dB = (i << 3) + j + 1; 81*6d67aabdSBjoern A. Zeeb 82*6d67aabdSBjoern A. Zeeb return dB; 83*6d67aabdSBjoern A. Zeeb } 84*6d67aabdSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_linear_2_db); 85*6d67aabdSBjoern A. Zeeb 86*6d67aabdSBjoern A. Zeeb u64 rtw89_db_2_linear(u32 db) 87*6d67aabdSBjoern A. Zeeb { 88*6d67aabdSBjoern A. Zeeb u64 linear; 89*6d67aabdSBjoern A. Zeeb u8 i, j; 90*6d67aabdSBjoern A. Zeeb 91*6d67aabdSBjoern A. Zeeb if (db > 96) 92*6d67aabdSBjoern A. Zeeb db = 96; 93*6d67aabdSBjoern A. Zeeb else if (db < 1) 94*6d67aabdSBjoern A. Zeeb return 1; 95*6d67aabdSBjoern A. Zeeb 96*6d67aabdSBjoern A. Zeeb i = (db - 1) >> 3; 97*6d67aabdSBjoern A. Zeeb j = (db - 1) & 0x7; 98*6d67aabdSBjoern A. Zeeb 99*6d67aabdSBjoern A. Zeeb linear = db_invert_table[i][j]; 100*6d67aabdSBjoern A. Zeeb 101*6d67aabdSBjoern A. Zeeb if (i >= NORM_ROW_MIN) 102*6d67aabdSBjoern A. Zeeb linear = linear << RTW89_LINEAR_FRAC_BITS; 103*6d67aabdSBjoern A. Zeeb 104*6d67aabdSBjoern A. Zeeb return linear; 105*6d67aabdSBjoern A. Zeeb } 106*6d67aabdSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_db_2_linear); 107