phy_common.c 14 KB

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