[rt2x00-users] [PATCH] rt2x00: Add support for RT3572/RT3592/RT3592+Bluetooth combo card

Shiang Tu shiang_tu at ralinktech.com
Tue Apr 12 01:02:30 EST 2011


Add support for RT3572/RT3592/RT3592+Bluetooth combo card

Signed-off-by: Shiang Tu <shiang_tu at ralinktech.com>
---
 drivers/net/wireless/rt2x00/rt2800.h    |   16 ++
 drivers/net/wireless/rt2x00/rt2800lib.c |  320 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/rt2x00/rt2800pci.c |    4 +-
 3 files changed, 331 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 3b3d851..4f43870 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1738,6 +1738,7 @@ struct mac_iveiv_entry {
 /*
  * BBP 3: RX Antenna
  */
+#define BBP3_RX_ADC				FIELD8(0x03)
 #define BBP3_RX_ANTENNA			FIELD8(0x18)
 #define BBP3_HT40_MINUS			FIELD8(0x20)
 
@@ -1781,6 +1782,8 @@ struct mac_iveiv_entry {
 #define RFCSR1_TX0_PD			FIELD8(0x08)
 #define RFCSR1_RX1_PD			FIELD8(0x10)
 #define RFCSR1_TX1_PD			FIELD8(0x20)
+#define RFCSR1_RX2_PD			FIELD8(0x40)
+#define RFCSR1_TX2_PD			FIELD8(0x80)
 
 /*
  * RFCSR 2:
@@ -1788,15 +1791,25 @@ struct mac_iveiv_entry {
 #define RFCSR2_RESCAL_EN		FIELD8(0x80)
 
 /*
+ * FRCSR 5:
+ */
+#define RFCSR5_R1			FIELD8(0x0c)
+
+/*
  * RFCSR 6:
  */
 #define RFCSR6_R1			FIELD8(0x03)
 #define RFCSR6_R2			FIELD8(0x40)
+#define RFCSR6_TXDIV		FIELD8(0x0c)
 
 /*
  * RFCSR 7:
  */
 #define RFCSR7_RF_TUNING		FIELD8(0x01)
+#define RFCSR7_R02				FIELD8(0x07)
+#define RFCSR7_R3				FIELD8(0x08)
+#define RFCSR7_R45				FIELD8(0x30)
+#define RFCSR7_R67				FIELD8(0xc0)
 
 /*
  * RFCSR 11:
@@ -1807,11 +1820,13 @@ struct mac_iveiv_entry {
  * RFCSR 12:
  */
 #define RFCSR12_TX_POWER		FIELD8(0x1f)
+#define RFCSR12_DR0				FIELD8(0xe0)
 
 /*
  * RFCSR 13:
  */
 #define RFCSR13_TX_POWER		FIELD8(0x1f)
+#define RFCSR13_DR0				FIELD8(0xe0)
 
 /*
  * RFCSR 15:
@@ -2254,6 +2269,7 @@ struct mac_iveiv_entry {
 #define MCU_ANT_SELECT			0X73
 #define MCU_BBP_SIGNAL			0x80
 #define MCU_POWER_SAVE			0x83
+#define MCU_BAND_SELECT		0x91
 
 /*
  * MCU mailbox tokens
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 0e2c006..09fb076 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 		return -EBUSY;
 
 	if (rt2x00_is_pci(rt2x00dev)) {
-		if (rt2x00_rt(rt2x00dev, RT5390)) {
+		if (rt2x00_rt(rt2x00dev, RT5390) ||
+		    rt2x00_rt(rt2x00dev, RT3572)) {
 			rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
 			rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
 			rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
@@ -1473,10 +1474,55 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 	u8 r1;
 	u8 r3;
 	u16 eeprom;
+	u8 is_3592cb_card;
 
 	rt2800_bbp_read(rt2x00dev, 1, &r1);
 	rt2800_bbp_read(rt2x00dev, 3, &r3);
 
+	if (rt2x00_rt(rt2x00dev, RT3572)) {
+		rt2x00_eeprom_read(rt2x00dev,
+				EEPROM_NIC_CONF1, &eeprom);
+		is_3592cb_card = rt2x00_get_field16(eeprom,
+				EEPROM_NIC_CONF1_BT_COEXIST) ? 1 : 0;
+	} else
+		is_3592cb_card = 0;
+
+	if (is_3592cb_card) {
+		u32 reg;
+		u8 led_ctrl, led_g_mode, led_r_mode;
+
+		rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
+		if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
+			rt2x00_set_field32(&reg, GPIO_SWITCH_0, 1);
+			rt2x00_set_field32(&reg, GPIO_SWITCH_1, 1);
+		} else {
+			rt2x00_set_field32(&reg, GPIO_SWITCH_0, 0);
+			rt2x00_set_field32(&reg, GPIO_SWITCH_1, 0);
+		}
+		rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+
+		rt2800_register_read(rt2x00dev, LED_CFG, &reg);
+		led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0;
+		led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
+		if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
+		    led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
+			rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+			led_ctrl = rt2x00_get_field16(eeprom,
+						EEPROM_FREQ_LED_MODE);
+			if (led_ctrl == 0 || led_ctrl > 0x40) {
+				rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE,
+							led_g_mode);
+				rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE,
+							led_r_mode);
+				rt2800_register_write(rt2x00dev, LED_CFG, reg);
+			} else {
+				rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT,
+					0xff, (led_g_mode << 2) | led_r_mode,
+					1);
+			}
+		}
+	}
+
 	/*
 	 * Configure the TX antenna.
 	 */
@@ -1485,7 +1531,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
 		break;
 	case 2:
-		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+		if (is_3592cb_card)
+			rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1);
+		else
+			rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
 		break;
 	case 3:
 		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
@@ -1510,7 +1559,13 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
 		break;
 	case 2:
-		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+		if (is_3592cb_card) {
+			rt2x00_set_field8(&r3, BBP3_RX_ADC, 1);
+			rt2x00_set_field8(&r3, BBP3_RX_ANTENNA,
+				rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
+			rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B);
+		} else
+			rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
 		break;
 	case 3:
 		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
@@ -1644,6 +1699,180 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
 	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
+static void rt2800_config_channel_rf35xx(struct rt2x00_dev *rt2x00dev,
+					 struct ieee80211_conf *conf,
+					 struct rf_channel *rf,
+					 struct channel_info *info)
+{
+	u8 rfcsr, rfcsr2, rfcsr3;
+	u16 eeprom;
+	u32 reg;
+
+	if (rf->channel <= 14) {
+		rt2800_bbp_write(rt2x00dev, 25, 0x15);
+		rt2800_bbp_write(rt2x00dev, 26, 0x85);
+	} else {
+		rt2800_bbp_write(rt2x00dev, 25, 0x09);
+		rt2800_bbp_write(rt2x00dev, 26, 0xff);
+	}
+
+	rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
+	rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
+	if (rf->channel <= 14)
+		rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2);
+	else
+		rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1);
+	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr);
+	if (rf->channel <= 14)
+		rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1);
+	else
+		rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2);
+	rt2800_rfcsr_write(rt2x00dev, 5, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
+	if (rf->channel <= 14) {
+		rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
+		rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+				(info->default_power1 & 0x3) |
+				((info->default_power1 & 0xC) << 1));
+	} else {
+		rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
+		rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+				(info->default_power1 & 0x3) |
+				((info->default_power1 & 0xC) << 1));
+	}
+	rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
+	if (rf->channel <= 14) {
+		rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
+		rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+				(info->default_power2 & 0x3) |
+				((info->default_power2 & 0xC) << 1));
+	} else {
+		rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
+		rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+				(info->default_power2 & 0x3) |
+				((info->default_power2 & 0xC) << 1));
+	}
+	rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+		if (rf->channel <= 14) {
+			rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+			rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+		}
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+	} else {
+		switch (rt2x00dev->default_ant.tx_chain_num) {
+		case 1:
+			rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+		case 2:
+			rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+			break;
+		}
+
+		switch (rt2x00dev->default_ant.rx_chain_num) {
+		case 1:
+			rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+		case 2:
+			rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+			break;
+		}
+	}
+	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+	rt2800_rfcsr_write(rt2x00dev, 24,
+			      rt2x00dev->calibration[conf_is_ht40(conf)]);
+	rt2800_rfcsr_write(rt2x00dev, 31,
+			      rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+	if (rf->channel <= 14)
+		rfcsr = 0xd8;
+	else {
+		rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+		rt2x00_set_field8(&rfcsr, RFCSR7_R02, 4);
+		rt2x00_set_field8(&rfcsr, RFCSR7_R3, 0);
+		rt2x00_set_field8(&rfcsr, RFCSR7_R45, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR7_R67, 0);
+	}
+	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+
+	rfcsr = (rf->channel <= 14) ? 0xc3 : 0xc0;
+	rt2800_rfcsr_write(rt2x00dev, 9, rfcsr);
+
+	rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+
+	rfcsr = (rf->channel <= 14) ? 0xb9 : 0x00;
+	rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
+
+	rfcsr = (rf->channel <= 14) ? 0x53 : 0x43;
+	rt2800_rfcsr_write(rt2x00dev, 15, rfcsr);
+
+	rfcsr = (rf->channel <= 14) ? 0x4c : 0x7a;
+	rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
+
+	rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+
+	if (rf->channel <= 14) {
+		rfcsr = 0x93;
+		rfcsr2 = 0xb3;
+		rfcsr3 = 0x15;
+	} else if (rf->channel <= 64) {
+		rfcsr = 0xb7;
+		rfcsr2 = 0xf6;
+		rfcsr3 = 0x3d;
+	} else if (rf->channel <= 128) {
+		rfcsr = 0x74;
+		rfcsr2 = 0xf4;
+		rfcsr3 = 0x01;
+	} else {
+		rfcsr = 0x72;
+		rfcsr2 = 0xf3;
+		rfcsr3 = 0x01;
+	}
+	rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
+	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr2);
+	rt2800_rfcsr_write(rt2x00dev, 25, rfcsr3);
+
+	rfcsr = (rf->channel <= 14) ? 0x85 : 0x87;
+	rt2800_rfcsr_write(rt2x00dev, 26, rfcsr);
+
+	rfcsr = (rf->channel <= 14) ? 0x00 : 0x01;
+	rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
+
+	rfcsr = (rf->channel <= 14) ? 0x9b : 0x9f;
+	rt2800_rfcsr_write(rt2x00dev, 29, rfcsr);
+
+	rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+	rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
+	if (rf->channel <= 14)
+		rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 1);
+	else
+		rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 0);
+	rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+
+	rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+}
 
 #define RT5390_POWER_BOUND     0x27
 #define RT5390_FREQ_OFFSET_BOUND       0x5f
@@ -1760,11 +1989,12 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 		info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
 	}
 
-	if (rt2x00_rf(rt2x00dev, RF2020) ||
+	if (rt2x00_rt(rt2x00dev, RT3572))
+		rt2800_config_channel_rf35xx(rt2x00dev, conf, rf, info);
+	else if (rt2x00_rf(rt2x00dev, RF2020) ||
 	    rt2x00_rf(rt2x00dev, RF3020) ||
 	    rt2x00_rf(rt2x00dev, RF3021) ||
 	    rt2x00_rf(rt2x00dev, RF3022) ||
-	    rt2x00_rf(rt2x00dev, RF3052) ||
 	    rt2x00_rf(rt2x00dev, RF3320))
 		rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
 	else if (rt2x00_rf(rt2x00dev, RF5390))
@@ -1792,7 +2022,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 			}
 		}
 	} else {
-		rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+		if (rt2x00_rt(rt2x00dev, RT3572))
+			rt2800_bbp_write(rt2x00dev, 82, 0x94);
+		else
+			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
 
 		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
 			rt2800_bbp_write(rt2x00dev, 75, 0x46);
@@ -1806,12 +2039,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
 	rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
 
+	if (rt2x00_rt(rt2x00dev, RT3572))
+		rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
 	tx_pin = 0;
 
 	/* Turn on unused PA or LNA when not using 1T or 1R */
 	if (rt2x00dev->default_ant.tx_chain_num == 2) {
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
+				rf->channel > 14);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
+				rf->channel <= 14);
 	}
 
 	/* Turn on unused PA or LNA when not using 1T or 1R */
