1 /******************************************************************************
2 *
3 * Copyright(c) 2016 - 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 #include "mp_precomp.h"
16
17 static struct rfe_type_8821c_wifi_only gl_rfe_type_8821c_1ant;
18 static struct rfe_type_8821c_wifi_only *rfe_type = &gl_rfe_type_8821c_1ant;
19
20
21
hal8821c_wifi_only_switch_antenna(IN struct wifi_only_cfg * pwifionlycfg,IN u1Byte is_5g)22 VOID hal8821c_wifi_only_switch_antenna(
23 IN struct wifi_only_cfg *pwifionlycfg,
24 IN u1Byte is_5g
25 )
26 {
27 boolean switch_polatiry_inverse = false;
28 u8 regval_0xcb7 = 0;
29 u8 pos_type, ctrl_type;
30
31 if (!rfe_type->ext_ant_switch_exist)
32 return;
33
34 /* swap control polarity if use different switch control polarity*/
35 /* 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 */
36 /* Normal switch polarity for SPDT, 0xcb4[29:28] = 2b'01 => Ant to BTG, 0xcb4[29:28] = 2b'10 => Ant to WLG */
37 if (rfe_type->ext_ant_switch_ctrl_polarity)
38 switch_polatiry_inverse = !switch_polatiry_inverse;
39
40 /* swap control polarity if 1-Ant at Aux */
41 if (rfe_type->ant_at_main_port == false)
42 switch_polatiry_inverse = !switch_polatiry_inverse;
43
44 if (is_5g)
45 pos_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLA;
46 else
47 pos_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLG;
48
49 switch (pos_type) {
50 case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLA:
51
52 break;
53 case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_TO_WLG:
54 if (!rfe_type->wlg_Locate_at_btg)
55 switch_polatiry_inverse = !switch_polatiry_inverse;
56 break;
57 }
58
59 if (pwifionlycfg->haldata_info.ant_div_cfg)
60 ctrl_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_ANTDIV;
61 else
62 ctrl_type = BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_BBSW;
63
64
65 switch (ctrl_type) {
66 case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_BBSW:
67 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x4c, 0x01800000, 0x2);
68
69 /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */
70 halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x000000ff, 0x77);
71
72 regval_0xcb7 = (switch_polatiry_inverse == false ? 0x1 : 0x2);
73
74 /* 0xcb4[29:28] = 2b'01 for no switch_polatiry_inverse, DPDT_SEL_N =1, DPDT_SEL_P =0 */
75 halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x30000000, regval_0xcb7);
76 break;
77
78 case BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_CTRL_BY_ANTDIV:
79 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x4c, 0x01800000, 0x2);
80
81 /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */
82 halwifionly_phy_set_bb_reg(pwifionlycfg, 0xcb4, 0x000000ff, 0x88);
83
84 /* no regval_0xcb7 setup required, because antenna switch control value by antenna diversity */
85
86 break;
87
88 }
89
90 }
91
92
halbtc8821c_wifi_only_set_rfe_type(IN struct wifi_only_cfg * pwifionlycfg)93 VOID halbtc8821c_wifi_only_set_rfe_type(
94 IN struct wifi_only_cfg *pwifionlycfg
95 )
96 {
97
98 /* the following setup should be got from Efuse in the future */
99 rfe_type->rfe_module_type = (pwifionlycfg->haldata_info.rfe_type) & 0x1f;
100
101 rfe_type->ext_ant_switch_ctrl_polarity = 0;
102
103 switch (rfe_type->rfe_module_type) {
104 case 0:
105 default:
106 rfe_type->ext_ant_switch_exist = true;
107 rfe_type->ext_ant_switch_type =
108 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*2-Ant, DPDT, WLG*/
109 rfe_type->wlg_Locate_at_btg = false;
110 rfe_type->ant_at_main_port = true;
111 break;
112 case 1:
113 rfe_type->ext_ant_switch_exist = true;
114 rfe_type->ext_ant_switch_type =
115 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_SPDT; /*1-Ant, Main, DPDT or SPDT, WLG */
116 rfe_type->wlg_Locate_at_btg = false;
117 rfe_type->ant_at_main_port = true;
118 break;
119 case 2:
120 rfe_type->ext_ant_switch_exist = true;
121 rfe_type->ext_ant_switch_type =
122 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_SPDT; /*1-Ant, Main, DPDT or SPDT, BTG */
123 rfe_type->wlg_Locate_at_btg = true;
124 rfe_type->ant_at_main_port = true;
125 break;
126 case 3:
127 rfe_type->ext_ant_switch_exist = true;
128 rfe_type->ext_ant_switch_type =
129 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*1-Ant, Aux, DPDT, WLG */
130 rfe_type->wlg_Locate_at_btg = false;
131 rfe_type->ant_at_main_port = false;
132 break;
133 case 4:
134 rfe_type->ext_ant_switch_exist = true;
135 rfe_type->ext_ant_switch_type =
136 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT; /*1-Ant, Aux, DPDT, BTG */
137 rfe_type->wlg_Locate_at_btg = true;
138 rfe_type->ant_at_main_port = false;
139 break;
140 case 5:
141 rfe_type->ext_ant_switch_exist = false; /*2-Ant, no antenna switch, WLG*/
142 rfe_type->ext_ant_switch_type =
143 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_NONE;
144 rfe_type->wlg_Locate_at_btg = false;
145 rfe_type->ant_at_main_port = true;
146 break;
147 case 6:
148 rfe_type->ext_ant_switch_exist = false; /*2-Ant, no antenna switch, WLG*/
149 rfe_type->ext_ant_switch_type =
150 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_NONE;
151 rfe_type->wlg_Locate_at_btg = false;
152 rfe_type->ant_at_main_port = true;
153 break;
154 case 7:
155 rfe_type->ext_ant_switch_exist = true; /*2-Ant, DPDT, BTG*/
156 rfe_type->ext_ant_switch_type =
157 BT_8821C_WIFI_ONLY_EXT_ANT_SWITCH_USE_DPDT;
158 rfe_type->wlg_Locate_at_btg = true;
159 rfe_type->ant_at_main_port = true;
160 break;
161 }
162
163 }
164
165
166 VOID
ex_hal8821c_wifi_only_hw_config(IN struct wifi_only_cfg * pwifionlycfg)167 ex_hal8821c_wifi_only_hw_config(
168 IN struct wifi_only_cfg *pwifionlycfg
169 )
170 {
171 halbtc8821c_wifi_only_set_rfe_type(pwifionlycfg);
172
173 /* set gnt_wl, gnt_bt control owner to WL*/
174 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x70, 0x4000000, 0x1);
175
176 /*gnt_wl=1 , gnt_bt=0*/
177 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x1704, 0xffffffff, 0x7700);
178 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x1700, 0xffffffff, 0xc00f0038);
179
180 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x6c0, 0xffffffff, 0xaaaaaaaa);
181 halwifionly_phy_set_bb_reg(pwifionlycfg, 0x6c4, 0xffffffff, 0xaaaaaaaa);
182 }
183
184 VOID
ex_hal8821c_wifi_only_scannotify(IN struct wifi_only_cfg * pwifionlycfg,IN u1Byte is_5g)185 ex_hal8821c_wifi_only_scannotify(
186 IN struct wifi_only_cfg *pwifionlycfg,
187 IN u1Byte is_5g
188 )
189 {
190 hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g);
191 }
192
193 VOID
ex_hal8821c_wifi_only_switchbandnotify(IN struct wifi_only_cfg * pwifionlycfg,IN u1Byte is_5g)194 ex_hal8821c_wifi_only_switchbandnotify(
195 IN struct wifi_only_cfg *pwifionlycfg,
196 IN u1Byte is_5g
197 )
198 {
199 hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g);
200 }
201
202 VOID
ex_hal8821c_wifi_only_connectnotify(IN struct wifi_only_cfg * pwifionlycfg,IN u1Byte is_5g)203 ex_hal8821c_wifi_only_connectnotify(
204 IN struct wifi_only_cfg *pwifionlycfg,
205 IN u1Byte is_5g
206 )
207 {
208 hal8821c_wifi_only_switch_antenna(pwifionlycfg, is_5g);
209 }
210
211
212