ath9k_hw: add a private callback for PLL control computation
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Thu, 15 Apr 2010 21:38:17 +0000 (17:38 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Apr 2010 19:43:19 +0000 (15:43 -0400)
The PLL control computation used to program the AR_RTC_PLL_CONTROL
register varies between our harware so just add a private callback for it.
AR9003 will use its own callback.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/ar9002_phy.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h

index 982b0d3877f8a0b4a77ee6e8e1b129ea25d34ed4..9685f4c6fc99acc7ac2c8f15456b39072fb9c51c 100644 (file)
@@ -967,6 +967,54 @@ static void ar5008_set_diversity(struct ath_hw *ah, bool value)
        REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
 }
 
+static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       if (chan && IS_CHAN_5GHZ(chan))
+               return 0x1450;
+       return 0x1458;
+}
+
+static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan))
+               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+       else
+               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+
+       return pll;
+}
+
+static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan))
+               pll |= SM(0xa, AR_RTC_PLL_DIV);
+       else
+               pll |= SM(0xb, AR_RTC_PLL_DIV);
+
+       return pll;
+}
+
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -988,4 +1036,11 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
        priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
        priv_ops->restore_chainmask = ar5008_restore_chainmask;
        priv_ops->set_diversity = ar5008_set_diversity;
+
+       if (AR_SREV_9100(ah))
+               priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
+       else if (AR_SREV_9160_10_OR_LATER(ah))
+               priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
+       else
+               priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
 }
index 29b50ca0a0ccb2c0213d68a60390a482d4a88a91..87541a8440c0b9256c189cee368c768a8222437a 100644 (file)
@@ -437,6 +437,36 @@ static void ar9002_olc_init(struct ath_hw *ah)
        }
 }
 
+static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan)) {
+               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+
+
+               if (AR_SREV_9280_20(ah)) {
+                       if (((chan->channel % 20) == 0)
+                           || ((chan->channel % 10) == 0))
+                               pll = 0x2850;
+                       else
+                               pll = 0x142c;
+               }
+       } else {
+               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+       }
+
+       return pll;
+}
+
 void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -447,4 +477,5 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
        priv_ops->rf_set_freq = ar9002_hw_set_channel;
        priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
        priv_ops->olc_init = ar9002_olc_init;
+       priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
 }
index ea831f575a9d60973da7b2c9e0501212fd4b7595..349cffdbdea6daac1a884c918361ff193fd3ac83 100644 (file)
@@ -66,6 +66,12 @@ static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
        return priv_ops->macversion_supported(ah->hw_version.macVersion);
 }
 
+static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
+                                       struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
+}
+
 /********************/
 /* Helper Functions */
 /********************/
@@ -1023,64 +1029,8 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
 static void ath9k_hw_init_pll(struct ath_hw *ah,
                              struct ath9k_channel *chan)
 {
-       u32 pll;
-
-       if (AR_SREV_9100(ah)) {
-               if (chan && IS_CHAN_5GHZ(chan))
-                       pll = 0x1450;
-               else
-                       pll = 0x1458;
-       } else {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan)) {
-                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-
-
-                               if (AR_SREV_9280_20(ah)) {
-                                       if (((chan->channel % 20) == 0)
-                                           || ((chan->channel % 10) == 0))
-                                               pll = 0x2850;
-                                       else
-                                               pll = 0x142c;
-                               }
-                       } else {
-                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-                       }
-
-               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
-                       else
-                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
-               } else {
-                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+       u32 pll = ath9k_hw_compute_pll_control(ah, chan);
 
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0xa, AR_RTC_PLL_DIV);
-                       else
-                               pll |= SM(0xb, AR_RTC_PLL_DIV);
-               }
-       }
        REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
        /* Switch the core clock for ar9271 to 117Mhz */
index d740e9cc721ca67927def91bd6f3259246cd1dff..79b938b930559f2ec66cbd22781223a3fac574e5 100644 (file)
@@ -454,6 +454,8 @@ struct ath_gen_timer_table {
  * @rf_alloc_ext_banks:
  * @rf_free_ext_banks:
  * @set_rf_regs:
+ * @compute_pll_control: compute the PLL control value to use for
+ *     AR_RTC_PLL_CONTROL for a given channel
  */
 struct ath_hw_private_ops {
        void (*init_cal_settings)(struct ath_hw *ah);
@@ -483,6 +485,8 @@ struct ath_hw_private_ops {
        void (*enable_rfkill)(struct ath_hw *ah);
        void (*restore_chainmask)(struct ath_hw *ah);
        void (*set_diversity)(struct ath_hw *ah, bool value);
+       u32 (*compute_pll_control)(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
 };
 
 /**