Merge "Enable FM SSR support"
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 0b7a366..1986917 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -2123,7 +2123,7 @@
             Log.d(LOGTAG, "fmOn: RdsStd      :"+ config.getRdsStd());
             Log.d(LOGTAG, "fmOn: LowerLimit  :"+ config.getLowerLimit());
             Log.d(LOGTAG, "fmOn: UpperLimit  :"+ config.getUpperLimit());
-            bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration());
+            bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this);
             if (isSpeakerEnabled()) {
                 setAudioPath(false);
             } else {
@@ -2281,7 +2281,7 @@
       // This will disable the FM radio device
       if (mReceiver != null)
       {
-         bStatus = mReceiver.disable();
+         bStatus = mReceiver.disable(this);
          mReceiver = null;
       }
       fmOperationsOff();
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 1c506c4..091b1b3 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -276,6 +276,7 @@
 
     private Thread mRecordUpdateHandlerThread = null;
     private Thread mRunTestThread = null;
+    private Thread mTuneCompleteThread = null;
     boolean mRecording = false;
 
 
@@ -465,12 +466,10 @@
                         if (lastCmdSent == CMD_STNPARAM_SINR)
                             nSINR = msg.arg1;
                     }
-                    if (mRunTestThread !=  null) {
-                        synchronized (obj) {
-                            obj.notify();
-                        }
-                    }
-                    lastCmdSent = 0;
+					synchronized (obj) {
+						obj.notify();
+					}
+					lastCmdSent = 0;
                     break;
                 case GET_STATION_DBG_PARAM:
                     status = msg.arg2;
@@ -484,12 +483,10 @@
                         if  (lastCmdSent == CMD_STNDBGPARAM_INFDETOUT)
                             nIntDet = msg.arg1;
                     }
-                    if (mRunTestThread !=  null) {
-                        synchronized (obj) {
-                            mRunTestThread.notify();
-                        }
-                    }
-                    break;
+					synchronized (obj) {
+						obj.notify();
+					}
+					break;
                 default:
                     Log.e(LOGTAG, "mCallbackHandler:Default");
                     break;
@@ -535,9 +532,6 @@
         if(mUIUpdateHandlerHandler != null) {
            mUIUpdateHandlerHandler.removeCallbacksAndMessages(null);
         }
-        if(mHandler != null) {
-           mHandler.removeCallbacksAndMessages(null);
-        }
         unRegisterBroadcastReceiver(mBandSweepDelayExprdListener);
         unRegisterBroadcastReceiver(mBandSweepDwellExprdListener);
         if(null != mFileCursor ) {
@@ -563,6 +557,28 @@
         }
     };
 
