brcmsmac: support 4313iPA
authorPiotr Haber <phaber@broadcom.com>
Wed, 28 Nov 2012 20:44:10 +0000 (21:44 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 30 Nov 2012 19:00:22 +0000 (14:00 -0500)
Add support for 4313 iPA variant.
It is a variant of already supported 4313 ePA
and needs some PHY changes to work properly.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Piotr Haber <phaber@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c

index 18d37645e2cde25f2d291a94bd51a3e3675db5be..606b534347bc93984cb9aefb38acd6981f3af8de 100644 (file)
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
        gain0_15 = ((biq1 & 0xf) << 12) |
                   ((tia & 0xf) << 8) |
                   ((lna2 & 0x3) << 6) |
-                  ((lna2 &
-                    0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+                  ((lna2 & 0x3) << 4) |
+                  ((lna1 & 0x3) << 2) |
+                  ((lna1 & 0x3) << 0);
 
        mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
        mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
        }
 
        mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+       mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+       mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
 
 }
 
@@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
        return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
 }
 
+static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
+                                     u16 tia_gain, u16 lna2_gain)
+{
+       u32 i_thresh_l, q_thresh_l;
+       u32 i_thresh_h, q_thresh_h;
+       struct lcnphy_iq_est iq_est_h, iq_est_l;
+
+       wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
+                                              lna2_gain, 0);
+
+       wlc_lcnphy_rx_gain_override_enable(pi, true);
+       wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
+       usleep_range(500, 500);
+       write_radio_reg(pi, RADIO_2064_REG112, 0);
+       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
+               return false;
+
+       wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
+       usleep_range(500, 500);
+       write_radio_reg(pi, RADIO_2064_REG112, 0);
+       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
+               return false;
+
+       i_thresh_l = (iq_est_l.i_pwr << 1);
+       i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
+
+       q_thresh_l = (iq_est_l.q_pwr << 1);
+       q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
+       if ((iq_est_h.i_pwr > i_thresh_l) &&
+           (iq_est_h.i_pwr < i_thresh_h) &&
+           (iq_est_h.q_pwr > q_thresh_l) &&
+           (iq_est_h.q_pwr < q_thresh_h))
+               return true;
+
+       return false;
+}
+
 static bool
 wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                     const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
            RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
            rfoverride3_old, rfoverride3val_old, rfoverride4_old,
            rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
-       int tia_gain;
-       u32 received_power, rx_pwr_threshold;
+       int tia_gain, lna2_gain, biq1_gain;
+       bool set_gain;
        u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
        u16 values_to_save[11];
        s16 *ptr;
@@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                goto cal_done;
        }
 
