Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtw88: 8723d: Add coex support

8723D is a Wifi+BT combo card. To make them work properly, we need coex
mechanism to avoid interference, such as TX simultaneously. Basically,
coex.c provide main algorithm to deal with many use cases, and this commit
adds some parameters and ops differ from other chips, because coex
hardware and WiFi generation are changed.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200512102621.5148-8-yhchuang@realtek.com

authored by

Ping-Ke Shih and committed by
Kalle Valo
d1391c49 7e149368

+330
+327
drivers/net/wireless/realtek/rtw88/rtw8723d.c
··· 1497 1497 rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] finished\n"); 1498 1498 } 1499 1499 1500 + /* for coex */ 1501 + static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev) 1502 + { 1503 + /* enable TBTT nterrupt */ 1504 + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 1505 + 1506 + /* BT report packet sample rate */ 1507 + /* 0x790[5:0]=0x5 */ 1508 + rtw_write8_set(rtwdev, REG_BT_TDMA_TIME, 0x05); 1509 + 1510 + /* enable BT counter statistics */ 1511 + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); 1512 + 1513 + /* enable PTA (3-wire function form BT side) */ 1514 + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 1515 + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_AOD_GPIO3); 1516 + 1517 + /* enable PTA (tx/rx signal form WiFi side) */ 1518 + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 1519 + } 1520 + 1521 + static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 1522 + { 1523 + } 1524 + 1525 + static void rtw8723d_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) 1526 + { 1527 + rtw_write8_mask(rtwdev, REG_LEDCFG2, BIT(6), 0); 1528 + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(0), 0); 1529 + rtw_write8_mask(rtwdev, REG_GPIO_INTM + 2, BIT(4), 0); 1530 + rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT(1), 0); 1531 + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(1), 0); 1532 + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT(7), 0); 1533 + rtw_write8_mask(rtwdev, REG_SYS_CLKR + 1, BIT(1), 0); 1534 + rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT(3), 0); 1535 + } 1536 + 1537 + static void rtw8723d_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 1538 + { 1539 + struct rtw_efuse *efuse = &rtwdev->efuse; 1540 + struct rtw_coex *coex = &rtwdev->coex; 1541 + struct rtw_coex_rfe *coex_rfe = &coex->rfe; 1542 + bool aux = efuse->bt_setting & BIT(6); 1543 + 1544 + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; 1545 + coex_rfe->ant_switch_polarity = 0; 1546 + coex_rfe->ant_switch_exist = false; 1547 + coex_rfe->ant_switch_with_bt = false; 1548 + coex_rfe->ant_switch_diversity = false; 1549 + coex_rfe->wlg_at_btg = true; 1550 + 1551 + /* decide antenna at main or aux */ 1552 + if (efuse->share_ant) { 1553 + if (aux) 1554 + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x80); 1555 + else 1556 + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x200); 1557 + } else { 1558 + if (aux) 1559 + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x280); 1560 + else 1561 + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x0); 1562 + } 1563 + 1564 + /* disable LTE coex in wifi side */ 1565 + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); 1566 + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); 1567 + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); 1568 + } 1569 + 1570 + static void rtw8723d_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 1571 + { 1572 + struct rtw_coex *coex = &rtwdev->coex; 1573 + struct rtw_coex_dm *coex_dm = &coex->dm; 1574 + static const u8 wl_tx_power[] = {0xb2, 0x90}; 1575 + u8 pwr; 1576 + 1577 + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) 1578 + return; 1579 + 1580 + coex_dm->cur_wl_pwr_lvl = wl_pwr; 1581 + 1582 + if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power)) 1583 + coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1; 1584 + 1585 + pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl]; 1586 + 1587 + rtw_write8(rtwdev, REG_ANA_PARAM1 + 3, pwr); 1588 + } 1589 + 1590 + static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 1591 + { 1592 + struct rtw_coex *coex = &rtwdev->coex; 1593 + struct rtw_coex_dm *coex_dm = &coex->dm; 1594 + /* WL Rx Low gain on */ 1595 + static const u32 wl_rx_low_gain_on[] = { 1596 + 0xec120101, 0xeb130101, 0xce140101, 0xcd150101, 0xcc160101, 1597 + 0xcb170101, 0xca180101, 0x8d190101, 0x8c1a0101, 0x8b1b0101, 1598 + 0x4f1c0101, 0x4e1d0101, 0x4d1e0101, 0x4c1f0101, 0x0e200101, 1599 + 0x0d210101, 0x0c220101, 0x0b230101, 0xcf240001, 0xce250001, 1600 + 0xcd260001, 0xcc270001, 0x8f280001 1601 + }; 1602 + /* WL Rx Low gain off */ 1603 + static const u32 wl_rx_low_gain_off[] = { 1604 + 0xec120101, 0xeb130101, 0xea140101, 0xe9150101, 0xe8160101, 1605 + 0xe7170101, 0xe6180101, 0xe5190101, 0xe41a0101, 0xe31b0101, 1606 + 0xe21c0101, 0xe11d0101, 0xe01e0101, 0x861f0101, 0x85200101, 1607 + 0x84210101, 0x83220101, 0x82230101, 0x81240101, 0x80250101, 1608 + 0x44260101, 0x43270101, 0x42280101 1609 + }; 1610 + u8 i; 1611 + 1612 + if (low_gain == coex_dm->cur_wl_rx_low_gain_en) 1613 + return; 1614 + 1615 + coex_dm->cur_wl_rx_low_gain_en = low_gain; 1616 + 1617 + if (coex_dm->cur_wl_rx_low_gain_en) { 1618 + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++) 1619 + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_on[i]); 1620 + } else { 1621 + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) 1622 + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_off[i]); 1623 + } 1624 + } 1625 + 1500 1626 static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) 1501 1627 { 1502 1628 struct rtw_dm_info *dm_info = &rtwdev->dm_info; ··· 1934 1808 .config_bfee = NULL, 1935 1809 .set_gid_table = NULL, 1936 1810 .cfg_csi_rate = NULL, 1811 + 1812 + .coex_set_init = rtw8723d_coex_cfg_init, 1813 + .coex_set_ant_switch = NULL, 1814 + .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, 1815 + .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, 1816 + .coex_set_rfe_type = rtw8723d_coex_cfg_rfe_type, 1817 + .coex_set_wl_tx_power = rtw8723d_coex_cfg_wl_tx_power, 1818 + .coex_set_wl_rx_gain = rtw8723d_coex_cfg_wl_rx_gain, 1819 + }; 1820 + 1821 + /* Shared-Antenna Coex Table */ 1822 + static const struct coex_table_para table_sant_8723d[] = { 1823 + {0xffffffff, 0xffffffff}, /* case-0 */ 1824 + {0x55555555, 0x55555555}, 1825 + {0x65555555, 0x65555555}, 1826 + {0xaaaaaaaa, 0xaaaaaaaa}, 1827 + {0x5a5a5a5a, 0x5a5a5a5a}, 1828 + {0xfafafafa, 0xfafafafa}, /* case-5 */ 1829 + {0xa5555555, 0xaaaa5aaa}, 1830 + {0x6a5a5a5a, 0x5a5a5a5a}, 1831 + {0x6a5a5a5a, 0x6a5a5a5a}, 1832 + {0x65555555, 0x5a5a5a5a}, 1833 + {0x65555555, 0x6a5a5a5a}, /* case-10 */ 1834 + {0x65555555, 0xfafafafa}, 1835 + {0x65555555, 0x6a5a5aaa}, 1836 + {0x65555555, 0x5aaa5aaa}, 1837 + {0x65555555, 0xaaaa5aaa}, 1838 + {0x65555555, 0xaaaaaaaa}, /* case-15 */ 1839 + {0xffff55ff, 0xfafafafa}, 1840 + {0xffff55ff, 0x6afa5afa}, 1841 + {0xaaffffaa, 0xfafafafa}, 1842 + {0xaa5555aa, 0x5a5a5a5a}, 1843 + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 1844 + {0xaa5555aa, 0xaaaaaaaa}, 1845 + {0xffffffff, 0x5a5a5a5a}, 1846 + {0xffffffff, 0x6a5a5a5a}, 1847 + {0xffffffff, 0x55555555}, 1848 + {0xffffffff, 0x6a5a5aaa}, /* case-25 */ 1849 + {0x55555555, 0x5a5a5a5a}, 1850 + {0x55555555, 0xaaaaaaaa}, 1851 + {0x55555555, 0x6a6a6a6a}, 1852 + {0x656a656a, 0x656a656a} 1853 + }; 1854 + 1855 + /* Non-Shared-Antenna Coex Table */ 1856 + static const struct coex_table_para table_nsant_8723d[] = { 1857 + {0xffffffff, 0xffffffff}, /* case-100 */ 1858 + {0x55555555, 0x55555555}, 1859 + {0x65555555, 0x65555555}, 1860 + {0xaaaaaaaa, 0xaaaaaaaa}, 1861 + {0x5a5a5a5a, 0x5a5a5a5a}, 1862 + {0xfafafafa, 0xfafafafa}, /* case-105 */ 1863 + {0x5afa5afa, 0x5afa5afa}, 1864 + {0x55555555, 0xfafafafa}, 1865 + {0x65555555, 0xfafafafa}, 1866 + {0x65555555, 0x5a5a5a5a}, 1867 + {0x65555555, 0x6a5a5a5a}, /* case-110 */ 1868 + {0x65555555, 0xaaaaaaaa}, 1869 + {0xffff55ff, 0xfafafafa}, 1870 + {0xffff55ff, 0x5afa5afa}, 1871 + {0xffff55ff, 0xaaaaaaaa}, 1872 + {0xaaffffaa, 0xfafafafa}, /* case-115 */ 1873 + {0xaaffffaa, 0x5afa5afa}, 1874 + {0xaaffffaa, 0xaaaaaaaa}, 1875 + {0xffffffff, 0xfafafafa}, 1876 + {0xffffffff, 0x5afa5afa}, 1877 + {0xffffffff, 0xaaaaaaaa},/* case-120 */ 1878 + {0x55ff55ff, 0x5afa5afa}, 1879 + {0x55ff55ff, 0xaaaaaaaa}, 1880 + {0x55ff55ff, 0x55ff55ff} 1881 + }; 1882 + 1883 + /* Shared-Antenna TDMA */ 1884 + static const struct coex_tdma_para tdma_sant_8723d[] = { 1885 + { {0x08, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 1886 + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 1887 + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 1888 + { {0x61, 0x20, 0x03, 0x11, 0x11} }, 1889 + { {0x61, 0x30, 0x03, 0x11, 0x11} }, 1890 + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ 1891 + { {0x61, 0x48, 0x03, 0x11, 0x10} }, 1892 + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 1893 + { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1894 + { {0x61, 0x20, 0x03, 0x11, 0x10} }, 1895 + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 1896 + { {0x61, 0x10, 0x03, 0x11, 0x14} }, 1897 + { {0x61, 0x08, 0x03, 0x10, 0x14} }, 1898 + { {0x51, 0x10, 0x03, 0x10, 0x54} }, 1899 + { {0x51, 0x10, 0x03, 0x10, 0x55} }, 1900 + { {0x51, 0x10, 0x07, 0x10, 0x54} }, /* case-15 */ 1901 + { {0x51, 0x45, 0x03, 0x10, 0x50} }, 1902 + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 1903 + { {0x51, 0x30, 0x03, 0x10, 0x50} }, 1904 + { {0x51, 0x20, 0x03, 0x10, 0x50} }, 1905 + { {0x51, 0x15, 0x03, 0x10, 0x50} }, /* case-20 */ 1906 + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 1907 + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, 1908 + { {0x55, 0x08, 0x03, 0x10, 0x54} }, 1909 + { {0x65, 0x10, 0x03, 0x11, 0x11} }, 1910 + { {0x51, 0x10, 0x03, 0x10, 0x51} }, 1911 + { {0x61, 0x15, 0x03, 0x11, 0x10} } 1912 + }; 1913 + 1914 + /* Non-Shared-Antenna TDMA */ 1915 + static const struct coex_tdma_para tdma_nsant_8723d[] = { 1916 + { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ 1917 + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */ 1918 + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 1919 + { {0x61, 0x30, 0x03, 0x11, 0x11} }, 1920 + { {0x61, 0x20, 0x03, 0x11, 0x11} }, 1921 + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ 1922 + { {0x61, 0x45, 0x03, 0x11, 0x10} }, 1923 + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 1924 + { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1925 + { {0x61, 0x20, 0x03, 0x11, 0x10} }, 1926 + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ 1927 + { {0x61, 0x08, 0x03, 0x11, 0x14} }, 1928 + { {0x61, 0x08, 0x03, 0x10, 0x14} }, 1929 + { {0x51, 0x08, 0x03, 0x10, 0x54} }, 1930 + { {0x51, 0x08, 0x03, 0x10, 0x55} }, 1931 + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ 1932 + { {0x51, 0x45, 0x03, 0x10, 0x50} }, 1933 + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 1934 + { {0x51, 0x30, 0x03, 0x10, 0x50} }, 1935 + { {0x51, 0x20, 0x03, 0x10, 0x50} }, 1936 + { {0x51, 0x10, 0x03, 0x10, 0x50} } 1937 + }; 1938 + 1939 + /* rssi in percentage % (dbm = % - 100) */ 1940 + static const u8 wl_rssi_step_8723d[] = {60, 50, 44, 30}; 1941 + static const u8 bt_rssi_step_8723d[] = {30, 30, 30, 30}; 1942 + static const struct coex_5g_afh_map afh_5g_8723d[] = { {0, 0, 0} }; 1943 + 1944 + /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ 1945 + static const struct coex_rf_para rf_para_tx_8723d[] = { 1946 + {0, 0, false, 7}, /* for normal */ 1947 + {0, 10, false, 7}, /* for WL-CPT */ 1948 + {1, 0, true, 4}, 1949 + {1, 2, true, 4}, 1950 + {1, 10, true, 4}, 1951 + {1, 15, true, 4} 1952 + }; 1953 + 1954 + static const struct coex_rf_para rf_para_rx_8723d[] = { 1955 + {0, 0, false, 7}, /* for normal */ 1956 + {0, 10, false, 7}, /* for WL-CPT */ 1957 + {1, 0, true, 5}, 1958 + {1, 2, true, 5}, 1959 + {1, 10, true, 5}, 1960 + {1, 15, true, 5} 1937 1961 }; 1938 1962 1939 1963 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = { ··· 2639 2363 .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, 2640 2364 }; 2641 2365 2366 + static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { 2367 + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 2368 + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, 2369 + {0, 0, RTW_REG_DOMAIN_NL}, 2370 + {0x964, BIT(1), RTW_REG_DOMAIN_MAC8}, 2371 + {0x864, BIT(0), RTW_REG_DOMAIN_MAC8}, 2372 + {0xab7, BIT(5), RTW_REG_DOMAIN_MAC8}, 2373 + {0xa01, BIT(7), RTW_REG_DOMAIN_MAC8}, 2374 + {0, 0, RTW_REG_DOMAIN_NL}, 2375 + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 2376 + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 2377 + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 2378 + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 2379 + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, 2380 + {0, 0, RTW_REG_DOMAIN_NL}, 2381 + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, 2382 + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, 2383 + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 2384 + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 2385 + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, 2386 + }; 2387 + 2642 2388 struct rtw_chip_info rtw8723d_hw_spec = { 2643 2389 .ops = &rtw8723d_ops, 2644 2390 .id = RTW_CHIP_TYPE_8723D, ··· 2707 2409 .rx_ldpc = false, 2708 2410 .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, 2709 2411 .iqk_threshold = 8, 2412 + 2413 + .coex_para_ver = 0x1905302f, 2414 + .bt_desired_ver = 0x2f, 2415 + .scbd_support = true, 2416 + .new_scbd10_def = true, 2417 + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 2418 + .bt_rssi_type = COEX_BTRSSI_RATIO, 2419 + .ant_isolation = 15, 2420 + .rssi_tolerance = 2, 2421 + .wl_rssi_step = wl_rssi_step_8723d, 2422 + .bt_rssi_step = bt_rssi_step_8723d, 2423 + .table_sant_num = ARRAY_SIZE(table_sant_8723d), 2424 + .table_sant = table_sant_8723d, 2425 + .table_nsant_num = ARRAY_SIZE(table_nsant_8723d), 2426 + .table_nsant = table_nsant_8723d, 2427 + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8723d), 2428 + .tdma_sant = tdma_sant_8723d, 2429 + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8723d), 2430 + .tdma_nsant = tdma_nsant_8723d, 2431 + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8723d), 2432 + .wl_rf_para_tx = rf_para_tx_8723d, 2433 + .wl_rf_para_rx = rf_para_rx_8723d, 2434 + .bt_afh_span_bw20 = 0x20, 2435 + .bt_afh_span_bw40 = 0x30, 2436 + .afh_5g_num = ARRAY_SIZE(afh_5g_8723d), 2437 + .afh_5g = afh_5g_8723d, 2438 + 2439 + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8723d), 2440 + .coex_info_hw_regs = coex_info_hw_regs_8723d, 2710 2441 }; 2711 2442 EXPORT_SYMBOL(rtw8723d_hw_spec); 2712 2443
+3
drivers/net/wireless/realtek/rtw88/rtw8723d.h
··· 143 143 #define BIT_MASK_RFMOD BIT(0) 144 144 #define BIT_LCK BIT(15) 145 145 146 + #define REG_GPIO_INTM 0x0048 146 147 #define REG_BTG_SEL 0x0067 147 148 #define REG_LTECOEX_PATH_CONTROL 0x0070 148 149 #define REG_LTECOEX_CTRL 0x07c0 ··· 151 150 #define REG_LTECOEX_READ_DATA 0x07c8 152 151 #define REG_PSDFN 0x0808 153 152 #define REG_BB_PWR_SAV1_11N 0x0874 153 + #define REG_ANA_PARAM1 0x0880 154 154 #define REG_ANALOG_P4 0x088c 155 155 #define REG_PSDRPT 0x08b4 156 156 #define REG_FPGA1_RFMOD 0x0900 ··· 194 192 #define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) 195 193 #define REG_OFDM0_XAAGC1 0x0c50 196 194 #define REG_OFDM0_XBAGC1 0x0c58 195 + #define REG_AGCRSSI 0x0c78 197 196 #define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 198 197 #define BIT_MASK_TXIQ_ELM_A 0x03ff 199 198 #define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \