ath9k: Initialize AGC calibration properly
authorSujith <Sujith.Manoharan@atheros.com>
Thu, 12 Feb 2009 04:36:49 +0000 (10:06 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 27 Feb 2009 19:51:44 +0000 (14:51 -0500)
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath9k/calib.c
drivers/net/wireless/ath9k/phy.h

index 1fc3a08e85c64b14d16c9c0dc80e06a36dd819c0..a7ce8c5d48f5d4225b389fff8838fe5c03cd1c61 100644 (file)
@@ -851,6 +851,30 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 bool ath9k_hw_init_cal(struct ath_hw *ah,
                       struct ath9k_channel *chan)
 {
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+
+               /* Kick off the cal */
+               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                         REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                         AR_PHY_AGC_CONTROL_CAL);
+
+               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+                                  AR_PHY_AGC_CONTROL_CAL, 0)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "offset calibration failed to complete in 1ms; "
+                               "noisy environment?\n");
+                       return false;
+               }
+
+               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       }
+
+       /* Calibrate the AGC */
        REG_WRITE(ah, AR_PHY_AGC_CONTROL,
                  REG_READ(ah, AR_PHY_AGC_CONTROL) |
                  AR_PHY_AGC_CONTROL_CAL);
@@ -862,9 +886,16 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
                return false;
        }
 
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+       }
+
+       /* Do PA Calibration */
        if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
                ath9k_hw_9285_pa_cal(ah);
 
+       /* Do NF Calibration */
        REG_WRITE(ah, AR_PHY_AGC_CONTROL,
                  REG_READ(ah, AR_PHY_AGC_CONTROL) |
                  AR_PHY_AGC_CONTROL_NF);
index 837a598a7ae5196f28efaa32c9a1122875a181ec..4758c37e4b882f3be743bd03e0d9a27367853ad3 100644 (file)
@@ -485,6 +485,10 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
 #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
 
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+
 #define AR_PHY_POWER_TX_RATE5   0xA38C
 #define AR_PHY_POWER_TX_RATE6   0xA390