aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGábor Stefanik <netrolller.3d@gmail.com>2009-08-11 15:53:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:14:03 -0400
commitd4de9532fd0b50d486259ace17650a58bbb751c2 (patch)
treef2a10d510be7edaac7938237e40e3fe85740a422 /drivers
parent84ec167d327b42414285f22eb037a5bdee486ded (diff)
b43: Implement RC calibration for rev.2+ LP PHYs
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/b43/phy_lp.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 2bec791041fe..296e209a8c10 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -605,6 +605,90 @@ static void lpphy_radio_init(struct b43_wldev *dev)
605 } 605 }
606} 606}
607 607
608static void lpphy_set_rc_cap(struct b43_wldev *dev)
609{
610 u8 rc_cap = dev->phy.lp->rc_cap;
611
612 b43_radio_write(dev, B2062_N_RXBB_CALIB2, max_t(u8, rc_cap-4, 0x80));
613 b43_radio_write(dev, B2062_N_TX_CTL_A, ((rc_cap & 0x1F) >> 1) | 0x80);
614 b43_radio_write(dev, B2062_S_RXG_CNT16, ((rc_cap & 0x1F) >> 2) | 0x80);
615}
616
617static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
618{
619 //TODO and SPEC FIXME
620}
621
622static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
623{
624 struct ssb_bus *bus = dev->dev->bus;
625 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
626 u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
627 int i;
628
629 b43_radio_write(dev, B2063_RX_BB_SP8, 0x0);
630 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
631 b43_radio_mask(dev, B2063_PLL_SP1, 0xF7);
632 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7C);
633 b43_radio_write(dev, B2063_RC_CALIB_CTL2, 0x15);
634 b43_radio_write(dev, B2063_RC_CALIB_CTL3, 0x70);
635 b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0x52);
636 b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x1);
637 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7D);
638
639 for (i = 0; i < 10000; i++) {
640 if (b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2)
641 break;
642 msleep(1);
643 }
644
645 if (!(b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2))
646 b43_radio_write(dev, B2063_RX_BB_SP8, tmp);
647
648 tmp = b43_radio_read(dev, B2063_TX_BB_SP3) & 0xFF;
649
650 b43_radio_write(dev, B2063_TX_BB_SP3, 0x0);
651 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
652 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7C);
653 b43_radio_write(dev, B2063_RC_CALIB_CTL2, 0x55);
654 b43_radio_write(dev, B2063_RC_CALIB_CTL3, 0x76);
655
656 if (crystal_freq == 24000000) {
657 b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0xFC);
658 b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x0);
659 } else {
660 b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0x13);
661 b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x1);
662 }
663
664 b43_radio_write(dev, B2063_PA_SP7, 0x7D);
665
666 for (i = 0; i < 10000; i++) {
667 if (b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2)
668 break;
669 msleep(1);
670 }
671
672 if (!(b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2))
673 b43_radio_write(dev, B2063_TX_BB_SP3, tmp);
674
675 b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
676}
677
678static void lpphy_calibrate_rc(struct b43_wldev *dev)
679{
680 struct b43_phy_lp *lpphy = dev->phy.lp;
681
682 if (dev->phy.rev >= 2) {
683 lpphy_rev2plus_rc_calib(dev);
684 } else if (!lpphy->rc_cap) {
685 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
686 lpphy_rev0_1_rc_calib(dev);
687 } else {
688 lpphy_set_rc_cap(dev);
689 }
690}
691
608/* Read the TX power control mode from hardware. */ 692/* Read the TX power control mode from hardware. */
609static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev) 693static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
610{ 694{
@@ -780,7 +864,7 @@ static int b43_lpphy_op_init(struct b43_wldev *dev)
780 lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? 864 lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs?
781 lpphy_baseband_init(dev); 865 lpphy_baseband_init(dev);
782 lpphy_radio_init(dev); 866 lpphy_radio_init(dev);
783 //TODO calibrate RC 867 lpphy_calibrate_rc(dev);
784 //TODO set channel 868 //TODO set channel
785 lpphy_tx_pctl_init(dev); 869 lpphy_tx_pctl_init(dev);
786 lpphy_calibration(dev); 870 lpphy_calibration(dev);