OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / hal / btc / halbtc8821cwifionly.c
diff --git a/rtl8821ce/hal/btc/halbtc8821cwifionly.c b/rtl8821ce/hal/btc/halbtc8821cwifionly.c
new file mode 100755 (executable)
index 0000000..26de835
--- /dev/null
@@ -0,0 +1,211 @@
+/******************************************************************************
+ *
+ * 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) {
+       default:
+       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) {
+       default:
+       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, 0x400000, 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);
+}