aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-09-16 06:34:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-19 16:10:13 -0400
commit1b0a69c1ff445c265b173cc82c3f41a01dd90bec (patch)
tree4cd524ec9a44caf2c5e47c15e2be850a8c04a2bd
parentac78a52f49e3645c49e2c13a239b570d2e590bee (diff)
b43: LCN-PHY: init TX power control
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/phy_lcn.c92
-rw-r--r--drivers/net/wireless/b43/phy_lcn.h2
2 files changed, 93 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index 895164783c3b..8810bc99d28c 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -37,6 +37,13 @@
37#include "tables_phy_lcn.h" 37#include "tables_phy_lcn.h"
38#include "main.h" 38#include "main.h"
39 39
40struct lcn_tx_gains {
41 u16 gm_gain;
42 u16 pga_gain;
43 u16 pad_gain;
44 u16 dac_gain;
45};
46
40struct lcn_tx_iir_filter { 47struct lcn_tx_iir_filter {
41 u8 type; 48 u8 type;
42 u16 values[16]; 49 u16 values[16];
@@ -198,6 +205,29 @@ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev)
198 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1); 205 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1);
199} 206}
200 207
208/* wlc_lcnphy_get_pa_gain */
209static u16 b43_phy_lcn_get_pa_gain(struct b43_wldev *dev)
210{
211 return (b43_phy_read(dev, 0x4fb) & 0x7f00) >> 8;
212}
213
214/* wlc_lcnphy_set_dac_gain */
215static void b43_phy_lcn_set_dac_gain(struct b43_wldev *dev, u16 dac_gain)
216{
217 u16 dac_ctrl;
218
219 dac_ctrl = b43_phy_read(dev, 0x439);
220 dac_ctrl = dac_ctrl & 0xc7f;
221 dac_ctrl = dac_ctrl | (dac_gain << 7);
222 b43_phy_maskset(dev, 0x439, ~0xfff, dac_ctrl);
223}
224
225/* wlc_lcnphy_set_bbmult */
226static void b43_phy_lcn_set_bbmult(struct b43_wldev *dev, u8 m0)
227{
228 b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x57), m0 << 8);
229}
230
201/* wlc_lcnphy_clear_tx_power_offsets */ 231/* wlc_lcnphy_clear_tx_power_offsets */
202static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev) 232static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev)
203{ 233{
@@ -400,6 +430,65 @@ static bool b43_phy_lcn_load_tx_iir_ofdm_filter(struct b43_wldev *dev,
400 return false; 430 return false;
401} 431}
402 432
433/* wlc_lcnphy_set_tx_gain_override */
434static void b43_phy_lcn_set_tx_gain_override(struct b43_wldev *dev, bool enable)
435{
436 b43_phy_maskset(dev, 0x4b0, ~(0x1 << 7), enable << 7);
437 b43_phy_maskset(dev, 0x4b0, ~(0x1 << 14), enable << 14);
438 b43_phy_maskset(dev, 0x43b, ~(0x1 << 6), enable << 6);
439}
440
441/* wlc_lcnphy_set_tx_gain */
442static void b43_phy_lcn_set_tx_gain(struct b43_wldev *dev,
443 struct lcn_tx_gains *target_gains)
444{
445 u16 pa_gain = b43_phy_lcn_get_pa_gain(dev);
446
447 b43_phy_write(dev, 0x4b5,
448 (target_gains->gm_gain | (target_gains->pga_gain << 8)));
449 b43_phy_maskset(dev, 0x4fb, ~0x7fff,
450 (target_gains->pad_gain | (pa_gain << 8)));
451 b43_phy_write(dev, 0x4fc,
452 (target_gains->gm_gain | (target_gains->pga_gain << 8)));
453 b43_phy_maskset(dev, 0x4fd, ~0x7fff,
454 (target_gains->pad_gain | (pa_gain << 8)));
455
456 b43_phy_lcn_set_dac_gain(dev, target_gains->dac_gain);
457 b43_phy_lcn_set_tx_gain_override(dev, true);
458}
459
460/* wlc_lcnphy_tx_pwr_ctrl_init */
461static void b43_phy_lcn_tx_pwr_ctl_init(struct b43_wldev *dev)
462{
463 struct lcn_tx_gains tx_gains;
464 u8 bbmult;
465
466 b43_mac_suspend(dev);
467
468 if (!dev->phy.lcn->hw_pwr_ctl_capable) {
469 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
470 tx_gains.gm_gain = 4;
471 tx_gains.pga_gain = 12;
472 tx_gains.pad_gain = 12;
473 tx_gains.dac_gain = 0;
474 bbmult = 150;
475 } else {
476 tx_gains.gm_gain = 7;
477 tx_gains.pga_gain = 15;
478 tx_gains.pad_gain = 14;
479 tx_gains.dac_gain = 0;
480 bbmult = 150;
481 }
482 b43_phy_lcn_set_tx_gain(dev, &tx_gains);
483 b43_phy_lcn_set_bbmult(dev, bbmult);
484 b43_phy_lcn_sense_setup(dev); /* TODO: TEMPSENSE as arg */
485 } else {
486 b43err(dev->wl, "TX power control not supported for this HW\n");
487 }
488
489 b43_mac_enable(dev);
490}
491
403/* wlc_lcnphy_txrx_spur_avoidance_mode */ 492/* wlc_lcnphy_txrx_spur_avoidance_mode */
404static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev, 493static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev,
405 bool enable) 494 bool enable)
@@ -562,7 +651,8 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev)
562 else 651 else
563 B43_WARN_ON(1); 652 B43_WARN_ON(1);
564 653
565 b43_phy_lcn_sense_setup(dev); 654 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
655 b43_phy_lcn_tx_pwr_ctl_init(dev);
566 656
567 b43_switch_channel(dev, dev->phy.channel); 657 b43_switch_channel(dev, dev->phy.channel);
568 658
diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h
index 25f06e8d4531..2a386d07fc23 100644
--- a/drivers/net/wireless/b43/phy_lcn.h
+++ b/drivers/net/wireless/b43/phy_lcn.h
@@ -19,6 +19,8 @@
19 19
20 20
21struct b43_phy_lcn { 21struct b43_phy_lcn {
22 bool hw_pwr_ctl;
23 bool hw_pwr_ctl_capable;
22}; 24};
23 25
24 26