-       if (module == 1) {
+       WARN_ON(module != 1);
+       tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+       wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
 
-               tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
-               wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+       for (i = 0; i < 11; i++)
+               values_to_save[i] =
+                       read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+       Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+       or_phy_reg(pi, 0x631, 0x0015);
+
+       RFOverride0_old = read_phy_reg(pi, 0x44c);
+       RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+       rfoverride2_old = read_phy_reg(pi, 0x4b0);
+       rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+       rfoverride3_old = read_phy_reg(pi, 0x4f9);
+       rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+       rfoverride4_old = read_phy_reg(pi, 0x938);
+       rfoverride4val_old = read_phy_reg(pi, 0x939);
+       afectrlovr_old = read_phy_reg(pi, 0x43b);
+       afectrlovrval_old = read_phy_reg(pi, 0x43c);
+       old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+       old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
 
-               for (i = 0; i < 11; i++)
-                       values_to_save[i] =
-                               read_radio_reg(pi, rxiq_cal_rf_reg[i]);
-               Core1TxControl_old = read_phy_reg(pi, 0x631);
-
-               or_phy_reg(pi, 0x631, 0x0015);
-
-               RFOverride0_old = read_phy_reg(pi, 0x44c);
-               RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
-               rfoverride2_old = read_phy_reg(pi, 0x4b0);
-               rfoverride2val_old = read_phy_reg(pi, 0x4b1);
-               rfoverride3_old = read_phy_reg(pi, 0x4f9);
-               rfoverride3val_old = read_phy_reg(pi, 0x4fa);
-               rfoverride4_old = read_phy_reg(pi, 0x938);
-               rfoverride4val_old = read_phy_reg(pi, 0x939);
-               afectrlovr_old = read_phy_reg(pi, 0x43b);
-               afectrlovrval_old = read_phy_reg(pi, 0x43c);
-               old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
-               old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
-               tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
-               if (tx_gain_override_old) {
-                       wlc_lcnphy_get_tx_gain(pi, &old_gains);
-                       tx_gain_index_old = pi_lcn->lcnphy_current_index;
-               }
+       tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+       if (tx_gain_override_old) {
+               wlc_lcnphy_get_tx_gain(pi, &old_gains);
+               tx_gain_index_old = pi_lcn->lcnphy_current_index;
+       }
 
-               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
 
-               mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+       mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
 
-               mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+       mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
 
-               write_radio_reg(pi, RADIO_2064_REG116, 0x06);
-               write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
-               write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
-               write_radio_reg(pi, RADIO_2064_REG098, 0x03);
-               write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
-               mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
-               write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
-               write_radio_reg(pi, RADIO_2064_REG114, 0x01);
-               write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
-               write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
-               mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
-               mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
-               mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
-               mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
-               mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
-               mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
-               mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
-
-               mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
-
-               wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
-               write_phy_reg(pi, 0x6da, 0xffff);
-               or_phy_reg(pi, 0x6db, 0x3);
-               wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
-               wlc_lcnphy_rx_gain_override_enable(pi, true);
-
-               tia_gain = 8;
-               rx_pwr_threshold = 950;
-               while (tia_gain > 0) {
-                       tia_gain -= 1;
-                       wlc_lcnphy_set_rx_gain_by_distribution(pi,
-                                                              0, 0, 2, 2,
-                                                              (u16)
-                                                              tia_gain, 1, 0);
-                       udelay(500);
+       write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+       write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+       write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+       write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+       write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+       mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+       write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+       write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+       write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+       write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+       mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+       mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+       mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+       mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+       mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+       mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+       mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
 
-                       received_power =
-                               wlc_lcnphy_measure_digital_power(pi, 2000);
-                       if (received_power < rx_pwr_threshold)
-                               break;
+       mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+       write_phy_reg(pi, 0x6da, 0xffff);
+       or_phy_reg(pi, 0x6db, 0x3);
+
+       wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+       set_gain = false;
+
+       lna2_gain = 3;
+       while ((lna2_gain >= 0) && !set_gain) {
+               tia_gain = 4;
+
+               while ((tia_gain >= 0) && !set_gain) {
+                       biq1_gain = 6;
+
+                       while ((biq1_gain >= 0) && !set_gain) {
+                               set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
+                                                                    (u16)
+                                                                    biq1_gain,
+                                                                    (u16)
+                                                                    tia_gain,
+                                                                    (u16)
+                                                                    lna2_gain);
+                               biq1_gain -= 1;
+                       }
+                       tia_gain -= 1;
                }
-               result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+               lna2_gain -= 1;
+       }
 
-               wlc_lcnphy_stop_tx_tone(pi);
+       if (set_gain)
+               result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
+       else
+               result = false;
 
-               write_phy_reg(pi, 0x631, Core1TxControl_old);
+       wlc_lcnphy_stop_tx_tone(pi);
 
-               write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
-               write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
-               write_phy_reg(pi, 0x4b0, rfoverride2_old);
-               write_phy_reg(pi, 0x4b1, rfoverride2val_old);
-               write_phy_reg(pi, 0x4f9, rfoverride3_old);
-               write_phy_reg(pi, 0x4fa, rfoverride3val_old);
-               write_phy_reg(pi, 0x938, rfoverride4_old);
-               write_phy_reg(pi, 0x939, rfoverride4val_old);
-               write_phy_reg(pi, 0x43b, afectrlovr_old);
-               write_phy_reg(pi, 0x43c, afectrlovrval_old);
-               write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
-               write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+       write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+       write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+       write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+       write_phy_reg(pi, 0x4b0, rfoverride2_old);
+       write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+       write_phy_reg(pi, 0x4f9, rfoverride3_old);
+       write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+       write_phy_reg(pi, 0x938, rfoverride4_old);
+       write_phy_reg(pi, 0x939, rfoverride4val_old);
+       write_phy_reg(pi, 0x43b, afectrlovr_old);
+       write_phy_reg(pi, 0x43c, afectrlovrval_old);
+       write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+       write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
 
-               wlc_lcnphy_clear_trsw_override(pi);
+       wlc_lcnphy_clear_trsw_override(pi);
 
-               mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+       mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
 
-               for (i = 0; i < 11; i++)
-                       write_radio_reg(pi, rxiq_cal_rf_reg[i],
-                                       values_to_save[i]);
+       for (i = 0; i < 11; i++)
+               write_radio_reg(pi, rxiq_cal_rf_reg[i],
+                               values_to_save[i]);
 
-               if (tx_gain_override_old)
-                       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
-               else
-                       wlc_lcnphy_disable_tx_gain_override(pi);
+       if (tx_gain_override_old)
+               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+       else
+               wlc_lcnphy_disable_tx_gain_override(pi);
 
-               wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
-               wlc_lcnphy_rx_gain_override_enable(pi, false);
-       }
+       wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+       wlc_lcnphy_rx_gain_override_enable(pi, false);
 
 cal_done:
        kfree(ptr);
@@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
                write_radio_reg(pi, RADIO_2064_REG038, 3);
                write_radio_reg(pi, RADIO_2064_REG091, 7);
        }
+
+       if (!(pi->sh->boardflags & BFL_FEM)) {
+               u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
+                       0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
+
+               write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
+               write_radio_reg(pi, RADIO_2064_REG091, 0x3);
+               write_radio_reg(pi, RADIO_2064_REG038, 0x3);
+
+               write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
+       }
 }
 
 static int
@@ -1975,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
                } else {
                        mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
                        mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+                       mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
+                       mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
+                       mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
+                       mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
+                       mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+                       mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
+                       mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
+                       mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
+                       mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
+                       mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
                }
        } else {
                mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2061,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
                    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
 
        mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+       mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
 }
 
 static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 {
        struct phytbl_info tab;
        u32 rfseq, ind;
+       u8 tssi_sel;
 
        tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
        tab.tbl_width = 32;
@@ -2088,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
        mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
 
-       wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+       if (pi->sh->boardflags & BFL_FEM) {
+               tssi_sel = 0x1;
+               wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+       } else {
+               tssi_sel = 0xe;
+               wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
+       }
        mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
 
        mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2124,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
        mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
 
        if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
-               mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+               mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
                mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
        } else {
+               mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
                mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
                mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
        }
@@ -2173,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
        mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
 
+       mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
+       mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+       mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+
        wlc_lcnphy_pwrctrl_rssiparams(pi);
 }
 
@@ -2791,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
                read_radio_reg(pi, RADIO_2064_REG007) & 1;
        u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
        u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+       u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
+
        idleTssi = read_phy_reg(pi, 0x4ab);
        suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
                         MCTL_EN_MAC));
@@ -2808,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
        mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
        mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
        wlc_lcnphy_tssi_setup(pi);
+
+       mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
+       mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
+
+       wlc_lcnphy_set_bbmult(pi, 0x0);
+
        wlc_phy_do_dummy_tx(pi, true, OFF);
        idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
                    >> 0);
@@ -2829,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
 
        mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
 
+       wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
        wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
        wlc_lcnphy_set_tx_gain(pi, &old_gains);
        wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3042,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
                        wlc_lcnphy_write_table(pi, &tab);
                        tab.tbl_offset++;
                }
+               mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
+               mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
+               mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
+               mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
+               mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
 
                mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
 
@@ -3843,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
        target_gains.pad_gain = 21;
        target_gains.dac_gain = 0;
        wlc_lcnphy_set_tx_gain(pi, &target_gains);
-       wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
 
        if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
 
@@ -3854,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
                                        lcnphy_recal ? LCNPHY_CAL_RECAL :
                                        LCNPHY_CAL_FULL), false);
        } else {
+               wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
                wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
        }
 
@@ -4278,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
        if (CHSPEC_IS5G(pi->radio_chanspec))
                pa_gain = 0x70;
        else
-               pa_gain = 0x70;
+               pa_gain = 0x60;
 
        if (pi->sh->boardflags & BFL_FEM)
                pa_gain = 0x10;
+
        tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
        tab.tbl_width = 32;
        tab.tbl_len = 1;
        tab.tbl_ptr = &val;
 
        for (j = 0; j < 128; j++) {
-               gm_gain = gain_table[j].gm;
+               if (pi->sh->boardflags & BFL_FEM)
+                       gm_gain = gain_table[j].gm;
+               else
+                       gm_gain = 15;
+
                val = (((u32) pa_gain << 24) |
                       (gain_table[j].pad << 16) |
                       (gain_table[j].pga << 8) | gm_gain);
@@ -4499,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
 
        write_phy_reg(pi, 0x4ea, 0x4688);
 
-       mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+       if (pi->sh->boardflags & BFL_FEM)
+               mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+       else
+               mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
 
        mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
 
@@ -4510,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
        wlc_lcnphy_rcal(pi);
 
        wlc_lcnphy_rc_cal(pi);
+
+       if (!(pi->sh->boardflags & BFL_FEM)) {
+               write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
+               write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+               write_radio_reg(pi, RADIO_2064_REG039, 0xe);
+       }
+
 }
 
 static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4539,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
                wlc_lcnphy_write_table(pi, &tab);
        }
 
-       tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
-       tab.tbl_width = 16;
-       tab.tbl_ptr = &val;
-       tab.tbl_len = 1;
-
-       val = 114;
-       tab.tbl_offset = 0;
-       wlc_lcnphy_write_table(pi, &tab);
+       if (!(pi->sh->boardflags & BFL_FEM)) {
+               tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+               tab.tbl_width = 16;
+               tab.tbl_ptr = &val;
+               tab.tbl_len = 1;
 
-       val = 130;
-       tab.tbl_offset = 1;
-       wlc_lcnphy_write_table(pi, &tab);
+               val = 150;
+               tab.tbl_offset = 0;
+               wlc_lcnphy_write_table(pi, &tab);
 
-       val = 6;
-       tab.tbl_offset = 8;
-       wlc_lcnphy_write_table(pi, &tab);
+               val = 220;
+               tab.tbl_offset = 1;
+               wlc_lcnphy_write_table(pi, &tab);
+       }
 
        if (CHSPEC_IS2G(pi->radio_chanspec)) {
                if (pi->sh->boardflags & BFL_FEM)
@@ -4946,6 +5055,7 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
                wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
 
        mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+       wlc_lcnphy_tssi_setup(pi);
 }
 
 void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -4984,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
        if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
                return false;
 
-       if ((pi->sh->boardflags & BFL_FEM) &&
-           (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+       if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
                if (pi_lcn->lcnphy_tempsense_option == 3) {
                        pi->hwpwrctrl = true;
                        pi->hwpwrctrl_capable = true;
index 622c01ca72c5d24e8bfc55c3b84ad61633c4bb92..b7e95acc2084033dd5c27de24b80bebd78f8dfbe 100644 (file)
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
 };
 
 static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
-       0x000a,
        0x0009,
-       0x0006,
-       0x0005,
        0x000a,
-       0x0009,
-       0x0006,
        0x0005,
-       0x000a,
-       0x0009,
        0x0006,
-       0x0005,
-       0x000a,
        0x0009,
-       0x0006,
-       0x0005,
        0x000a,
-       0x0009,
-       0x0006,
        0x0005,
-       0x000a,
-       0x0009,
        0x0006,
-       0x0005,
-       0x000a,
        0x0009,
-       0x0006,
-       0x0005,
        0x000a,
-       0x0009,
-       0x0006,
        0x0005,
-       0x000a,
-       0x0009,
        0x0006,
-       0x0005,
-       0x000a,
        0x0009,
-       0x0006,
-       0x0005,
        0x000a,
-       0x0009,
-       0x0006,
        0x0005,
-       0x000a,
-       0x0009,
        0x0006,
-       0x0005,
+       0x0009,
        0x000a,
+       0x0005,
+       0x0006,
        0x0009,
+       0x000a,
+       0x0005,
        0x0006,
+       0x0009,
+       0x000a,
        0x0005,
+       0x0006,
+       0x0009,
        0x000a,
+       0x0005,
+       0x0006,
        0x0009,
+       0x000a,
+       0x0005,
        0x0006,
+       0x0009,
+       0x000a,
        0x0005,
+       0x0006,
+       0x0009,
        0x000a,
+       0x0005,
+       0x0006,
        0x0009,
+       0x000a,
+       0x0005,
        0x0006,
+       0x0009,
+       0x000a,
        0x0005,
+       0x0006,
+       0x0009,
        0x000a,
+       0x0005,
+       0x0006,
        0x0009,
+       0x000a,
+       0x0005,
        0x0006,
+       0x0009,
+       0x000a,
        0x0005,
+       0x0006,
 };
 
 static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {