/****************************************************************************** * * Copyright(c) 2016 - 2017 Realtek Corporation. * * 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. * *****************************************************************************/ #include "mp_precomp.h" static struct rfe_type_8821c_wifi_only gl_rfe_type_8821c_1ant; static struct rfe_type_8821c_wifi_only *rfe_type = &gl_rfe_type_8821c_1ant; VOID hal8821c_wifi_only_switch_antenna( IN struct wifi_only_cfg *pwifionlycfg, IN u1Byte is_5g ) { boolean switch_polatiry_inverse = false; u8 regval_0xcb7 = 0; u8 pos_type, ctrl_type; if (!rfe_type->ext_ant_switch_exist) return; /* swap control polarity if use different switch control polarity*/ /* Normal switch polarity for DPDT, 0xcb4[29:28] = 2b'01 => BTG to Main, WLG to Aux, 0xcb4[29:28] = 2b'10 => BTG to Aux, WLG to Main */ /* Normal switch polarity for SPDT, 0xcb4[29:28] = 2b'01 => Ant to BTG, 0xcb4[29:28] = 2b'10 => Ant to WLG */ if (rfe_type->ext_ant_switch_ctrl_polarity) switch_polatiry_inverse = !switch_polatiry_inverse; /* swap control polarity if 1-Ant at Aux */ if (rfe_type->ant_at_main_port == false) switch_polatiry_inverse = !switch_polatiry_inverse; if (is_5g) pos_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLA; else pos_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLG; switch (pos_type) { case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLA: break; case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLG: if (!rfe_type->wlg_Locate_at_btg) switch_polatiry_inverse = !switch_polatiry_inverse; break; } if (pwifionlycfg->haldata_info.ant_div_cfg) ctrl_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_ANTDIV; else ctrl_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_BBSW; switch (ctrl_type) { case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_BBSW: halwifionly_phy_set_bb_reg(pwifionlycfg, 0x4c, 0x01800000, 0x2); /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x000000ff, 0x77); regval_0xcb7 = (switch_polatiry_inverse == false ? 0x1 : 0x2); /* 0xcb4[29:28] = 2b'01 for no switch_polatiry_inverse, DPDT_SEL_N =1, DPDT_SEL_P =0 */ halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x30000000, regval_0xcb7); break; case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_ANTDIV: halwifionly_phy_set_bb_reg(pwifionlycfg, 0x4c, 0x01800000, 0x2); /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x000000ff, 0x88); /* no regval_0xcb7 setup required, because antenna switch control value by antenna diversity */ break; } } VOID halbtc8821c_wifi_only_set_rfe_type( IN struct wifi_only_cfg *pwifionlycfg ) { /* the following setup should be got from Efuse in the future */ rfe_type->rfe_module_type = (pwifionlycfg->haldata_info.rfe_type) & 0x1f; rfe_type->ext_ant_switch_ctrl_polarity = 0; switch (rfe_type->rfe_module_type) { case 0: default: rfe_type->ext_ant_switch_exist = true; rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*2-Ant, DPDT, WLG*/ rfe_type->wlg_Locate_at_btg = false; rfe_type->ant_at_main_port = true; break; case 1: rfe_type->ext_ant_switch_exist = true; rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_SPDT; /*1-Ant, Main, DPDT or SPDT, WLG */ rfe_type->wlg_Locate_at_btg = false; rfe_type->ant_at_main_port = true; break; case 2: rfe_type->ext_ant_switch_exist = true; rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_SPDT; /*1-Ant, Main, DPDT or SPDT, BTG */ rfe_type->wlg_Locate_at_btg = true; rfe_type->ant_at_main_port = true; break; case 3: rfe_type->ext_ant_switch_exist = true; rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*1-Ant, Aux, DPDT, WLG */ rfe_type->wlg_Locate_at_btg = false; rfe_type->ant_at_main_port = false; break; case 4: rfe_type->ext_ant_switch_exist = true; rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*1-Ant, Aux, DPDT, BTG */ rfe_type->wlg_Locate_at_btg = true; rfe_type->ant_at_main_port = false; break; case 5: rfe_type->ext_ant_switch_exist = false; /*2-Ant, no antenna switch, WLG*/ rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_NONE; rfe_type->wlg_Locate_at_btg = false; rfe_type->ant_at_main_port = true; break; case 6: rfe_type->ext_ant_switch_exist = false; /*2-Ant, no antenna switch, WLG*/ rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_NONE; rfe_type->wlg_Locate_at_btg = false; rfe_type->ant_at_main_port = true; break; case 7: rfe_type->ext_ant_switch_exist = true; /*2-Ant, DPDT, BTG*/ rfe_type->ext_ant_switch_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; rfe_type->wlg_Locate_at_btg = true; rfe_type->ant_at_main_port = true; break; } } VOID ex_hal8821c_wifi_only_hw_config( IN struct wifi_only_cfg *pwifionlycfg ) { halbtc8821c_wifi_only_set_rfe_type(pwifionlycfg); /* set gnt_wl, gnt_bt control owner to WL*/ halwifionly_phy_set_bb_reg(pwifionlycfg, 0x70, 0x4000000, 0x1); /*gnt_wl=1 , gnt_bt=0*/ halwifionly_phy_set_bb_reg(pwifionlycfg, 0x1704, 0xffffffff, 0x7700); halwifionly_phy_set_bb_reg(pwifionlycfg, 0x1700, 0xffffffff, 0xc00f0038); halwifionly_phy_set_bb_reg(pwifionlycfg, 0x6c0, 0xffffffff, 0xaaaaaaaa); halwifionly_phy_set_bb_reg(pwifionlycfg, 0x6c4, 0xffffffff, 0xaaaaaaaa); } VOID ex_hal8821c_wifi_only_scannotify( IN struct wifi_only_cfg *pwifionlycfg, IN u1Byte is_5g ) { hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g); } VOID ex_hal8821c_wifi_only_switchbandnotify( IN struct wifi_only_cfg *pwifionlycfg, IN u1Byte is_5g ) { hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g); } VOID ex_hal8821c_wifi_only_connectnotify( IN struct wifi_only_cfg *pwifionlycfg, IN u1Byte is_5g ) { hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g); }