@@ -1825,10 +2063,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+	if (rt2x00_rt(rt2x00dev, RT3572)) {
+		u16 eeprom, bt_cap;
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+		bt_cap = rt2x00_get_field16(eeprom,
+						EEPROM_NIC_CONF1_BT_COEXIST);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
+				((rf->channel <= 14) && (!bt_cap)));
+	}
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
 
 	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
 
+	if (rt2x00_rt(rt2x00dev, RT3572))
+		rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
+
 	rt2800_bbp_read(rt2x00dev, 4, &bbp);
 	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
 	rt2800_bbp_write(rt2x00dev, 4, bbp);
@@ -2432,6 +2682,9 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+	} else if (rt2x00_rt(rt2x00dev, RT3572)) {
+		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
 	} else {
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2814,6 +3067,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	}
 
 	if (rt2800_is_305x_soc(rt2x00dev) ||
+		rt2x00_rt(rt2x00dev, RT3572) ||
 	    rt2x00_rt(rt2x00dev, RT5390))
 		rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
@@ -2843,6 +3097,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	    rt2x00_rt(rt2x00dev, RT3071) ||
 	    rt2x00_rt(rt2x00dev, RT3090) ||
 	    rt2x00_rt(rt2x00dev, RT3390) ||
+	    rt2x00_rt(rt2x00dev, RT3572) ||
 	    rt2x00_rt(rt2x00dev, RT5390)) {
 		rt2800_bbp_write(rt2x00dev, 79, 0x13);
 		rt2800_bbp_write(rt2x00dev, 80, 0x05);
@@ -2883,6 +3138,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	    rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
 	    rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
 	    rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
+	    rt2x00_rt(rt2x00dev, RT3572) ||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 	    rt2800_is_305x_soc(rt2x00dev))
 		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
