From cad7171261a1e8709a18c2868f1964e74feb9709 Mon Sep 17 00:00:00 2001 From: Kiran Kelageri <kirankelageri@codeaurora.org> Date: Wed, 27 Apr 2016 16:54:22 -0700 Subject: [PATCH] FM: Avoid interferece during WAN and Fm Coex. Changes are made to avoid interferece seen during WAN and Fm co-ex tests, With this change FM does keep track of WAN status such that it would enable LPF to avoid interference Change-Id: I015cd8b3fa074c4b7b90827a1fe619d44433323b --- .../src/com/caf/fmradio/FMRadioService.java | 4 +- .../com/caf/fmradio/FMTransmitterService.java | 10 +-- helium/radio-helium-commands.h | 1 + helium/radio-helium.h | 2 + helium/radio_helium_hal.c | 11 +++ helium/radio_helium_hal_cmds.c | 12 +++ qcom/fmradio/FmReceiver.java | 80 ++++++++++++++++++- qcom/fmradio/FmRxControls.java | 9 +++ 8 files changed, 118 insertions(+), 11 deletions(-) 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 @@ public class FMRadioService extends Service 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 @@ public class FMRadioService extends Service // 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/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 @@ public class FMTransmitterService extends Service /* Disable Receiver */ if (mReceiver != null) { - bStatus = mReceiver.disable(); + bStatus = mReceiver.disable(this); mReceiver = null; } RText = " "; @@ -585,7 +585,7 @@ public class FMTransmitterService extends Service /* Disable Receiver */ if (mReceiver != null) { - bStatus = mReceiver.disable(); + bStatus = mReceiver.disable(this); mReceiver = null; } try { @@ -705,7 +705,7 @@ public class FMTransmitterService extends Service mFMOn = false; } if(null != mReceiver) { - mReceiver.disable(); + mReceiver.disable(this); mReceiver = null; } try { @@ -723,14 +723,14 @@ public class FMTransmitterService extends Service 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 @@ enum helium_cmd_t { 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 @@ struct radio_hci_dev { #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 set_ch_det_thresholds_req(struct hci_fm_ch_det_threshold *ch_det_th); 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 @@ static inline void hci_cmd_complete_event(char *buff) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ int hci_fm_get_station_dbg_param_req() 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..0ed4149 100644 --- a/qcom/fmradio/FmReceiver.java +++ b/qcom/fmradio/FmReceiver.java @@ -28,10 +28,15 @@ 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; + /** * This class contains all interfaces and types needed to * Control the FM receiver. @@ -46,6 +51,12 @@ public class FmReceiver extends FmTransceiver static final int GRP_3A = 64; private static final String TAG = "FMRadio"; + private static boolean mEnableLpfGsm = false; + private static boolean mEnableLpfCdma = false; + private static boolean mEnableLpfWcdma = false; + private static boolean mEnableLpfLte = false; + private static boolean mEnableLpfScdma = false; + /** * Search (seek/scan/searchlist) by decrementing the frequency * @@ -306,7 +317,6 @@ public class FmReceiver extends FmTransceiver 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 +341,31 @@ public class FmReceiver extends FmTransceiver 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, 1); + } else { + FMcontrolLowPassFilter(state, networkType, 0); + } + } + }; + + /* 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); + } + /** * Constructor for the receiver Object */ @@ -461,7 +496,7 @@ public class FmReceiver extends FmTransceiver * @see #disable * */ - public boolean enable (FmConfig configSettings){ + public boolean enable (FmConfig configSettings, Context app_context){ boolean status = false; /* * Check for FM State. @@ -493,6 +528,7 @@ public class FmReceiver extends FmTransceiver status = registerClient(mCallback); } mRdsData = new FmRxRdsData(sFd); + registerDataConnectionStateListener(app_context); } else { status = false; @@ -559,7 +595,7 @@ public class FmReceiver extends FmTransceiver * @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 +653,7 @@ public class FmReceiver extends FmTransceiver setFMPowerState(subPwrLevel_FMTurning_Off); Log.v(TAG, "disable: CURRENT-STATE : FMRxOn ---> NEW-STATE : FMTurningOff"); super.disable(); - + unregisterDataConnectionStateListener(app_context); return true; } @@ -2820,4 +2856,40 @@ public class FmReceiver extends FmTransceiver } return; } + public void FMcontrolLowPassFilter(int state, int net_type, int enable) { + switch (net_type) + { + case TelephonyManager.NETWORK_TYPE_CDMA: + if ((state == TelephonyManager.DATA_CONNECTED) && + mEnableLpfCdma == true) { + 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 == true) { + 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 == true) { + 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 == true) { + 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"); + 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 @@ class FmRxControls 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 @@ class FmRxControls 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 */ -- GitLab