+@@ -4410,6 +4744,128 @@ static void rt2800_config_txpower_rt3593
+ (unsigned long) regs[i]);
+ }
+
++static void rt2800_config_txpower_mt7620(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_channel *chan,
++ int power_level)
++{
++ u32 reg, pwreg;
++ u16 eeprom;
++ u32 data, gdata;
++ u8 t, i;
++ enum nl80211_band band = chan->band;
++ int delta;
++
++ /* Warn user if bw_comp is set in EEPROM */
++ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
++
++ if (delta)
++ rt2x00_warn(rt2x00dev, "ignoring EEPROM HT40 power delta: %d\n",
++ delta);
++
++ /* populate TX_PWR_CFG_0 up to TX_PWR_CFG_4 from EEPROM for HT40, limit
++ * value to 0x3f and replace 0x20 by 0x21 as this is what the vendor
++ * driver does as well, though it looks kinda wrong.
++ * Maybe some misunderstanding of what a signed 8-bit value is? Maybe
++ * the hardware has a problem handling 0x20, and as the code initially
++ * used a fixed offset between HT20 and HT40 rates they had to work-
++ * around that issue and most likely just forgot about it later on.
++ * Maybe we should use rt2800_get_txpower_bw_comp() here as well,
++ * however, the corresponding EEPROM value is not respected by the
++ * vendor driver, so maybe this is rather being taken care of the
++ * TXALC and the driver doesn't need to handle it...?
++ * Though this is all very awkward, just do as they did, as that's what
++ * board vendors expected when they populated the EEPROM...
++ */
++ for (i = 0; i < 5; i++) {
++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++ i * 2, &eeprom);
++
++ data = eeprom;
++
++ t = eeprom & 0x3f;
++ if (t == 32)
++ t++;
++
++ gdata = t;
++
++ t = (eeprom & 0x3f00) >> 8;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 8);
++
++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++ (i * 2) + 1, &eeprom);
++
++ t = eeprom & 0x3f;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 16);
++
++ t = (eeprom & 0x3f00) >> 8;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 24);
++ data |= (eeprom << 16);
++
++ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) {
++ /* HT20 */
++ if (data != 0xffffffff)
++ rt2800_register_write(rt2x00dev,
++ TX_PWR_CFG_0 + (i * 4),
++ data);
++ } else {
++ /* HT40 */
++ if (gdata != 0xffffffff)
++ rt2800_register_write(rt2x00dev,
++ TX_PWR_CFG_0 + (i * 4),
++ gdata);
++ }
++ }
++
++ /* Aparently Ralink ran out of space in the BYRATE calibration section
++ * of the EERPOM which is copied to the corresponding TX_PWR_CFG_x
++ * registers. As recent 2T chips use 8-bit instead of 4-bit values for
++ * power-offsets more space would be needed. Ralink decided to rather
++ * keep the EEPROM layout untouched and rather have some shared values
++ * covering multiple bitrates.
++ * Populate the registers not covered by the EEPROM in the same way the
++ * vendor driver does.
++ */
++
++ /* For OFDM 54MBS use value from OFDM 48MBS */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_1B_48MBS);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_54MBS, t);
++
++ /* For MCS 7 use value from MCS 6 */
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_2B_MCS6_MCS7);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_MCS7, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, pwreg);
++
++ /* For MCS 15 use value from MCS 14 */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_3B_MCS14);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_8B_MCS15, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, pwreg);
++
++ /* For STBC MCS 7 use value from STBC MCS 6 */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_4B_STBC_MCS6);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg);
++
++ rt2800_config_alc(rt2x00dev, chan, power_level);
++
++ /* TODO: temperature compensation code! */
++}
++
+ /*
+ * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
+ * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
+@@ -4607,6 +5063,8 @@ static void rt2800_config_txpower(struct
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
++ else if (rt2x00_rf(rt2x00dev, RF7620))
++ rt2800_config_txpower_mt7620(rt2x00dev, chan, power_level);
+ else
+ rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
+ }
+@@ -4622,6 +5080,7 @@ void rt2800_vco_calibration(struct rt2x0
+ {
+ u32 tx_pin;
+ u8 rfcsr;
++ unsigned long min_sleep = 0;
+
+ /*
+ * A voltage-controlled oscillator(VCO) is an electronic oscillator
+@@ -4661,6 +5120,15 @@ void rt2800_vco_calibration(struct rt2x0
+ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);