Commit 2e9c43dd authored by John Li's avatar John Li Committed by John W. Linville
Browse files

rt2x00:Add VCO recalibration

parent 9da27232
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -965,6 +965,7 @@
 * TX_PIN_CFG:
 */
#define TX_PIN_CFG			0x1328
#define TX_PIN_CFG_PA_PE_DISABLE	0xfcfffff0
#define TX_PIN_CFG_PA_PE_A0_EN		FIELD32(0x00000001)
#define TX_PIN_CFG_PA_PE_G0_EN		FIELD32(0x00000002)
#define TX_PIN_CFG_PA_PE_A1_EN		FIELD32(0x00000004)
@@ -985,6 +986,14 @@
#define TX_PIN_CFG_RFTR_POL		FIELD32(0x00020000)
#define TX_PIN_CFG_TRSW_EN		FIELD32(0x00040000)
#define TX_PIN_CFG_TRSW_POL		FIELD32(0x00080000)
#define TX_PIN_CFG_PA_PE_A2_EN		FIELD32(0x01000000)
#define TX_PIN_CFG_PA_PE_G2_EN		FIELD32(0x02000000)
#define TX_PIN_CFG_PA_PE_A2_POL		FIELD32(0x04000000)
#define TX_PIN_CFG_PA_PE_G2_POL		FIELD32(0x08000000)
#define TX_PIN_CFG_LNA_PE_A2_EN		FIELD32(0x10000000)
#define TX_PIN_CFG_LNA_PE_G2_EN		FIELD32(0x20000000)
#define TX_PIN_CFG_LNA_PE_A2_POL	FIELD32(0x40000000)
#define TX_PIN_CFG_LNA_PE_G2_POL	FIELD32(0x80000000)

/*
 * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
+88 −0
Original line number Diff line number Diff line
@@ -2497,6 +2497,80 @@ void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2800_gain_calibration);

void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
{
	u32	tx_pin;
	u8	rfcsr;

	/*
	 * A voltage-controlled oscillator(VCO) is an electronic oscillator
	 * designed to be controlled in oscillation frequency by a voltage
	 * input. Maybe the temperature will affect the frequency of
	 * oscillation to be shifted. The VCO calibration will be called
	 * periodically to adjust the frequency to be precision.
	*/

	rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
	tx_pin &= TX_PIN_CFG_PA_PE_DISABLE;
	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);

	switch (rt2x00dev->chip.rf) {
	case RF2020:
	case RF3020:
	case RF3021:
	case RF3022:
	case RF3320:
	case RF3052:
		rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
		rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
		rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
		break;
	case RF5370:
	case RF5372:
	case RF5390:
		rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
		rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
		rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
		break;
	default:
		return;
	}

	mdelay(1);

	rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
	if (rt2x00dev->rf_channel <= 14) {
		switch (rt2x00dev->default_ant.tx_chain_num) {
		case 3:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, 1);
			/* fall through */
		case 2:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
			/* fall through */
		case 1:
		default:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
			break;
		}
	} else {
		switch (rt2x00dev->default_ant.tx_chain_num) {
		case 3:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN, 1);
			/* fall through */
		case 2:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
			/* fall through */
		case 1:
		default:
			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, 1);
			break;
		}
	}
	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);

}
EXPORT_SYMBOL_GPL(rt2800_vco_calibration);

static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
				      struct rt2x00lib_conf *libconf)
{
@@ -4451,6 +4525,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
		}
	}

	switch (rt2x00dev->chip.rf) {
	case RF2020:
	case RF3020:
	case RF3021:
	case RF3022:
	case RF3320:
	case RF3052:
	case RF5370:
	case RF5372:
	case RF5390:
		__set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags);
		break;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode);
+1 −0
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
		       const u32 count);
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);

int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
+1 −0
Original line number Diff line number Diff line
@@ -1050,6 +1050,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
	.reset_tuner		= rt2800_reset_tuner,
	.link_tuner		= rt2800_link_tuner,
	.gain_calibration	= rt2800_gain_calibration,
	.vco_calibration	= rt2800_vco_calibration,
	.start_queue		= rt2800pci_start_queue,
	.kick_queue		= rt2800pci_kick_queue,
	.stop_queue		= rt2800pci_stop_queue,
+1 −0
Original line number Diff line number Diff line
@@ -781,6 +781,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
	.reset_tuner		= rt2800_reset_tuner,
	.link_tuner		= rt2800_link_tuner,
	.gain_calibration	= rt2800_gain_calibration,
	.vco_calibration	= rt2800_vco_calibration,
	.watchdog		= rt2800usb_watchdog,
	.start_queue		= rt2800usb_start_queue,
	.kick_queue		= rt2x00usb_kick_queue,
Loading