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