Search Linux Wireless

RE: [PATCH] wifi: rtl8xxxu: Support new chip RTL8192FU

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> Sent: Wednesday, April 26, 2023 1:28 AM
> To: linux-wireless@xxxxxxxxxxxxxxx
> Cc: Jes Sorensen <Jes.Sorensen@xxxxxxxxx>; Ping-Ke Shih <pkshih@xxxxxxxxxxx>
> Subject: [PATCH] wifi: rtl8xxxu: Support new chip RTL8192FU
> 
> This is a newer chip, similar to the RTL8710BU in that it uses the same
> PHY status structs.
> 
> Features: 2.4 GHz, b/g/n mode, 2T2R, 300 Mbps.
> 
> It can allegedly have Bluetooth, but that's not implemented here.
> 
> This chip can have many RFE (RF front end) types, of which type 5 is
> the only one tested. Many of the other types need different
> initialisation tables. They can be added if someone wants them.
> 
> The vendor driver v5.8.6.2_35538.20191028_COEX20190910-0d02 from
> https://github.com/BrightX/rtl8192fu was used as reference.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
>  drivers/net/wireless/realtek/rtl8xxxu/Kconfig |    3 +-
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  |   47 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8188f.c         |    3 +-
>  .../realtek/rtl8xxxu/rtl8xxxu_8192f.c         | 2081 +++++++++++++++++
>  .../realtek/rtl8xxxu/rtl8xxxu_8710b.c         |    1 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8723b.c         |    1 +
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c |  104 +-
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h |   15 +
>  8 files changed, 2225 insertions(+), 30 deletions(-)
>  create mode 100644 drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
> 

[...]

> +static void rtl8192fu_config_kfree(struct rtl8xxxu_priv *priv, u8 channel)
> +{
> +       u8 bb_gain[3] = { EFUSE_UNDEFINED, EFUSE_UNDEFINED, EFUSE_UNDEFINED };
> +       u8 bb_gain_path_mask[2] = { 0x0f, 0xf0 };
> +       enum rtl8xxxu_rfpath rfpath;
> +       u8 bb_gain_for_path;
> +       u8 channel_idx;
> +
> +       if (channel >= 1 && channel <= 3)
> +               channel_idx = 0;
> +       if (channel >= 4 && channel <= 9)
> +               channel_idx = 1;
> +       if (channel >= 10 && channel <= 14)
> +               channel_idx = 2;
> +
> +       rtl8xxxu_read_efuse8(priv, 0x1ee, &bb_gain[1]);
> +       rtl8xxxu_read_efuse8(priv, 0x1ec, &bb_gain[0]);
> +       rtl8xxxu_read_efuse8(priv, 0x1ea, &bb_gain[2]);

Can you define these fields in struct rtl8192fu_efuse, and access via
the struct? 


> +
> +       if (bb_gain[1] == EFUSE_UNDEFINED)
> +               return;
> +
> +       if (bb_gain[0] == EFUSE_UNDEFINED)
> +               bb_gain[0] = bb_gain[1];
> +
> +       if (bb_gain[2] == EFUSE_UNDEFINED)
> +               bb_gain[2] = bb_gain[1];
> +
> +       for (rfpath = RF_A; rfpath < priv->rf_paths; rfpath++) {
> +               /* power_trim based on 55[19:14] */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_UNKNOWN_55,
> +                                         BIT(5), 1);
> +
> +               /* enable 55[14] for 0.5db step */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, 0xf5, BIT(18), 1);

#define RF6052_REG_GAIN_CTRL 0x55

> +
> +               /* enter power_trim debug mode */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_UNKNOWN_DF,
> +                                         BIT(7), 1);
> +
> +               /* write enable */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_WE_LUT, BIT(7), 1);
> +
> +               bb_gain_for_path = (bb_gain[channel_idx] & bb_gain_path_mask[rfpath])
> +                                >> __ffs(bb_gain_path_mask[rfpath]);

Normally, putting operator >> in tail, but this statement is so long.
How about this?

		bb_gain_for_path = (bb_gain[channel_idx] & bb_gain_path_mask[rfpath]);
		bb_gain_for_path >>= __ffs(bb_gain_path_mask[rfpath]);

> +
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3,
> +                                         0x70000, channel_idx * 2);
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3,
> +                                         0x3f, bb_gain_for_path);
> +
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3,
> +                                         0x70000, channel_idx * 2 + 1);
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_TXPA_G3,
> +                                         0x3f, bb_gain_for_path);
> +
> +               /* leave power_trim debug mode */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_UNKNOWN_DF,
> +                                         BIT(7), 0);
> +
> +               /* write disable */
> +               rtl8xxxu_write_rfreg_mask(priv, rfpath, RF6052_REG_WE_LUT, BIT(7), 0);
> +       }
> +}
> +

[...]

> +static void rtl8192fu_init_phy_bb(struct rtl8xxxu_priv *priv)
> +{
> +       /* Enable BB and RF */
> +       rtl8xxxu_write16_set(priv, REG_SYS_FUNC,
> +                            SYS_FUNC_BBRSTB | SYS_FUNC_BB_GLB_RSTN);
> +
> +       rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB);
> +
> +       /* To Fix MAC loopback mode fail. */
> +       rtl8xxxu_write8(priv, REG_LDOHCI12_CTRL, 0xf);
> +       rtl8xxxu_write8(priv, 0x15, 0xe9);

#define REG_SYS_SWR_CTRL2 0x14

You can use REG_SYS_SWR_CTRL2 + 1 here.

> +
> +       rtl8xxxu_init_phy_regs(priv, rtl8192fu_phy_init_table);
> +
> +       rtl8xxxu_init_phy_regs(priv, rtl8192f_agc_table);
> +}
> +

[...]

> +static int rtl8192fu_iqk_path_a(struct rtl8xxxu_priv *priv)
> +{
> +       u32 reg_eac, reg_e94, reg_e9c, val32;
> +       u32 rf_0x58_i, rf_0x58_q;
> +       u8 rfe = priv->rfe_type;
> +       int result = 0;
> +       int ktime, i;
> +
> +       /* Leave IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
> +       rtl8xxxu_write32(priv, 0xd94, 0x44ffbb44);

#define REG_ANAPWR1 0xd94

> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(4), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12)
> +               val32 = 0x30;
> +       else
> +               val32 = 0xe9;
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x003ff, val32);
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* path-A IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8214000f);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28140000);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
> +       rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00e62911);
> +
> +       /* One shot, path A LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xe98) == 0 && ktime < 21) {

#define REG_IQK_RTP_TXA 0xe98

> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       /* Check failed */
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
> +       reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
> +
> +       /* reload 0xdf and CCK_IND off */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_WE_LUT, BIT(4), 1);
> +
> +       val32 = rtl8xxxu_read_rfreg(priv, RF_A, 0x58);

#define RF6052_REG_TXMOD 0x58

> +       rf_0x58_i = u32_get_bits(val32, 0xfc000);
> +       rf_0x58_q = u32_get_bits(val32, 0x003f0);
> +
> +       for (i = 0; i < 8; i++) {
> +               rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3,
> +                                         0x1c000, i);
> +               rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3,
> +                                         0x00fc0, rf_0x58_i);
> +               rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_TXPA_G3,
> +                                         0x0003f, rf_0x58_q);
> +       }
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, BIT(14), 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_WE_LUT, BIT(4), 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x00810, 0);
> +
> +       if (!(reg_eac & BIT(28)) &&
> +           ((reg_e94 & 0x03ff0000) != 0x01420000) &&
> +           ((reg_e9c & 0x03ff0000) != 0x00420000))
> +               result |= 0x01;
> +
> +       return result;
> +}
> +
> +static int rtl8192fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
> +{
> +       u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32;
> +       int result = 0;
> +       int ktime;
> +
> +       /* Leave IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       /* PA/PAD control by 0x56, and set = 0x0 */
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(1), 1);
> +       rtl8xxxu_write_rfreg(priv, RF_A, 0x35, 0);

#define RF6052_REG_GAIN_P1  0x35
#define RF6052_REG_PAD_TXG 0x56
#define RF6052_REG_GAIN_CCA 0xdf

> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x003ff, 0x27);
> +
> +       /* Enter IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* path-A IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160027);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000);
> +
> +       /* Tx IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
> +       rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0086a911);
> +
> +       /* One shot, path A LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xe98) == 0 && ktime < 21) {

#define REG_IQK_RTP_TXA 0xe98

> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       /* Check failed */
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
> +       reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
> +
> +       if (!(reg_eac & BIT(28)) &&
> +           ((reg_e94 & 0x03ff0000) != 0x01420000) &&
> +           ((reg_e9c & 0x03ff0000) != 0x00420000)) {
> +               result |= 0x01;
> +       } else { /* If TX not OK, ignore RX */
> +               /* PA/PAD controlled by 0x0 */
> +               rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +               rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF,
> +                                         BIT(11), 0);
> +
> +               return result;
> +       }
> +
> +       val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) | ((reg_e9c & 0x3ff0000) >> 16);
> +       rtl8xxxu_write32(priv, REG_TX_IQK, val32);
> +
> +       /* Modify RX IQK mode table */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       /* PA/PAD control by 0x56, and set = 0x0 */
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(1), 1);
> +       rtl8xxxu_write_rfreg(priv, RF_A, 0x35, 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x003ff, 0x1e0);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
> +       rtl8xxxu_write32(priv, 0xd94, 0x44ffbb44);
> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100);
> +
> +       /* Enter IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* path-A IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82170000);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28170000);
> +
> +       /* RX IQK setting */
> +       rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a8d1);
> +
> +       /* One shot, path A LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xea8) == 0 && ktime < 21) {

#define REG_IQK_RTP_RXA 0xea8

> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       /* Check failed */
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
> +
> +       /* Leave IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_UNKNOWN_DF, BIT(11), 0);
> +       rtl8xxxu_write_rfreg(priv, RF_A, 0x35, 0x02000);
> +
> +       if (!(reg_eac & BIT(27)) &&
> +           ((reg_ea4 & 0x03ff0000) != 0x01320000) &&
> +           ((reg_eac & 0x03ff0000) != 0x00360000))
> +               result |= 0x02;
> +
> +       return result;
> +}
> +
> +static int rtl8192fu_iqk_path_b(struct rtl8xxxu_priv *priv)
> +{
> +       u32 reg_eac, reg_eb4, reg_ebc, val32;
> +       u32 rf_0x58_i, rf_0x58_q;
> +       u8 rfe = priv->rfe_type;
> +       int result = 0;
> +       int ktime, i;
> +
> +       /* PA/PAD controlled by 0x0 */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
> +       rtl8xxxu_write32(priv, 0xd94, 0x44ffbb44);
> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(4), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12)
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_56,
> +                                         0x003ff, 0x30);
> +       else
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_56,
> +                                         0x00fff, 0xe9);
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* Path B IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x8214000F);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28140000);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
> +       rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00e62911);
> +
> +       /* One shot, path B LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xeb8) == 0 && ktime < 21) {

#define REG_IQK_RTP_TXB 0xeb8

> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       /* Check failed */
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
> +       reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
> +
> +       /* reload 0xdf and CCK_IND off */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_WE_LUT, BIT(4), 1);
> +
> +       val32 = rtl8xxxu_read_rfreg(priv, RF_B, 0x58);
> +       rf_0x58_i = u32_get_bits(val32, 0xfc000);
> +       rf_0x58_q = u32_get_bits(val32, 0x003f0);
> +
> +       for (i = 0; i < 8; i++) {
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3,
> +                                         0x1c000, i);
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3,
> +                                         0x00fc0, rf_0x58_i);
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_TXPA_G3,
> +                                         0x0003f, rf_0x58_q);
> +       }
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_AC, BIT(14), 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_WE_LUT, BIT(4), 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x00810, 0);
> +
> +       if (!(reg_eac & BIT(31)) &&
> +           ((reg_eb4 & 0x03ff0000) != 0x01420000) &&
> +           ((reg_ebc & 0x03ff0000) != 0x00420000))
> +               result |= 0x01;
> +       else
> +               dev_warn(&priv->udev->dev, "%s: Path B IQK failed!\n",
> +                        __func__);
> +
> +       return result;
> +}
> +
> +static int rtl8192fu_rx_iqk_path_b(struct rtl8xxxu_priv *priv)
> +{
> +       u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc, val32;
> +       int result = 0;
> +       int ktime;
> +
> +       /* Leave IQK mode */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(1), 1);
> +       rtl8xxxu_write_rfreg(priv, RF_B, 0x35, 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_56, 0x003ff, 0x67);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
> +       rtl8xxxu_write32(priv, 0xd94, 0x44ffbb44);
> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000);
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* path-B IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82160027);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28160000);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0086a911);
> +
> +       /* One shot, path A LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xeb8) == 0 && ktime < 21) {
> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       /* Check failed */
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
> +       reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
> +
> +       if (!(reg_eac & BIT(31)) &&
> +           ((reg_eb4 & 0x03ff0000) != 0x01420000) &&
> +           ((reg_ebc & 0x03ff0000) != 0x00420000)) {
> +               result |= 0x01;
> +       } else {
> +               /* PA/PAD controlled by 0x0 */
> +               rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +               rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF,
> +                                         BIT(11), 0);
> +
> +               return result;
> +       }
> +
> +       val32 = 0x80007c00 | (reg_eb4 & 0x03ff0000) | ((reg_ebc >> 16) & 0x03ff);
> +       rtl8xxxu_write32(priv, REG_TX_IQK, val32);
> +
> +       /* Modify RX IQK mode table */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(1), 1);
> +       rtl8xxxu_write_rfreg(priv, RF_B, 0x35, 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(11), 1);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_56, 0x003ff, 0x1e0);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
> +       rtl8xxxu_write32(priv, 0xd94, 0x44ffbb44);
> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00400040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005403);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000804e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04203400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000000);
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +
> +       /* Path B IQK setting */
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x18008c1c);
> +
> +       rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82170000);
> +       rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28170000);
> +
> +       /* IQK setting */
> +       rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
> +
> +       /* LO calibration setting */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911);
> +
> +       /* One shot, path A LOK & IQK */
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa005800);
> +       rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8005800);
> +
> +       mdelay(15);
> +
> +       ktime = 0;
> +       while (rtl8xxxu_read32(priv, 0xec8) == 0 && ktime < 21) {

#define REG_IQK_RTP_RXB 0xec8

> +               mdelay(5);
> +               ktime += 5;
> +       }
> +
> +       reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +       reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2);
> +       reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2);
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100);
> +
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(11), 0);
> +       rtl8xxxu_write_rfreg_mask(priv, RF_B, RF6052_REG_UNKNOWN_DF, BIT(1), 0);
> +       rtl8xxxu_write_rfreg(priv, RF_B, 0x35, 0x02000);
> +
> +       if (!(reg_eac & BIT(30)) &&
> +           ((reg_ec4 & 0x03ff0000) != 0x01320000) &&
> +           ((reg_ecc & 0x03ff0000) != 0x00360000))
> +               result |= 0x02;
> +       else
> +               dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n",
> +                        __func__);
> +
> +       return result;
> +}
> +
> +static void rtl8192fu_phy_iqcalibrate(struct rtl8xxxu_priv *priv,
> +                                     int result[][8], int t)
> +{
> +       static const u32 adda_regs[2] = {
> +               0xd94, REG_RX_WAIT_CCA
> +       };
> +       static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = {
> +               REG_TXPAUSE, REG_BEACON_CTRL,
> +               REG_BEACON_CTRL_1, REG_GPIO_MUXCFG
> +       };
> +       static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = {
> +               REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR,
> +               REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B,
> +               REG_DPDT_CTRL, REG_RFE_CTRL_ANTA_SRC,
> +               0x938, REG_CCK0_AFE_SETTING
> +       };

#define REG_RFE_CTRL_ANT_SRC2 0x938

> +       u32 rx_initial_gain_a, rx_initial_gain_b;
> +       struct device *dev = &priv->udev->dev;
> +       int path_a_ok, path_b_ok;
> +       u8 rfe = priv->rfe_type;
> +       int retry = 2;
> +       u32 i, val32;
> +
> +       /*
> +        * Note: IQ calibration must be performed after loading
> +        *       PHY_REG.txt , and radio_a, radio_b.txt
> +        */
> +
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rx_initial_gain_a = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
> +       rx_initial_gain_b = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1);
> +
> +       if (t == 0) {
> +               /* Save ADDA parameters, turn Path A ADDA on */
> +               rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup,
> +                                  ARRAY_SIZE(adda_regs));
> +               rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
> +               rtl8xxxu_save_regs(priv, iqk_bb_regs,
> +                                  priv->bb_backup, RTL8XXXU_BB_REGS);
> +       }
> +
> +       /* Instead of rtl8xxxu_path_adda_on */
> +       rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, BIT(31));
> +
> +       /* MAC settings */
> +       rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
> +       rtl8xxxu_write8_clear(priv, REG_GPIO_MUXCFG, GPIO_MUXCFG_IO_SEL_ENBT);
> +
> +       if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) {
> +               /* in ePA IQK, rfe_func_config & SW both pull down */
> +               /* path A */
> +               rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF, 0x7);
> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x1, 0x0);
> +
> +               rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF00, 0x7);
> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x4, 0x0);
> +
> +               rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC, 0xF000, 0x7);
> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x8, 0x0);
> +
> +               /* path B */
> +               rtl8xxxu_write32_mask(priv, 0x938, 0xF0, 0x7);
> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x20000, 0x0);
> +
> +               rtl8xxxu_write32_mask(priv, 0x938, 0xF0000, 0x7);
> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x100000, 0x0);
> +
> +               rtl8xxxu_write32_mask(priv, 0x93c, 0xF000, 0x7);