+     private Runnable mTuneComplete = new Runnable(){
+         public void run(){
+             if((null != mMultiUpdateThread) &&(null != mSync))
+             {
+                 synchronized(mSync){
+                     mSync.notify();
+                 }
+             }
+            if((mTestSelected == SEARCH_TEST) && (mService != null)) {
+                /* On every Tune Complete generate the result for the current
+                Frequency*/
+                Message updateUI = new Message();
+                updateUI.what = STATUS_UPDATE;
+                int freq = FmSharedPreferences.getTunedFrequency();
+                updateUI.obj = (Object)GetFMStatsForFreq(freq);
+                if (updateUI.obj == null)
+                    updateUI.what = STATUS_DONE;
+                mUIUpdateHandlerHandler.sendMessage(updateUI);
+            }
+         }
+     };
+
     private View.OnClickListener mOnRunListener = new View.OnClickListener() {
         public void onClick(View v) {
             Log.d(LOGTAG, "mTestRunning=" + mTestRunning);
@@ -2880,12 +2896,12 @@
     private boolean isCherokeeChip() {
         Log.d(LOGTAG, "isCherokeeChip");
 
-		String chip = SystemProperties.get("qcom.bluetooth.soc");
-		if (chip.equals("cherokee"))
-			return true;
-		else
-			return false;
-	}
+        String chip = SystemProperties.get("qcom.bluetooth.soc");
+        if (chip.equals("cherokee"))
+            return true;
+        else
+            return false;
+    }
 
     private boolean isRomeChip() {
         String chip = "";
@@ -3515,8 +3531,21 @@
           public void onTuneStatusChanged()
           {
              Log.d(LOGTAG, "mServiceCallbacks.onTuneStatusChanged :" + mTestRunning);
-             if (mTestRunning)
-                 mHandler.post(mTuneComplete);
+             if (mTestRunning) {
+                 if ((mTuneCompleteThread == null) || (mTuneCompleteThread.getState() == Thread.State.TERMINATED)) {
+                     mTuneCompleteThread = new Thread(mTuneComplete,
+                                                "mTuneCompleteThread");
+                 } else {
+                     Log.e(LOGTAG, "mTuneCompleteThread is already running");
+                     return;
+                 }
+                 if (mTuneCompleteThread != null) {
+                     mTuneCompleteThread.start();
+                 } else {
+                     Log.e(LOGTAG, "mTuneCompleteThread: new thread create failed");
+                     return;
+                 }
+             }
           }
 
           public void onProgramServiceChanged()
@@ -3737,30 +3766,6 @@
               mCallbackHandler.obtainMessage(GET_STATION_DBG_PARAM, val, status).sendToTarget();
           }
       };
-      /* Radio Vars */
-     private Handler mHandler = new Handler();
-
-     private Runnable mTuneComplete = new Runnable(){
-         public void run(){
-             if((null != mMultiUpdateThread) &&(null != mSync))
-             {
-                 synchronized(mSync){
-                     mSync.notify();
-                 }
-             }
-            if((mTestSelected == SEARCH_TEST) && (mService != null)) {
-                /* On every Tune Complete generate the result for the current
-                Frequency*/
-                Message updateUI = new Message();
-                updateUI.what = STATUS_UPDATE;
-                int freq = FmSharedPreferences.getTunedFrequency();
-                updateUI.obj = (Object)GetFMStatsForFreq(freq);
-                if (updateUI.obj == null)
-                    updateUI.what = STATUS_DONE;
-                mUIUpdateHandlerHandler.sendMessage(updateUI);
-            }
-         }
-     };
 
      private void stopCurTest() {
          if (mRunTestThread != null) {
@@ -3779,7 +3784,8 @@
                       mMultiUpdateThread.interrupt();
                   break;
              case SEARCH_TEST:
-                  mHandler.removeCallbacks(mTuneComplete);
+                  if (mTuneCompleteThread != null)
+                      mTuneCompleteThread.interrupt();
                   if (mService != null) {
                       try {
                            Message updateStop = new Message();
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
index 021e468..e3cf3d6 100644
--- a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
@@ -530,7 +530,7 @@
       /* Disable Receiver */
       if (mReceiver != null)
       {
-         bStatus = mReceiver.disable();
+         bStatus = mReceiver.disable(this);
          mReceiver = null;
       }
       RText = " ";
@@ -585,7 +585,7 @@
       /* Disable Receiver */
       if (mReceiver != null)
       {
-         bStatus = mReceiver.disable();
+         bStatus = mReceiver.disable(this);
          mReceiver = null;
       }
       try {
@@ -705,7 +705,7 @@
            mFMOn = false;
        }
        if(null != mReceiver) {
-           mReceiver.disable();
+           mReceiver.disable(this);
            mReceiver = null;
        }
        try {
@@ -723,14 +723,14 @@
             throw new RuntimeException("FmTx service not available!");
            }
            if (mReceiver.getFMState() == mReceiver.FMState_Turned_Off) {
-               bStatus = mReceiver.enable(config);
+               bStatus = mReceiver.enable(config, this);
            } else {
                try {
                    Thread.sleep(100);
                } catch (Exception ex) {
                    Log.d( LOGTAG,  "RunningThread InterruptedException");
                }
-               bStatus = mReceiver.enable(config);
+               bStatus = mReceiver.enable(config, this);
            }
            if (!bStatus) {
                Log.e( LOGTAG,  "Search for weak station failed");
diff --git a/helium/radio-helium-commands.h b/helium/radio-helium-commands.h
index da02f52..c5dfba9 100644
--- a/helium/radio-helium-commands.h
+++ b/helium/radio-helium-commands.h
@@ -100,6 +100,7 @@
     HCI_FM_HELIUM_RDS_GRP_COUNTERS_EXT,
     HCI_FM_HELIUM_AGC_UCCTRL = 0x8000043, /* 0x8000043 */
     HCI_FM_HELIUM_AGC_GAIN_STATE,
+    HCI_FM_HELIUM_ENABLE_LPF,
 
     /*using private CIDs under userclass*/
     HCI_FM_HELIUM_READ_DEFAULT = 0x00980928,
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 4437748..30c3d0c 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -283,6 +283,7 @@
 #define HCI_OCF_FM_GET_CH_DET_THRESHOLD     0x0018
 #define HCI_OCF_FM_SET_BLND_TBL             0x001B
 #define HCI_OCF_FM_GET_BLND_TBL             0x001C
+#define HCI_OCF_FM_LOW_PASS_FILTER_CTRL     0x001F
 /* HCI trans control commans opcode*/
 #define HCI_OCF_FM_ENABLE_TRANS_REQ         0x0001
 #define HCI_OCF_FM_DISABLE_TRANS_REQ        0x0002
@@ -1275,6 +1276,7 @@
 int hci_fm_default_data_read_req(struct hci_fm_def_data_rd_req *def_data_rd);
 int hci_fm_get_blend_req();
 int hci_fm_set_blend_tbl_req(struct hci_fm_blend_table *blnd_tbl);
+int hci_fm_enable_lpf(int enable);
 int hci_fm_default_data_write_req(struct hci_fm_def_data_wr_req * data_wrt);
 int hci_fm_get_station_dbg_param_req();
 int hci_fm_get_station_cmd_param_req();
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index c3dc559..e6ab1b1 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -488,6 +488,11 @@
             hci_cc_station_rsp(pbuf);
             break;
 
+    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_LOW_PASS_FILTER_CTRL):
+            ALOGI("%s: recived LPF enable event", __func__);
+            hci_cc_rsp(pbuf);
+            break;
+
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
             hci_cc_dbg_param_rsp(pbuf);
             break;
@@ -1559,6 +1564,12 @@
          radio->blend_tbl.BlendRmssiHi = val;
          ret = hci_fm_set_blend_tbl_req(&radio->blend_tbl);
          break;
+    case HCI_FM_HELIUM_ENABLE_LPF:
+         ALOGI("%s: val: %x", __func__, val);
+         if (!(ret = hci_fm_enable_lpf(val))) {
+             ALOGI("%s: command sent sucessfully", __func__, val);
+         }
+         break;
     default:
         ALOGE("%s:%s: Not a valid FM CMD!!", LOG_TAG, __func__);
         ret = 0;
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index 8feb41f..7945023 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -447,3 +447,15 @@
             HCI_OCF_FM_STATION_DBG_PARAM);
     return send_fm_cmd_pkt(opcode, 0, NULL);
 }
+
+int hci_fm_enable_lpf(int enable)
+{
+    ALOGI("%s: enable: %x", __func__, enable);
+
+    uint16_t opcode = 0;
+    int enable_lpf = enable;
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+                                  HCI_OCF_FM_LOW_PASS_FILTER_CTRL);
+    return send_fm_cmd_pkt(opcode, sizeof(enable_lpf), &enable_lpf);
+}
diff --git a/qcom/fmradio/FmReceiver.java b/qcom/fmradio/FmReceiver.java
index c61b78e..5ba27c8 100644
--- a/qcom/fmradio/FmReceiver.java
+++ b/qcom/fmradio/FmReceiver.java
@@ -28,10 +28,20 @@
 
 package qcom.fmradio;
 
+import android.content.Context;
+import android.os.Bundle;
+import android.telephony.TelephonyManager;
+import android.telephony.PhoneStateListener;
 import android.util.Log;
 import android.os.SystemProperties;
 import java.util.Arrays;
 import java.lang.Runnable;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.content.IntentFilter;
+import android.bluetooth.BluetoothAdapter;
+
 /**
  * This class contains all interfaces and types needed to
  * Control the FM receiver.
@@ -41,11 +51,38 @@
 {
 
    public static int mSearchState = subSrchLevel_NoSearch;
+   private IntentFilter mIntentFilter;
+   private IntentFilter mBtIntentFilter;
 
    static final int STD_BUF_SIZE = 256;
    static final int GRP_3A = 64;
+   static final int ENABLE_LPF = 1;
+   static final int DISABLE_LPF = 0;
    private static final String TAG = "FMRadio";
 
+
+   private static int  mEnableLpfGprs = 0x1;
+   private static int  mEnableLpfEdge = 0x2;
+   private static int  mEnableLpfUmts = 0x4;
+   private static int  mEnableLpfCdma = 0x8;
+   private static int  mEnableLpfEvdo0 = 0x10;
+   private static int  mEnableLpfEvdoA = 0x20;
+   private static int  mEnableLpf1xRtt = 0x40;
+   private static int  mEnableLpfHsdpa = 0x80;
+   private static int  mEnableLpfHsupa = 0x100;
+   private static int  mEnableLpfHspa = 0x200;
+   private static int  mEnableLpfIden = 0x400;
+   private static int  mEnableLpfEvdoB = 0x800;
+   private static int  mEnableLpfLte = 0x1000;
+   private static int  mEnableLpfEhrpd = 0x2000;
+   private static int  mEnableLpfHspap = 0x4000;
+   private static int  mEnableLpfGsm = 0x8000;
+   private static int  mEnableLpfScdma = 0x10000;
+   private static int  mEnableLpfIwlan = 0x20000;
+   private static int  mEnableLpfLteCa = 0x40000;
+
+   private static int  mIsBtLpfEnabled = 0x01;
+   private static int  mIsWlanLpfEnabled = 0x2;
    /**
    * Search (seek/scan/searchlist) by decrementing the frequency
    *
@@ -306,7 +343,6 @@
    private static final int SEARCH_MPXDCC = 0;
    private static final int SEARCH_SINR_INT = 1;
 
-
    public boolean isSmdTransportLayer() {
        String transportLayer = SystemProperties.get("ro.qualcomm.bt.hci_transport");
        if (transportLayer.equals("smd"))
@@ -331,6 +367,79 @@
            return false;
    }
 
+   public PhoneStateListener  mDataConnectionStateListener = new PhoneStateListener(){
+        public void onDataConnectionStateChanged(int state, int networkType) {
+              Log.d (TAG, "state: " + Integer.toString(state) +  " networkType: " + Integer.toString(networkType));
+              if (state == TelephonyManager.DATA_CONNECTED) {
+                  FMcontrolLowPassFilter(state, networkType, ENABLE_LPF);
+              } else {
+                  mControl.enableLPF(sFd, DISABLE_LPF);
+              }
+       }
+   };
+
+   /* Register for wan state changes to support wan-fm concurrency */
+   public void registerDataConnectionStateListener(Context mContext) {
+       Log.d (TAG, "registerDataConnectionStateListener");
+       TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+       tm.listen(mDataConnectionStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+   }
+
+   /* UnRegister */
+   public void unregisterDataConnectionStateListener(Context mContext) {
+       Log.d (TAG, "unregisterDataConnectionStateListener: ");
+       TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+       tm.listen(mDataConnectionStateListener, PhoneStateListener.LISTEN_NONE);
+   }
+
+   private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+       @Override
+       public void onReceive(Context context, Intent intent) {
+
+           Log.d (TAG, "onReceive: Wifi State change intent");
+
+           if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+               int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                        WifiManager.WIFI_STATE_UNKNOWN);
+               if (newState == WifiManager.WIFI_STATE_ENABLED) {
+                   Log.d (TAG, "enable LPF on wifi enabled " + newState);
+                   int mBtWlanLpf = SystemProperties.getInt("persist.btwlan.lpfenabler", 0);
+                   if ((mBtWlanLpf & mIsWlanLpfEnabled) == mIsWlanLpfEnabled)
+                       mControl.enableLPF(sFd, ENABLE_LPF);
+               } else {
+                   Log.d (TAG, "Disable LPF on wifi state other than enabled " + newState);
+                   mControl.enableLPF(sFd, DISABLE_LPF);
+               }
+           } else {
+               Log.d (TAG, "WIFI_STATE_CHANGED_ACTION failed");
+           }
+       }
+   };
+
+   private final BroadcastReceiver mBtReceiver = new BroadcastReceiver() {
+       @Override
+       public void onReceive(Context context, Intent intent) {
+
+           Log.d (TAG, "onReceive: Bluetooth State change intent");
+
+           if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+               int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+               if (newState == BluetoothAdapter.STATE_ON) {
+                   Log.d (TAG, "enable LPF on BT enabled " + newState);
+                   int mBtWlanLpf = SystemProperties.getInt("persist.btwlan.lpfenabler", 0);
+                   if ((mBtWlanLpf & mIsBtLpfEnabled) == mIsBtLpfEnabled)
+                       mControl.enableLPF(sFd, ENABLE_LPF);
+               } else {
+                   Log.d (TAG, "Disable LPF on BT state other than enabled " + newState);
+                   mControl.enableLPF(sFd, DISABLE_LPF);
+               }
+           } else {
+               Log.d (TAG, "ACTION_STATE_CHANGED failed");
+           }
+       }
+   };
+
    /**
     * Constructor for the receiver Object
     */
@@ -461,13 +570,17 @@
    *    @see #disable
    *
    */
-   public boolean enable (FmConfig configSettings){
+   public boolean enable (FmConfig configSettings, Context app_context){
       boolean status = false;
       /*
        * Check for FM State.
        * If FMRx already on, then return.
       */
       int state = getFMState();
+
+      mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
+      mBtIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+
       if (state == FMState_Rx_Turned_On || state == FMState_Srch_InProg) {
          Log.d(TAG, "enable: FM already turned On and running");
          return status;
@@ -493,6 +606,19 @@
               status = registerClient(mCallback);
           }
           mRdsData = new FmRxRdsData(sFd);
+          registerDataConnectionStateListener(app_context);
+          app_context.registerReceiver(mReceiver, mIntentFilter);
+         WifiManager wifiManager = (WifiManager)app_context.getSystemService(app_context.WIFI_SERVICE);
+         if (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
+               Log.d(TAG, "enable LPF if WIFI is already on");
+               mControl.enableLPF(sFd, ENABLE_LPF);
+         }
+         app_context.registerReceiver(mBtReceiver, mBtIntentFilter);
+         BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+         if (btAdapter != null) {
+               Log.d(TAG, "enable LPF if BT is already on");
+               mControl.enableLPF(sFd, ENABLE_LPF);
+         }
       }
       else {
          status = false;
@@ -559,7 +685,7 @@
    *    @see #enable
    *    @see #registerClient
    */
-   public boolean disable(){
+   public boolean disable(Context app_context){
       boolean status = false;
       /*
        * Check for FM State. If search is in progress, then cancel the search prior
@@ -617,7 +743,9 @@
       setFMPowerState(subPwrLevel_FMTurning_Off);
       Log.v(TAG, "disable: CURRENT-STATE : FMRxOn ---> NEW-STATE : FMTurningOff");
       super.disable();
-
+      unregisterDataConnectionStateListener(app_context);
+      app_context.unregisterReceiver(mBtReceiver);
+      app_context.unregisterReceiver(mReceiver);
       return true;
    }
 
@@ -2820,4 +2948,149 @@
      }
      return;
    }
+   public void FMcontrolLowPassFilter(int state, int net_type, int enable) {
+       int RatConf = SystemProperties.getInt("persist.fm_wan.ratconf", 0);
+       Log.v (TAG, "FMcontrolLowPassFilter " + RatConf);
+       switch (net_type)
+       {
+
+           case TelephonyManager.NETWORK_TYPE_GPRS:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfGprs  & RatConf) == mEnableLpfGprs)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_EDGE:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfEdge  & RatConf) == mEnableLpfEdge)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_UMTS:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfUmts  & RatConf) == mEnableLpfUmts )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_CDMA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfCdma & RatConf) == mEnableLpfCdma)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_EVDO_0:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfEvdo0  & RatConf) == mEnableLpfEvdo0 )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_EVDO_A:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfEvdoA  & RatConf) == mEnableLpfEvdoA )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_1xRTT:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpf1xRtt  & RatConf) == mEnableLpf1xRtt )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_HSDPA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfHsdpa  & RatConf) == mEnableLpfHsdpa )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_HSUPA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfHsupa & RatConf) == mEnableLpfHsupa)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_HSPA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfHspa  & RatConf) == mEnableLpfHspa )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_IDEN:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfIden  & RatConf) == mEnableLpfIden )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_EVDO_B:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfEvdoB  & RatConf) == mEnableLpfEvdoB )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_LTE:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfLte  & RatConf) == mEnableLpfLte )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_EHRPD:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfEhrpd  & RatConf) == mEnableLpfEhrpd )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_HSPAP:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfHspap  & RatConf) == mEnableLpfHspap)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_GSM:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfGsm & RatConf) == mEnableLpfGsm)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfScdma & RatConf) == mEnableLpfScdma)) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+          case TelephonyManager.NETWORK_TYPE_IWLAN:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfIwlan  & RatConf) == mEnableLpfIwlan )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+          case TelephonyManager.NETWORK_TYPE_LTE_CA:
+               if ((state == TelephonyManager.DATA_CONNECTED) &&
+                      ((mEnableLpfLteCa  & RatConf) == mEnableLpfLteCa )) {
+                   Log.d (TAG, "enabling LPF for net_type: " + Integer.toString(net_type));
+                   mControl.enableLPF(sFd, enable);
+               }
+               break;
+           default:
+               Log.d (TAG, "net_type " + Integer.toString(net_type) + " doesn't need LPF enabling");
+               mControl.enableLPF(sFd, enable);
+               break;
+       }
+   }
 }
diff --git a/qcom/fmradio/FmRxControls.java b/qcom/fmradio/FmRxControls.java
index 701448f..7b9fb7c 100644
--- a/qcom/fmradio/FmRxControls.java
+++ b/qcom/fmradio/FmRxControls.java
@@ -100,6 +100,7 @@
    private static final int V4L2_CID_PRIVATE_AF_JUMP_RSSI_TH               = V4L2_CID_PRIVATE_BASE + 0x3F;
    private static final int V4L2_CID_PRIVATE_BLEND_SINRHI                  = V4L2_CID_PRIVATE_BASE + 0x40;
    private static final int V4L2_CID_PRIVATE_BLEND_RMSSIHI                 = V4L2_CID_PRIVATE_BASE + 0x41;
+   private static final int ENABLE_LOW_PASS_FILTER                         = V4L2_CID_PRIVATE_BASE + 0x45;
 
    private static final int V4L2_CTRL_CLASS_USER = 0x980000;
    private static final int V4L2_CID_BASE        = V4L2_CTRL_CLASS_USER | 0x900;
@@ -196,6 +197,14 @@
       return re;
    }
 
+   public int enableLPF(int fd, int sBuff)
+   {
+      int re = FmReceiverJNI.setControlNative(fd, ENABLE_LOW_PASS_FILTER, sBuff);
+      if ( re < 0)
+         Log.e(TAG, "Failed to enable LPF");
+      return re;
+   }
+
    /*
     * Set Off channel threshold
     */