b43: N-PHY: complete generic support for 0x2057 radio
authorRafał Miłecki <zajec5@gmail.com>
Tue, 1 Jul 2014 14:19:08 +0000 (16:19 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 1 Jul 2014 18:29:39 +0000 (14:29 -0400)
It doesn't include any device (radio revision) specific code yet, so it
isn't really usable. As the commit says, it's just some generic code.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/radio_2057.c
drivers/net/wireless/b43/radio_2057.h

index 8369a08..0a6f04b 100644 (file)
@@ -590,6 +590,100 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
  * Radio 0x2057
  **************************************************/
 
+static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
+                                         const struct b43_nphy_chantabent_rev7 *e_r7,
+                                         const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
+{
+       if (e_r7_2g) {
+               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
+               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
+               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
+               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
+               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
+               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
+               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
+               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
+               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
+               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
+               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
+               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
+               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
+               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
+               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
+
+       } else {
+               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
+               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
+               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
+               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
+               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
+               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
+               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
+               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
+               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
+               b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
+               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
+               b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
+               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
+               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
+               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
+               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
+               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
+               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
+               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
+               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
+               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
+               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
+               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
+               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
+               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
+               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
+       }
+}
+
+static void b43_radio_2057_setup(struct b43_wldev *dev,
+                                const struct b43_nphy_chantabent_rev7 *tabent_r7,
+                                const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
+
+       switch (phy->radio_rev) {
+       case 0 ... 4:
+       case 6:
+               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
+                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
+               } else {
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
+                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
+                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
+               }
+               break;
+       /* TODO */
+       }
+
+       /* TODO */
+
+       usleep_range(50, 100);
+
+       /* VCO calibration */
+       b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
+       b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
+       b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
+       b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
+       usleep_range(300, 600);
+}
+
 /* Calibrate resistors in LPF of PLL?
  * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
  */
@@ -5535,10 +5629,17 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
 
        const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
        const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
+       const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
+       const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
 
        u8 tmp;
 
-       if (dev->phy.rev >= 3) {
+       if (phy->rev >= 7) {
+               r2057_get_chantabent_rev7(dev, channel->center_freq,
+                                         &tabent_r7, &tabent_r7_2g);
+               if (!tabent_r7 && !tabent_r7_2g)
+                       return -ESRCH;
+       } else if (phy->rev >= 3) {
                tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
                                                        channel->center_freq);
                if (!tabent_r3)
@@ -5560,14 +5661,29 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
                ; /* TODO: BMAC BW Set (channel_type) */
 #endif
 
-       if (channel_type == NL80211_CHAN_HT40PLUS)
-               b43_phy_set(dev, B43_NPHY_RXCTL,
-                               B43_NPHY_RXCTL_BSELU20);
-       else if (channel_type == NL80211_CHAN_HT40MINUS)
-               b43_phy_mask(dev, B43_NPHY_RXCTL,
-                               ~B43_NPHY_RXCTL_BSELU20);
+       if (channel_type == NL80211_CHAN_HT40PLUS) {
+               b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
+               if (phy->rev >= 7)
+                       b43_phy_set(dev, 0x310, 0x8000);
+       } else if (channel_type == NL80211_CHAN_HT40MINUS) {
+               b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
+               if (phy->rev >= 7)
+                       b43_phy_mask(dev, 0x310, (u16)~0x8000);
+       }
 
-       if (dev->phy.rev >= 3) {
+       if (phy->rev >= 7) {
+               const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
+                       &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
+
+               if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
+                       tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
+                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
+                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
+               }
+
+               b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
+               b43_nphy_channel_setup(dev, phy_regs, channel);
+       } else if (phy->rev >= 3) {
                tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
                b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
                b43_radio_2056_setup(dev, tabent_r3);
Simple merge
Simple merge