Search Linux Wireless

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

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

 



On 28/04/2023 09:21, Ping-Ke Shih wrote:
> 
> 
>> -----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? 
> 

They are not in the efuse map. These are "physical" efuse addresses.
I don't know what that means, as I have not studied the efuse stuff.

> 
>> +
>> +       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]);
> 

Looks good. I didn't think of that.

>> +
>> +               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.

Thank you for the names!

I wonder about these:

#define REG_IQK_RTP_TXA 0xe98
#define REG_IQK_RTP_RXA 0xea8
#define REG_IQK_RTP_TXB 0xeb8
#define REG_IQK_RTP_RXB 0xec8

Should they be REG_IQK_RPT_... for "report"?

And these:

#define REG_REF_OPT62 0x968
#define REG_REF_OPT 0x920

Should they be REG_RFE_... ?

> 
> 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