#define REG_RFE_CTRL_ANT_SRC3 0x93c

> +               rtl8xxxu_write32_mask(priv, REG_DPDT_CTRL, 0x8000000, 0x0);
> +       }
> +
> +       if (priv->rf_paths > 1) {
> +               /* path B standby */
> +               rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x000000);
> +               rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0x10000);
> +               rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0x808000);
> +       }
> +
> +       for (i = 0; i < retry; i++) {
> +               path_a_ok = rtl8192fu_iqk_path_a(priv);
> +
> +               if (path_a_ok == 0x01) {
> +                       val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
> +                       result[t][0] = (val32 >> 16) & 0x3ff;
> +
> +                       val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
> +                       result[t][1] = (val32 >> 16) & 0x3ff;
> +                       break;
> +               } else {
> +                       result[t][0] = 0x100;
> +                       result[t][1] = 0x0;
> +               }
> +       }
> +
> +       for (i = 0; i < retry; i++) {
> +               path_a_ok = rtl8192fu_rx_iqk_path_a(priv);
> +
> +               if (path_a_ok == 0x03) {
> +                       val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
> +                       result[t][2] = (val32 >> 16) & 0x3ff;
> +
> +                       val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
> +                       result[t][3] = (val32 >> 16) & 0x3ff;
> +                       break;
> +               } else {
> +                       result[t][2] = 0x100;
> +                       result[t][3] = 0x0;
> +               }
> +       }
> +
> +       if (!path_a_ok)
> +               dev_warn(dev, "%s: Path A IQK failed!\n", __func__);
> +
> +       if (priv->rf_paths > 1) {
> +               for (i = 0; i < retry; i++) {
> +                       path_b_ok = rtl8192fu_iqk_path_b(priv);
> +
> +                       if (path_b_ok == 0x01) {
> +                               val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
> +                               result[t][4] = (val32 >> 16) & 0x3ff;
> +
> +                               val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
> +                               result[t][5] = (val32 >> 16) & 0x3ff;
> +                               break;
> +                       } else {
> +                               result[t][4] = 0x100;
> +                               result[t][5] = 0x0;
> +                       }
> +               }
> +
> +               for (i = 0; i < retry; i++) {
> +                       path_b_ok = rtl8192fu_rx_iqk_path_b(priv);
> +
> +                       if (path_b_ok == 0x03) {
> +                               val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2);
> +                               result[t][6] = (val32 >> 16) & 0x3ff;
> +
> +                               val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2);
> +                               result[t][7] = (val32 >> 16) & 0x3ff;
> +                               break;
> +                       } else {
> +                               result[t][6] = 0x100;
> +                               result[t][7] = 0x0;
> +                       }
> +               }
> +
> +               if (!path_b_ok)
> +                       dev_warn(dev, "%s: Path B IQK failed!\n", __func__);
> +       }
> +
> +       /* Back to BB mode, load original value */
> +       rtl8xxxu_write32_mask(priv, REG_FPGA0_IQK, 0xffffff00, 0);
> +
> +       rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xcc0000c0);
> +
> +       rtl8xxxu_write32(priv, 0xd94, 0x44bbbb44);
> +       rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x80408040);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x6f005433);
> +       rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000004e4);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x04003400);
> +       rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100);
> +
> +       /* Reload ADDA power saving parameters */
> +       rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup,
> +                             ARRAY_SIZE(adda_regs));
> +
> +       /* Reload MAC parameters */
> +       rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
> +
> +       /* Reload BB parameters */
> +       rtl8xxxu_restore_regs(priv, iqk_bb_regs, priv->bb_backup, RTL8XXXU_BB_REGS);
> +
> +       rtl8xxxu_write32_clear(priv, REG_FPGA0_XCD_RF_PARM, BIT(31));
> +
> +       /* Restore RX initial gain */
> +       rtl8xxxu_write32_mask(priv, REG_OFDM0_XA_AGC_CORE1, 0xff, 0x50);
> +       rtl8xxxu_write32_mask(priv, REG_OFDM0_XA_AGC_CORE1, 0xff,
> +                             rx_initial_gain_a & 0xff);
> +       if (priv->rf_paths > 1) {
> +               rtl8xxxu_write32_mask(priv, REG_OFDM0_XB_AGC_CORE1, 0xff, 0x50);
> +               rtl8xxxu_write32_mask(priv, REG_OFDM0_XB_AGC_CORE1, 0xff,
> +                                     rx_initial_gain_b & 0xff);
> +       }
> +}
> +
> +static void rtl8192fu_phy_iq_calibrate(struct rtl8xxxu_priv *priv)
> +{
> +       s32 reg_e94, reg_e9c, reg_ea4, reg_eac;
> +       s32 reg_eb4, reg_ebc, reg_ec4, reg_ecc;
> +       struct device *dev = &priv->udev->dev;
> +       u32 path_a_0xdf, path_a_0x35;
> +       u32 path_b_0xdf, path_b_0x35;
> +       bool path_a_ok, path_b_ok;
> +       u8 rfe = priv->rfe_type;
> +       u32 rfe_path_select;
> +       int result[4][8]; /* last is final result */
> +       int i, candidate;
> +       s32 reg_tmp = 0;
> +       bool simu;
> +       u32 val32;
> +
> +       rfe_path_select = rtl8xxxu_read32(priv, REG_RFE_PATH_SELECT);
> +
> +       path_a_0xdf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
> +       path_a_0x35 = rtl8xxxu_read_rfreg(priv, RF_A, 0x35);
> +       path_b_0xdf = rtl8xxxu_read_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF);
> +       path_b_0x35 = rtl8xxxu_read_rfreg(priv, RF_B, 0x35);
> +
> +       memset(result, 0, sizeof(result));
> +       candidate = -1;
> +
> +       path_a_ok = false;
> +       path_b_ok = false;
> +
> +       for (i = 0; i < 3; i++) {
> +               rtl8192fu_phy_iqcalibrate(priv, result, i);
> +
> +               if (i == 1) {
> +                       simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1);
> +                       if (simu) {
> +                               candidate = 0;
> +                               break;
> +                       }
> +               }
> +
> +               if (i == 2) {
> +                       simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2);
> +                       if (simu) {
> +                               candidate = 0;
> +                               break;
> +                       }
> +
> +                       simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2);
> +                       if (simu) {
> +                               candidate = 1;
> +                       } else {
> +                               for (i = 0; i < 8; i++)
> +                                       reg_tmp += result[3][i];
> +
> +                               if (reg_tmp)
> +                                       candidate = 3;
> +                               else
> +                                       candidate = -1;
> +                       }
> +               }
> +       }
> +
> +       if (candidate >= 0) {
> +               reg_e94 = result[candidate][0];
> +               reg_e9c = result[candidate][1];
> +               reg_ea4 = result[candidate][2];
> +               reg_eac = result[candidate][3];
> +               reg_eb4 = result[candidate][4];
> +               reg_ebc = result[candidate][5];
> +               reg_ec4 = result[candidate][6];
> +               reg_ecc = result[candidate][7];
> +
> +               dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate);
> +               dev_dbg(dev, "%s: e94=%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%c\n",
> +                       __func__, reg_e94, reg_e9c, reg_ea4, reg_eac,
> +                       reg_eb4, reg_ebc, reg_ec4, reg_ecc);
> +
> +               path_a_ok = true;
> +               path_b_ok = true;
> +       }
> +
> +       rtl8xxxu_write32_mask(priv, REG_TX_IQK_TONE_A, 0x3ff00000, 0x100);
> +       rtl8xxxu_write32_mask(priv, 0xe20, 0x3ff, 0);

#define REG_NP_ANTA 0xe20

> +       rtl8xxxu_write32_mask(priv, REG_TX_IQK_TONE_B, 0x3ff00000, 0x100);
> +       rtl8xxxu_write32_mask(priv, REG_TAP_UPD_97F, 0x3ff, 0);
> +
> +       if (candidate >= 0) {
> +               if (reg_e94)
> +                       rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result,
> +                                                  candidate, (reg_ea4 == 0));
> +
> +               if (reg_eb4)
> +                       rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result,
> +                                                  candidate, (reg_ec4 == 0));
> +       }
> +
> +       rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, path_a_0xdf);
> +       rtl8xxxu_write_rfreg(priv, RF_A, 0x35, path_a_0x35);
> +       rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, path_b_0xdf);
> +       rtl8xxxu_write_rfreg(priv, RF_B, 0x35, path_b_0x35);
> +
> +       if (rfe == 7 || rfe == 8 || rfe == 9 || rfe == 12) {
> +               rtl8xxxu_write32_set(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x70000);
> +               rtl8xxxu_write32_clear(priv, REG_LEDCFG0, 0x6c00000);
> +               rtl8xxxu_write32_set(priv, REG_PAD_CTRL1, BIT(29) | BIT(28));
> +               rtl8xxxu_write32_clear(priv, REG_SW_GPIO_SHARE_CTRL_0,
> +                                      0x600000 | BIT(4));
> +
> +               /*
> +                * Originally:
> +                * odm_set_bb_reg(dm, R_0x944, BIT(11) | 0x1F, 0x3F);
> +                *
> +                * It clears bit 11 and sets bits 0..4. The mask doesn't cover
> +                * bit 5 so it's not modified. Is that what it's supposed to
> +                * accomplish?
> +                */
> +               val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER);
> +               val32 &= ~BIT(11);
> +               val32 |= 0x1f;
> +               rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32);
> +
> +               if (rfe == 7) {
> +                       rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC,
> +                                             0xfffff, 0x23200);
> +                       rtl8xxxu_write32_mask(priv, 0x938, 0xfffff, 0x23200);
> +                       rtl8xxxu_write32_mask(priv, 0x934, 0xf000, 0x3);
> +                       rtl8xxxu_write32_mask(priv, 0x93c, 0xf000, 0x3);
> +               } else {
> +                       rtl8xxxu_write32_mask(priv, REG_RFE_CTRL_ANTA_SRC,
> +                                             0xfffff, 0x22200);
> +                       rtl8xxxu_write32_mask(priv, 0x938, 0xfffff, 0x22200);
> +                       rtl8xxxu_write32_mask(priv, 0x934, 0xf000, 0x2);

#define REG_RFE_CTRL_ANT_SRC1 0x934

> +                       rtl8xxxu_write32_mask(priv, 0x93c, 0xf000, 0x2);
> +               }
> +
> +               rtl8xxxu_write32_clear(priv, 0x968, BIT(2));

#define REG_REF_OPT62 0x968

> +
> +               if (rfe == 7)
> +                       rtl8xxxu_write32(priv, 0x920, 0x03000003);

#define REG_REF_OPT 0x920

> +
> +               rtl8xxxu_write32(priv, REG_RFE_PATH_SELECT, rfe_path_select);
> +       }
> +}
> +
> +static void rtl8192fu_disabled_to_emu(struct rtl8xxxu_priv *priv)
> +{
> +       rtl8xxxu_write16_clear(priv, REG_APS_FSMCO,
> +                              APS_FSMCO_HW_POWERDOWN | APS_FSMCO_HW_SUSPEND);
> +
> +       rtl8xxxu_write32_clear(priv, REG_GPIO_INTM, BIT(16));
> +
> +       rtl8xxxu_write16_clear(priv, REG_APS_FSMCO,
> +                              APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND);
> +}
> +
> +static int rtl8192fu_emu_to_active(struct rtl8xxxu_priv *priv)
> +{
> +       u32 val32;
> +       u16 val16;
> +       int count;
> +
> +       /* enable LDOA12 MACRO block for all interface */
> +       rtl8xxxu_write8_set(priv, REG_LDOA15_CTRL, LDOA15_ENABLE);
> +
> +       /* disable BT_GPS_SEL pins */
> +       rtl8xxxu_write32_clear(priv, REG_PAD_CTRL1, BIT(28));
> +
> +       mdelay(1);
> +
> +       /* release analog Ips to digital */
> +       rtl8xxxu_write8_clear(priv, REG_SYS_ISO_CTRL, SYS_ISO_ANALOG_IPS);
> +
> +       val16 = APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND | APS_FSMCO_SW_LPS;
> +       rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, val16);
> +
> +       /* wait till 0x04[17] = 1 power ready */
> +       for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
> +               val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
> +               if (val32 & BIT(17))
> +                       break;
> +
> +               udelay(10);
> +       }
> +
> +       if (!count)
> +               return -EBUSY;
> +
> +       rtl8xxxu_write32_set(priv, REG_APS_FSMCO, APS_FSMCO_WLON_RESET);
> +
> +       for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
> +               val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
> +               if ((val32 & (APS_FSMCO_MAC_ENABLE | APS_FSMCO_MAC_OFF)) == 0)
> +                       break;
> +
> +               udelay(10);
> +       }
> +
> +       if (!count)
> +               return -EBUSY;
> +
> +       /* SWR OCP enable */
> +       rtl8xxxu_write32_set(priv, REG_AFE_MISC, BIT(18));
> +
> +       rtl8xxxu_write16_clear(priv, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN);
> +
> +       rtl8xxxu_write16_clear(priv, REG_APS_FSMCO,
> +                              APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND);
> +
> +       /* 0x7c[31]=1, LDO has max output capability */
> +       rtl8xxxu_write32_set(priv, REG_LDO_SW_CTRL, BIT(31));
> +
> +       rtl8xxxu_write16_set(priv, REG_APS_FSMCO, APS_FSMCO_MAC_ENABLE);
> +
> +       for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
> +               val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
> +               if ((val32 & APS_FSMCO_MAC_ENABLE) == 0)
> +                       break;
> +
> +               udelay(10);
> +       }
> +
> +       if (!count)
> +               return -EBUSY;
> +
> +       /* Enable WL control XTAL setting */
> +       rtl8xxxu_write8_set(priv, REG_AFE_MISC, AFE_MISC_WL_XTAL_CTRL);
> +
> +       /* Enable falling edge triggering interrupt */
> +       rtl8xxxu_write16_set(priv, REG_GPIO_INTM, GPIO_INTM_EDGE_TRIG_IRQ);
> +
> +       /* Enable GPIO9 data mode */
> +       rtl8xxxu_write16_clear(priv, REG_GPIO_IO_SEL_2, GPIO_IO_SEL_2_GPIO09_IRQ);
> +
> +       /* Enable GPIO9 input mode */
> +       rtl8xxxu_write16_clear(priv, REG_GPIO_IO_SEL_2, GPIO_IO_SEL_2_GPIO09_INPUT);
> +
> +       /* Enable HSISR GPIO[C:0] interrupt */
> +       rtl8xxxu_write8_set(priv, REG_HSIMR, BIT(0));
> +
> +       /* RF HW ON/OFF Enable */
> +       rtl8xxxu_write8_clear(priv, REG_MULTI_FUNC_CTRL, MULTI_WIFI_HW_ROF_EN);
> +
> +       /* Register Lock Disable */
> +       rtl8xxxu_write8_set(priv, REG_RSV_CTRL, BIT(7));
> +
> +       /* For GPIO9 internal pull high setting */
> +       rtl8xxxu_write16_set(priv, REG_MULTI_FUNC_CTRL, BIT(14));
> +
> +       /* reset RF path S1 */
> +       rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
> +
> +       /* reset RF path S0 */
> +       rtl8xxxu_write8(priv, 0x7b, 0);

#define REG_AFE_CTRL4 0x78

use REG_AFE_CTRL4 + 3 for 0x7b

> +
> +       /* enable RF path S1 */
> +       rtl8xxxu_write8(priv, REG_RF_CTRL, RF_SDMRSTB | RF_RSTB | RF_ENABLE);
> +
> +       /* enable RF path S0 */
> +       rtl8xxxu_write8(priv, 0x7b, RF_SDMRSTB | RF_RSTB | RF_ENABLE);
> +
> +       /* AFE_Ctrl */
> +       rtl8xxxu_write8_set(priv, 0x97, BIT(5));

#define REG_RSVD_1 0x97

> +
> +       /* AFE_Ctrl */
> +       rtl8xxxu_write8(priv, 0xdc, 0xcc);

#define REG_RSVD_4 0xdc

The name looks not so meaningful, but designers did give it as is.

> +
> +       /* AFE_Ctrl 0x24[4:3]=00 for xtal gmn */
> +       rtl8xxxu_write8_clear(priv, REG_AFE_XTAL_CTRL, BIT(4) | BIT(3));
> +
> +       /* GPIO_A[31:0] Pull down software register */
> +       rtl8xxxu_write32(priv, 0x1050, 0xffffffff);

#define REG_GPIO_A0 0x1050

> +
> +       /* GPIO_B[7:0] Pull down software register */
> +       rtl8xxxu_write8(priv, 0x105b, 0xff);

#define REG_GPIO_B0 0x105b

> +
> +       /* Register Lock Enable */
> +       rtl8xxxu_write8_clear(priv, REG_RSV_CTRL, BIT(7));
> +
> +       return 0;
> +}
> +

[...]

> @@ -2842,10 +2864,14 @@ void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv, bool iqk_ok,
> 
>         reg = (result[candidate][7] >> 6) & 0xf;
> 
> -       val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGCR_SSI_TABLE);
> -       val32 &= ~0x0000f000;
> -       val32 |= (reg << 12);
> -       rtl8xxxu_write32(priv, REG_OFDM0_AGCR_SSI_TABLE, val32);
> +       if (priv->rtl_chip == RTL8192F) {
> +               val32 = rtl8xxxu_write32_mask(priv, 0xca8, 0x000000f0, reg);

Setting val32 to return value isn't reasonable. 

#dfine REG_RXIQB_EXT 0xca8

> +       } else {
> +               val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGCR_SSI_TABLE);
> +               val32 &= ~0x0000f000;
> +               val32 |= (reg << 12);
> +               rtl8xxxu_write32(priv, REG_OFDM0_AGCR_SSI_TABLE, val32);
> +       }
>  }
> 

[...]

I lookup register document for uncertain addresses, but this isn't a simple
copy-paste thing, so I may mess something. Please tell me if something look weird.

Ping-Ke





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux