wifi: rtw89: 8851b: configure GPIO according to RFE type
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 12 May 2023 06:12:16 +0000 (14:12 +0800)
committerKalle Valo <kvalo@kernel.org>
Wed, 17 May 2023 08:05:57 +0000 (11:05 +0300)
Though 8851BE is a 1x1 chip, but it has two antenna hardware module that
needs additional configuration to help choose antenna we are going to use.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230512061220.16544-3-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c

index b60cd9852259ea7584066b3fc227fe43095bc179..fe464b7212f55a080fd8d7a96c463f3b43bf0d9b 100644 (file)
@@ -2799,6 +2799,7 @@ struct rtw89_chip_ops {
        int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map);
        int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map);
        void (*fem_setup)(struct rtw89_dev *rtwdev);
+       void (*rfe_gpio)(struct rtw89_dev *rtwdev);
        void (*rfk_init)(struct rtw89_dev *rtwdev);
        void (*rfk_channel)(struct rtw89_dev *rtwdev);
        void (*rfk_band_changed)(struct rtw89_dev *rtwdev,
@@ -4700,6 +4701,14 @@ static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev)
                chip->ops->fem_setup(rtwdev);
 }
 
+static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       if (chip->ops->rfe_gpio)
+               chip->ops->rfe_gpio(rtwdev);
+}
+
 static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
index 568488da3ff15de866aa421b9e0511072298cb1b..de0776dfddf7e97f6bdfb839f22f04a9ef6cf6b2 100644 (file)
@@ -4399,6 +4399,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
        rtw89_phy_cfo_init(rtwdev);
        rtw89_phy_ul_tb_info_init(rtwdev);
        rtw89_phy_antdiv_init(rtwdev);
+       rtw89_chip_rfe_gpio(rtwdev);
        rtw89_phy_antdiv_set_ant(rtwdev);
 
        rtw89_phy_init_rf_nctl(rtwdev);
index 21f68787ff1095371922707fee471870673559a3..a15bf3a6687c524868e13f19d9c2a4e53810e234 100644 (file)
 #define R_AX_EECS_EESK_FUNC_SEL 0x02D8
 #define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4)
 
+#define R_AX_GPIO16_23_FUNC_SEL 0x02D8
+#define B_AX_PINMUX_GPIO17_FUNC_SEL_MASK GENMASK(7, 4)
+#define B_AX_PINMUX_GPIO16_FUNC_SEL_MASK GENMASK(3, 0)
+
 #define R_AX_LED1_FUNC_SEL 0x02DC
 #define B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK GENMASK(27, 24)
 #define PINMUX_EESK_FUNC_SEL_BT_LOG 0x1
 #define R_RFE_E_A2 0x0334
 #define R_RFE_O_SEL_A2 0x0338
 #define R_RFE_SEL0_A2 0x033C
+#define B_RFE_SEL0_MASK GENMASK(1, 0)
 #define R_RFE_SEL32_A2 0x0340
 #define R_CIRST 0x035c
 #define B_CIRST_SYN GENMASK(11, 10)
 #define B_P0_ANTSEL_RX_ORI GENMASK(7, 4)
 #define R_RFSW_CTRL_ANT0_BASE 0x5870
 #define B_RFSW_CTRL_ANT_MAPPING GENMASK(15, 0)
+#define R_RFE_SEL0_BASE 0x5880
+#define B_RFE_SEL0_SRC_MASK GENMASK(3, 0)
+#define RFE_SEL0_SRC_ANTSEL_0 8
+#define R_RFE_INV0 0x5890
 #define R_P0_RFM 0x5894
 #define B_P0_RFM_DIS_WL BIT(7)
 #define B_P0_RFM_TX_OPT BIT(6)
index 00cabf92c5a9999ec5f6733eef90a36f7ad16d2a..047171ead2e973926609d0bea7ff9d63fff1495f 100644 (file)
@@ -72,8 +72,72 @@ static const struct rtw89_xtal_info rtw8851b_xtal_info = {
        .sc_xi_mask             = B_AX_XTAL_SC_XI_A_BLOCK_MASK,
 };
 
+static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv,
+                                u8 src_sel)
+{
+       u32 addr, mask;
+
+       if (gpio_idx >= 32)
+               return;
+
+       /* 2 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 2 bits */
+       addr = R_RFE_SEL0_A2 + (gpio_idx / 16) * sizeof(u32);
+       mask = B_RFE_SEL0_MASK << (gpio_idx % 16) * 2;
+
+       rtw89_phy_write32_mask(rtwdev, addr, mask, RF_PATH_A);
+       rtw89_phy_write32_mask(rtwdev, R_RFE_INV0, BIT(gpio_idx), inv);
+
+       /* 4 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 4 bits */
+       addr = R_RFE_SEL0_BASE + (gpio_idx / 8) * sizeof(u32);
+       mask = B_RFE_SEL0_SRC_MASK << (gpio_idx % 8) * 4;
+
+       rtw89_phy_write32_mask(rtwdev, addr, mask, src_sel);
+}
+
+static void rtw8851b_set_mac_gpio(struct rtw89_dev *rtwdev, u8 func)
+{
+       static const struct rtw89_reg3_def func16 = {
+               R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO16_FUNC_SEL_MASK, BIT(3)
+       };
+       static const struct rtw89_reg3_def func17 = {
+               R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO17_FUNC_SEL_MASK, BIT(7) >> 4,
+       };
+       const struct rtw89_reg3_def *def;
+
+       switch (func) {
+       case 16:
+               def = &func16;
+               break;
+       case 17:
+               def = &func17;
+               break;
+       default:
+               rtw89_warn(rtwdev, "undefined gpio func %d\n", func);
+               return;
+       }
+
+       rtw89_write8_mask(rtwdev, def->addr, def->mask, def->data);
+}
+
+static void rtw8851b_rfe_gpio(struct rtw89_dev *rtwdev)
+{
+       u8 rfe_type = rtwdev->efuse.rfe_type;
+
+       if (rfe_type > 50)
+               return;
+
+       if (rfe_type % 3 == 2) {
+               rtw8851b_set_bb_gpio(rtwdev, 16, true, RFE_SEL0_SRC_ANTSEL_0);
+               rtw8851b_set_bb_gpio(rtwdev, 17, false, RFE_SEL0_SRC_ANTSEL_0);
+
+               rtw8851b_set_mac_gpio(rtwdev, 16);
+               rtw8851b_set_mac_gpio(rtwdev, 17);
+       }
+}
+
 static const struct rtw89_chip_ops rtw8851b_chip_ops = {
        .fem_setup              = NULL,
+       .rfe_gpio               = rtw8851b_rfe_gpio,
        .fill_txdesc            = rtw89_core_fill_txdesc,
        .fill_txdesc_fwcmd      = rtw89_core_fill_txdesc,
        .h2c_dctl_sec_cam       = NULL,
index 4e6f3bbdc2d8f0abf0a737ec35b17f16a100d22a..541ad2f4b0c2bce6c3556c82be4531cf74b04ddc 100644 (file)
@@ -2032,6 +2032,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
        .read_efuse             = rtw8852a_read_efuse,
        .read_phycap            = rtw8852a_read_phycap,
        .fem_setup              = rtw8852a_fem_setup,
+       .rfe_gpio               = NULL,
        .rfk_init               = rtw8852a_rfk_init,
        .rfk_channel            = rtw8852a_rfk_channel,
        .rfk_band_changed       = rtw8852a_rfk_band_changed,
index b1a6b985842bed2193c015d6607c6229a01e535a..4e4023f114ec815b73039ad0b5d48c8bcfed85bd 100644 (file)
@@ -2454,6 +2454,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
        .read_efuse             = rtw8852b_read_efuse,
        .read_phycap            = rtw8852b_read_phycap,
        .fem_setup              = NULL,
+       .rfe_gpio               = NULL,
        .rfk_init               = rtw8852b_rfk_init,
        .rfk_channel            = rtw8852b_rfk_channel,
        .rfk_band_changed       = rtw8852b_rfk_band_changed,
index f2e70bda8e480da48c69ac8adae1ea8257873386..e4c984c87d6cc14a3e09372f1c21a4bbae731de1 100644 (file)
@@ -2762,6 +2762,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
        .read_efuse             = rtw8852c_read_efuse,
        .read_phycap            = rtw8852c_read_phycap,
        .fem_setup              = NULL,
+       .rfe_gpio               = NULL,
        .rfk_init               = rtw8852c_rfk_init,
        .rfk_channel            = rtw8852c_rfk_channel,
        .rfk_band_changed       = rtw8852c_rfk_band_changed,