Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1/******************************************************************************
  2 *
  3 * Copyright(c) 2009-2014  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 * The full GNU General Public License is included in this distribution in the
 15 * file called LICENSE.
 16 *
 17 * Contact Information:
 18 * wlanfae <wlanfae@realtek.com>
 19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
 20 * Hsinchu 300, Taiwan.
 21 *
 22 * Larry Finger <Larry.Finger@lwfinger.net>
 23 *
 24 *****************************************************************************/
 25
 26#include "../wifi.h"
 27#include "phy_common.h"
 28#include "../rtl8723ae/reg.h"
 29#include <linux/module.h>
 30
 31/* These routines are common to RTL8723AE and RTL8723bE */
 32
 33u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw,
 34			     u32 regaddr, u32 bitmask)
 35{
 36	struct rtl_priv *rtlpriv = rtl_priv(hw);
 37	u32 returnvalue, originalvalue, bitshift;
 38
 39	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 40		 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
 41	originalvalue = rtl_read_dword(rtlpriv, regaddr);
 42	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
 43	returnvalue = (originalvalue & bitmask) >> bitshift;
 44
 45	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 46		 "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n",
 47		  bitmask, regaddr, originalvalue);
 48
 49	return returnvalue;
 50}
 51EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg);
 52
 53void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
 54			      u32 bitmask, u32 data)
 55{
 56	struct rtl_priv *rtlpriv = rtl_priv(hw);
 57	u32 originalvalue, bitshift;
 58
 59	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 60		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 61		  regaddr, bitmask, data);
 62
 63	if (bitmask != MASKDWORD) {
 64		originalvalue = rtl_read_dword(rtlpriv, regaddr);
 65		bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
 66		data = ((originalvalue & (~bitmask)) | (data << bitshift));
 67	}
 68
 69	rtl_write_dword(rtlpriv, regaddr, data);
 70
 71	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 72		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 73		  regaddr, bitmask, data);
 74}
 75EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg);
 76
 77u32 rtl8723_phy_calculate_bit_shift(u32 bitmask)
 78{
 79	u32 i;
 80
 81	for (i = 0; i <= 31; i++) {
 82		if (((bitmask >> i) & 0x1) == 1)
 83			break;
 84	}
 85	return i;
 86}
 87EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift);
 88
 89u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw,
 90			       enum radio_path rfpath, u32 offset)
 91{
 92	struct rtl_priv *rtlpriv = rtl_priv(hw);
 93	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 94	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 95	u32 newoffset;
 96	u32 tmplong, tmplong2;
 97	u8 rfpi_enable = 0;
 98	u32 retvalue;
 99
100	offset &= 0xff;
101	newoffset = offset;
102	if (RT_CANNOT_IO(hw)) {
103		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
104		return 0xFFFFFFFF;
105	}
106	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
107	if (rfpath == RF90_PATH_A)
108		tmplong2 = tmplong;
109	else
110		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
111	tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
112		   (newoffset << 23) | BLSSIREADEDGE;
113	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
114		      tmplong & (~BLSSIREADEDGE));
115	mdelay(1);
116	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
117	mdelay(2);
118	if (rfpath == RF90_PATH_A)
119		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
120						 BIT(8));
121	else if (rfpath == RF90_PATH_B)
122		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
123						 BIT(8));
124	if (rfpi_enable)
125		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
126					 BLSSIREADBACKDATA);
127	else
128		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
129					 BLSSIREADBACKDATA);
130	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
131		 "RFR-%d Addr[0x%x]= 0x%x\n",
132		  rfpath, pphyreg->rf_rb, retvalue);
133	return retvalue;
134}
135EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read);
136
137void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw,
138				 enum radio_path rfpath,
139				 u32 offset, u32 data)
140{
141	u32 data_and_addr;
142	u32 newoffset;
143	struct rtl_priv *rtlpriv = rtl_priv(hw);
144	struct rtl_phy *rtlphy = &(rtlpriv->phy);
145	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
146
147	if (RT_CANNOT_IO(hw)) {
148		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
149		return;
150	}
151	offset &= 0xff;
152	newoffset = offset;
153	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
154	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
155	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
156		 "RFW-%d Addr[0x%x]= 0x%x\n", rfpath,
157		   pphyreg->rf3wire_offset, data_and_addr);
158}
159EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write);
160
161long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
162				  enum wireless_mode wirelessmode,
163				  u8 txpwridx)
164{
165	long offset;
166	long pwrout_dbm;
167
168	switch (wirelessmode) {
169	case WIRELESS_MODE_B:
170		offset = -7;
171		break;
172	case WIRELESS_MODE_G:
173	case WIRELESS_MODE_N_24G:
174	default:
175		offset = -8;
176		break;
177	}
178	pwrout_dbm = txpwridx / 2 + offset;
179	return pwrout_dbm;
180}
181EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm);
182
183void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
184{
185	struct rtl_priv *rtlpriv = rtl_priv(hw);
186	struct rtl_phy *rtlphy = &(rtlpriv->phy);
187
188	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
189	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
190	rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
191	rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
192
193	rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
194	rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
195	rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
196	rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
197
198	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
199	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
200
201	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
202	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
203
204	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
205			    RFPGA0_XA_LSSIPARAMETER;
206	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
207			    RFPGA0_XB_LSSIPARAMETER;
208
209	rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
210	rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
211	rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
212	rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
213
214	rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
215	rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
216	rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
217	rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
218
219	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
220	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
221
222	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
223	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
224
225	rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
226	rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
227	rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
228	rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
229
230	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
231	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
232	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
233	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
234
235	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
236	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
237	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
238	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
239
240	rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
241	rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
242	rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
243	rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
244
245	rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
246	rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
247	rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
248	rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
249
250	rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
251	rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
252	rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
253	rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
254
255	rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
256	rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
257	rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
258	rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
259
260	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
261	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
262	rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
263	rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
264
265	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
266	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
267}
268EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def);
269
270bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
271				      u32 cmdtableidx,
272				      u32 cmdtablesz,
273				      enum swchnlcmd_id cmdid,
274				      u32 para1, u32 para2,
275				      u32 msdelay)
276{
277	struct swchnlcmd *pcmd;
278
279	if (cmdtable == NULL) {
280		RT_ASSERT(false, "cmdtable cannot be NULL.\n");
281		return false;
282	}
283
284	if (cmdtableidx >= cmdtablesz)
285		return false;
286
287	pcmd = cmdtable + cmdtableidx;
288	pcmd->cmdid = cmdid;
289	pcmd->para1 = para1;
290	pcmd->para2 = para2;
291	pcmd->msdelay = msdelay;
292	return true;
293}
294EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray);
295
296void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
297					bool iqk_ok,
298					long result[][8],
299					u8 final_candidate,
300					bool btxonly)
301{
302	u32 oldval_0, x, tx0_a, reg;
303	long y, tx0_c;
304
305	if (final_candidate == 0xFF) {
306		return;
307	} else if (iqk_ok) {
308		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
309					  MASKDWORD) >> 22) & 0x3FF;
310		x = result[final_candidate][0];
311		if ((x & 0x00000200) != 0)
312			x = x | 0xFFFFFC00;
313		tx0_a = (x * oldval_0) >> 8;
314		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
315		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
316			      ((x * oldval_0 >> 7) & 0x1));
317		y = result[final_candidate][1];
318		if ((y & 0x00000200) != 0)
319			y = y | 0xFFFFFC00;
320		tx0_c = (y * oldval_0) >> 8;
321		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
322			      ((tx0_c & 0x3C0) >> 6));
323		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
324			      (tx0_c & 0x3F));
325		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
326			      ((y * oldval_0 >> 7) & 0x1));
327		if (btxonly)
328			return;
329		reg = result[final_candidate][2];
330		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
331		reg = result[final_candidate][3] & 0x3F;
332		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
333		reg = (result[final_candidate][3] >> 6) & 0xF;
334		rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
335	}
336}
337EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix);
338
339void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg,
340				 u32 *addabackup, u32 registernum)
341{
342	u32 i;
343
344	for (i = 0; i < registernum; i++)
345		addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
346}
347EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers);
348
349void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw,
350				    u32 *macreg, u32 *macbackup)
351{
352	struct rtl_priv *rtlpriv = rtl_priv(hw);
353	u32 i;
354
355	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
356		macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
357	macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
358}
359EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers);
360
361void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw,
362				       u32 *addareg, u32 *addabackup,
363				       u32 regiesternum)
364{
365	u32 i;
366
367	for (i = 0; i < regiesternum; i++)
368		rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
369}
370EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers);
371
372void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw,
373				      u32 *macreg, u32 *macbackup)
374{
375	struct rtl_priv *rtlpriv = rtl_priv(hw);
376	u32 i;
377
378	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
379		rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
380	rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
381}
382EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers);
383
384void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
385			      bool is_patha_on, bool is2t)
386{
387	u32 pathon;
388	u32 i;
389
390	pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
391	if (!is2t) {
392		pathon = 0x0bdb25a0;
393		rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
394	} else {
395		rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
396	}
397
398	for (i = 1; i < IQK_ADDA_REG_NUM; i++)
399		rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
400}
401EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on);
402
403void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw,
404					 u32 *macreg, u32 *macbackup)
405{
406	struct rtl_priv *rtlpriv = rtl_priv(hw);
407	u32 i = 0;
408
409	rtl_write_byte(rtlpriv, macreg[i], 0x3F);
410
411	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
412		rtl_write_byte(rtlpriv, macreg[i],
413			       (u8) (macbackup[i] & (~BIT(3))));
414	rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
415}
416EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration);
417
418void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw)
419{
420	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
421	rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
422	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
423}
424EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby);
425
426void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
427{
428	u32 mode;
429
430	mode = pi_mode ? 0x01000100 : 0x01000000;
431	rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
432	rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
433}
434EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch);