| /****************************************************************************** |
| * |
| * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of version 2 of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| * You should have received a copy of the GNU General Public License along with |
| * this program; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
| * |
| * |
| ******************************************************************************/ |
| |
| #include "odm_precomp.h" |
| |
| #include <phy.h> |
| |
| static bool check_condition(struct adapter *adapt, const u32 condition) |
| { |
| struct odm_dm_struct *odm = &GET_HAL_DATA(adapt)->odmpriv; |
| u32 _board = odm->BoardType; |
| u32 _platform = odm->SupportPlatform; |
| u32 _interface = odm->SupportInterface; |
| u32 cond = condition; |
| |
| if (condition == 0xCDCDCDCD) |
| return true; |
| |
| cond = condition & 0x000000FF; |
| if ((_board == cond) && cond != 0x00) |
| return false; |
| |
| cond = condition & 0x0000FF00; |
| cond >>= 8; |
| if ((_interface & cond) == 0 && cond != 0x07) |
| return false; |
| |
| cond = condition & 0x00FF0000; |
| cond >>= 16; |
| if ((_platform & cond) == 0 && cond != 0x0F) |
| return false; |
| return true; |
| } |
| |
| /* RadioA_1T.TXT */ |
| |
| static u32 Array_RadioA_1T_8188E[] = { |
| 0x000, 0x00030000, |
| 0x008, 0x00084000, |
| 0x018, 0x00000407, |
| 0x019, 0x00000012, |
| 0x01E, 0x00080009, |
| 0x01F, 0x00000880, |
| 0x02F, 0x0001A060, |
| 0x03F, 0x00000000, |
| 0x042, 0x000060C0, |
| 0x057, 0x000D0000, |
| 0x058, 0x000BE180, |
| 0x067, 0x00001552, |
| 0x083, 0x00000000, |
| 0x0B0, 0x000FF8FC, |
| 0x0B1, 0x00054400, |
| 0x0B2, 0x000CCC19, |
| 0x0B4, 0x00043003, |
| 0x0B6, 0x0004953E, |
| 0x0B7, 0x0001C718, |
| 0x0B8, 0x000060FF, |
| 0x0B9, 0x00080001, |
| 0x0BA, 0x00040000, |
| 0x0BB, 0x00000400, |
| 0x0BF, 0x000C0000, |
| 0x0C2, 0x00002400, |
| 0x0C3, 0x00000009, |
| 0x0C4, 0x00040C91, |
| 0x0C5, 0x00099999, |
| 0x0C6, 0x000000A3, |
| 0x0C7, 0x00088820, |
| 0x0C8, 0x00076C06, |
| 0x0C9, 0x00000000, |
| 0x0CA, 0x00080000, |
| 0x0DF, 0x00000180, |
| 0x0EF, 0x000001A0, |
| 0x051, 0x0006B27D, |
| 0xFF0F041F, 0xABCD, |
| 0x052, 0x0007E4DD, |
| 0xCDCDCDCD, 0xCDCD, |
| 0x052, 0x0007E49D, |
| 0xFF0F041F, 0xDEAD, |
| 0x053, 0x00000073, |
| 0x056, 0x00051FF3, |
| 0x035, 0x00000086, |
| 0x035, 0x00000186, |
| 0x035, 0x00000286, |
| 0x036, 0x00001C25, |
| 0x036, 0x00009C25, |
| 0x036, 0x00011C25, |
| 0x036, 0x00019C25, |
| 0x0B6, 0x00048538, |
| 0x018, 0x00000C07, |
| 0x05A, 0x0004BD00, |
| 0x019, 0x000739D0, |
| 0x034, 0x0000ADF3, |
| 0x034, 0x00009DF0, |
| 0x034, 0x00008DED, |
| 0x034, 0x00007DEA, |
| 0x034, 0x00006DE7, |
| 0x034, 0x000054EE, |
| 0x034, 0x000044EB, |
| 0x034, 0x000034E8, |
| 0x034, 0x0000246B, |
| 0x034, 0x00001468, |
| 0x034, 0x0000006D, |
| 0x000, 0x00030159, |
| 0x084, 0x00068200, |
| 0x086, 0x000000CE, |
| 0x087, 0x00048A00, |
| 0x08E, 0x00065540, |
| 0x08F, 0x00088000, |
| 0x0EF, 0x000020A0, |
| 0x03B, 0x000F02B0, |
| 0x03B, 0x000EF7B0, |
| 0x03B, 0x000D4FB0, |
| 0x03B, 0x000CF060, |
| 0x03B, 0x000B0090, |
| 0x03B, 0x000A0080, |
| 0x03B, 0x00090080, |
| 0x03B, 0x0008F780, |
| 0x03B, 0x000722B0, |
| 0x03B, 0x0006F7B0, |
| 0x03B, 0x00054FB0, |
| 0x03B, 0x0004F060, |
| 0x03B, 0x00030090, |
| 0x03B, 0x00020080, |
| 0x03B, 0x00010080, |
| 0x03B, 0x0000F780, |
| 0x0EF, 0x000000A0, |
| 0x000, 0x00010159, |
| 0x018, 0x0000F407, |
| 0xFFE, 0x00000000, |
| 0xFFE, 0x00000000, |
| 0x01F, 0x00080003, |
| 0xFFE, 0x00000000, |
| 0xFFE, 0x00000000, |
| 0x01E, 0x00000001, |
| 0x01F, 0x00080000, |
| 0x000, 0x00033E60, |
| }; |
| |
| #define READ_NEXT_PAIR(v1, v2, i) \ |
| do { \ |
| i += 2; v1 = array[i]; \ |
| v2 = array[i+1]; \ |
| } while (0) |
| |
| #define RFREG_OFFSET_MASK 0xfffff |
| #define B3WIREADDREAALENGTH 0x400 |
| #define B3WIREDATALENGTH 0x800 |
| #define BRFSI_RFENV 0x10 |
| |
| static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u32 addr, u32 mask, u32 data) |
| { |
| if (addr == 0xfe) { |
| mdelay(50); |
| } else if (addr == 0xfd) { |
| mdelay(5); |
| } else if (addr == 0xfc) { |
| mdelay(1); |
| } else if (addr == 0xfb) { |
| udelay(50); |
| } else if (addr == 0xfa) { |
| udelay(5); |
| } else if (addr == 0xf9) { |
| udelay(1); |
| } else { |
| phy_set_rf_reg(adapt, rfpath, addr, mask, data); |
| udelay(1); |
| } |
| } |
| |
| static void rtl8188e_config_rf_reg(struct adapter *adapt, |
| u32 addr, u32 data) |
| { |
| u32 content = 0x1000; /*RF Content: radio_a_txt*/ |
| u32 maskforphyset = (u32)(content & 0xE000); |
| |
| rtl_rfreg_delay(adapt, RF90_PATH_A, addr | maskforphyset, |
| RFREG_OFFSET_MASK, |
| data); |
| } |
| |
| static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt) |
| { |
| u32 i; |
| u32 array_len = sizeof(Array_RadioA_1T_8188E)/sizeof(u32); |
| u32 *array = Array_RadioA_1T_8188E; |
| |
| for (i = 0; i < array_len; i += 2) { |
| u32 v1 = array[i]; |
| u32 v2 = array[i+1]; |
| |
| if (v1 < 0xCDCDCDCD) { |
| rtl8188e_config_rf_reg(adapt, v1, v2); |
| continue; |
| } else { |
| if (!check_condition(adapt, array[i])) { |
| READ_NEXT_PAIR(v1, v2, i); |
| while (v2 != 0xDEAD && v2 != 0xCDEF && |
| v2 != 0xCDCD && i < array_len - 2) |
| READ_NEXT_PAIR(v1, v2, i); |
| i -= 2; |
| } else { |
| READ_NEXT_PAIR(v1, v2, i); |
| while (v2 != 0xDEAD && v2 != 0xCDEF && |
| v2 != 0xCDCD && i < array_len - 2) { |
| rtl8188e_config_rf_reg(adapt, v1, v2); |
| READ_NEXT_PAIR(v1, v2, i); |
| } |
| |
| while (v2 != 0xDEAD && i < array_len - 2) |
| READ_NEXT_PAIR(v1, v2, i); |
| } |
| } |
| } |
| return true; |
| } |
| |
| static bool rf6052_conf_para(struct adapter *adapt) |
| { |
| struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| u32 u4val = 0; |
| u8 rfpath; |
| bool rtstatus = true; |
| struct bb_reg_def *pphyreg; |
| |
| for (rfpath = 0; rfpath < hal_data->NumTotalRFPath; rfpath++) { |
| pphyreg = &hal_data->PHYRegDef[rfpath]; |
| |
| switch (rfpath) { |
| case RF90_PATH_A: |
| case RF90_PATH_C: |
| u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs, |
| BRFSI_RFENV); |
| break; |
| case RF90_PATH_B: |
| case RF90_PATH_D: |
| u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs, |
| BRFSI_RFENV << 16); |
| break; |
| } |
| |
| phy_set_bb_reg(adapt, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); |
| udelay(1); |
| |
| phy_set_bb_reg(adapt, pphyreg->rfintfo, BRFSI_RFENV, 0x1); |
| udelay(1); |
| |
| phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, |
| B3WIREADDREAALENGTH, 0x0); |
| udelay(1); |
| |
| phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, |
| B3WIREDATALENGTH, 0x0); |
| udelay(1); |
| |
| switch (rfpath) { |
| case RF90_PATH_A: |
| rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt); |
| break; |
| case RF90_PATH_B: |
| rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt); |
| break; |
| case RF90_PATH_C: |
| break; |
| case RF90_PATH_D: |
| break; |
| } |
| |
| switch (rfpath) { |
| case RF90_PATH_A: |
| case RF90_PATH_C: |
| phy_set_bb_reg(adapt, pphyreg->rfintfs, |
| BRFSI_RFENV, u4val); |
| break; |
| case RF90_PATH_B: |
| case RF90_PATH_D: |
| phy_set_bb_reg(adapt, pphyreg->rfintfs, |
| BRFSI_RFENV << 16, u4val); |
| break; |
| } |
| |
| if (rtstatus != true) |
| return false; |
| } |
| |
| return rtstatus; |
| } |
| |
| static bool rtl88e_phy_rf6052_config(struct adapter *adapt) |
| { |
| struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| |
| if (hal_data->rf_type == RF_1T1R) |
| hal_data->NumTotalRFPath = 1; |
| else |
| hal_data->NumTotalRFPath = 2; |
| |
| return rf6052_conf_para(adapt); |
| } |
| |
| bool rtl88eu_phy_rf_config(struct adapter *adapt) |
| { |
| return rtl88e_phy_rf6052_config(adapt); |
| } |