@@ -2910,6 +3166,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	if (rt2x00_rt(rt2x00dev, RT3071) ||
 	    rt2x00_rt(rt2x00dev, RT3090) ||
 	    rt2x00_rt(rt2x00dev, RT3390) ||
+	    rt2x00_rt(rt2x00dev, RT3572) ||
 	    rt2x00_rt(rt2x00dev, RT5390)) {
 		rt2800_bbp_read(rt2x00dev, 138, &value);
 
@@ -3047,6 +3304,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 	    !rt2x00_rt(rt2x00dev, RT3071) &&
 	    !rt2x00_rt(rt2x00dev, RT3090) &&
 	    !rt2x00_rt(rt2x00dev, RT3390) &&
+	    !rt2x00_rt(rt2x00dev, RT3572) &&
 	    !rt2x00_rt(rt2x00dev, RT5390) &&
 	    !rt2800_is_305x_soc(rt2x00dev))
 		return 0;
@@ -3092,6 +3350,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 		rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
 		rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
 		rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
+	} else if (rt2x00_rt(rt2x00dev, RT3572)) {
+		rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
+		rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
+		rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
+		rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
+		rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
+		rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
+		rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
+		rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
+		rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+		rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
+		rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
+		rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
+		rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
+		rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+		rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+		rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+		rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
+		rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
+		rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
+		rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
+		rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+		rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
+		rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
+		rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
+		rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+		rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+		rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+		rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
+		rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
+		rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
 	} else if (rt2x00_rt(rt2x00dev, RT3390)) {
 		rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
 		rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
@@ -3274,6 +3564,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 		rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
 		rt2x00_set_field32(&reg, GPIO_SWITCH_5, 0);
 		rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+	} else if (rt2x00_rt(rt2x00dev, RT3572)) {
+		rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+		rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
+		rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+		rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+		rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+		rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+		msleep(1);
+		rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+		rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
 	}
 
 	/*
@@ -3286,6 +3589,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 			rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
 	} else if (rt2x00_rt(rt2x00dev, RT3071) ||
 		   rt2x00_rt(rt2x00dev, RT3090) ||
+		   rt2x00_rt(rt2x00dev, RT3572) ||
 		   rt2x00_rt(rt2x00dev, RT3390)) {
 		rt2x00dev->calibration[0] =
 			rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 4241f19..e018508 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -493,7 +493,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
 	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
 
-	if (rt2x00_rt(rt2x00dev, RT5390)) {
+	if (rt2x00_is_pcie(rt2x00dev) &&
+	    (rt2x00_rt(rt2x00dev, RT5390) ||
+	    rt2x00_rt(rt2x00dev, RT3572))) {
 		rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
 		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
 		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
-- 
1.7.1




More information about the users mailing list