fm: add support for FMStats for cherokee

Add support for FMStats app for cherokee platform.

Change-Id: Ia63a69697554ebc28a22e86d450fade6b4427a67
diff --git a/helium/radio-helium-commands.h b/helium/radio-helium-commands.h
index f76b7d2..3c9bbdc 100644
--- a/helium/radio-helium-commands.h
+++ b/helium/radio-helium-commands.h
@@ -109,6 +109,7 @@
     HCI_FM_HELIUM_UPPER_BAND,
     HCI_FM_HELIUM_LOWER_BAND,
     HCI_FM_HELIUM_AUDIO_MODE,
+    HCI_FM_HELIUM_RMSSI,
     HCI_FM_HELIUM_AUDIO_MUTE,
 };
 #endif /* __RADIO_CHEROKEE_COMMANDS_H */
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 98452d8..05fc309 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -104,38 +104,41 @@
 #define FM_TX_PHY_CFG_LEN    0x10
 #define FM_TX_PWR_GAIN_OFFSET 14
 /**RDS CONFIG MODE**/
-#define FM_RDS_CNFG_MODE	0x0f
-#define FM_RDS_CNFG_LEN		0x10
-#define AF_RMSSI_TH_LSB_OFFSET	10
-#define AF_RMSSI_TH_MSB_OFFSET	11
-#define AF_RMSSI_SAMPLES_OFFSET	15
+#define FM_RDS_CNFG_MODE    0x0f
+#define FM_RDS_CNFG_LEN     0x10
+#define AF_RMSSI_TH_OFFSET  1
+#define AF_RMSSI_SAMPLES_OFFSET 2
 /**RX CONFIG MODE**/
-#define FM_RX_CONFG_MODE	0x15
-#define FM_RX_CNFG_LEN		0x20
-#define GD_CH_RMSSI_TH_OFFSET	12
-#define MAX_GD_CH_RMSSI_TH	127
-#define SRCH_ALGO_TYPE_OFFSET  25
-#define SINRFIRSTSTAGE_OFFSET  26
-#define RMSSIFIRSTSTAGE_OFFSET 27
-#define CF0TH12_BYTE1_OFFSET   8
-#define CF0TH12_BYTE2_OFFSET   9
-#define CF0TH12_BYTE3_OFFSET   10
-#define CF0TH12_BYTE4_OFFSET   11
-#define MAX_SINR_FIRSTSTAGE	127
-#define MAX_RMSSI_FIRSTSTAGE	127
+#define FM_RX_CONFG_MODE    0x15
+#define FM_RX_CNFG_LEN      0x15
+#define GD_CH_RMSSI_TH_OFFSET   0x03
+#define MAX_GD_CH_RMSSI_TH  0x7F
+#define SRCH_ALGO_TYPE_OFFSET  0x00
+#define SINRFIRSTSTAGE_OFFSET  0x01
+#define RMSSIFIRSTSTAGE_OFFSET 0x02
+#define CF0TH12_BYTE1_OFFSET   0x03
+#define CF0TH12_BYTE2_OFFSET   0x04
+#define MAX_SINR_FIRSTSTAGE 0x7F
+#define MAX_RMSSI_FIRSTSTAGE    0x7F
 #define RDS_PS0_XFR_MODE 0x01
-#define RDS_PS0_LEN 6
-#define RX_REPEATE_BYTE_OFFSET 5
-#define FM_SPUR_TBL_SIZE 240
-#define SPUR_DATA_LEN 16
-#define ENTRIES_EACH_CMD 15
-#define SPUR_DATA_INDEX 2
-#define FM_AF_LIST_MAX_SIZE   200
+#define RDS_PS0_LEN 0x06
+#define RX_REPEATE_BYTE_OFFSET 0x05
+#define FM_SPUR_TBL_SIZE 0xF0
+#define SPUR_DATA_LEN 0x10
+#define ENTRIES_EACH_CMD 0x0F
+#define SPUR_DATA_INDEX 0x02
+#define FM_AF_LIST_MAX_SIZE   0xC8
 #define AF_LIST_MAX     (FM_AF_LIST_MAX_SIZE / 4) /* Each AF frequency consist
-							of sizeof(int) bytes */
-#define MAX_BLEND_INDEX 49
+                            of sizeof(int) bytes */
+#define MAX_BLEND_INDEX 0x31
+
+#define FM_SRCH_CONFG_MODE  0x41
+#define FM_AFJUMP_CONFG_MODE 0x42
+#define FM_SRCH_CNFG_LEN    0x08
+#define FM_AFJUMP_CNFG_LEN  0x06
+
 /* HCI timeouts */
-#define RADIO_HCI_TIMEOUT	(10000)	/* 10 seconds */
+#define RADIO_HCI_TIMEOUT   (10000) /* 10 seconds */
 
 typedef enum {
     ASSOCIATE_JVM,
@@ -164,6 +167,15 @@
 typedef void (*fm_ssbi_peek_cb)(char *ssbi_peek_rsp);
 typedef void (*fm_ch_det_th_cb)(char *ch_det_rsp);
 typedef void (*fm_ecc_evt_cb)(char *ecc_rsp);
+typedef void (*fm_sig_thr_cb) (int val, int status);
+typedef void (*fm_get_ch_det_thrs_cb) (int val, int status);
+typedef void (*fm_def_data_rd_cb) (int val, int status);
+typedef void (*fm_get_blnd_cb) (int val, int status);
+typedef void (*fm_set_ch_det_thrs_cb) (int status);
+typedef void (*fm_def_data_wrt_cb) (int status);
+typedef void (*fm_set_blnd_cb) (int status);
+typedef void (*fm_get_stn_prm_cb) (int val, int status);
+typedef void (*fm_get_stn_dbg_prm_cb) (int val, int status);
 
 typedef struct {
     size_t  size;
@@ -188,6 +200,15 @@
     fm_ch_det_th_cb fm_ch_det_th_rsp_cb;
     fm_ecc_evt_cb	ext_country_code_cb;
     callback_thread_event thread_evt_cb;
+    fm_sig_thr_cb fm_get_sig_thres_cb;
+    fm_get_ch_det_thrs_cb fm_get_ch_det_thr_cb;
+    fm_def_data_rd_cb fm_def_data_read_cb;
+    fm_get_blnd_cb fm_get_blend_cb;
+    fm_set_ch_det_thrs_cb fm_set_ch_det_thr_cb;
+    fm_def_data_wrt_cb fm_def_data_write_cb;
+    fm_set_blnd_cb fm_set_blend_cb;
+    fm_get_stn_prm_cb fm_get_station_param_cb;
+    fm_get_stn_dbg_prm_cb fm_get_station_debug_param_cb;
 } fm_vendor_callbacks_t;
 
 pthread_mutex_t radio_fm_cmd;
@@ -304,11 +325,11 @@
      (short) hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, ocf)
 #define hci_trans_ctrl_cmd_op_pack(ocf) \
      (short) hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ, ocf)
-#define hci_common_cmd_op_pack(ocf)	\
+#define hci_common_cmd_op_pack(ocf) \
      (short) hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ, ocf)
-#define hci_status_param_op_pack(ocf)	\
+#define hci_status_param_op_pack(ocf)   \
      (short) hci_opcode_pack(HCI_OGF_FM_STATUS_PARAMETERS_CMD_REQ, ocf)
-#define hci_diagnostic_cmd_op_pack(ocf)	\
+#define hci_diagnostic_cmd_op_pack(ocf) \
      (short) hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ, ocf)
 
 
@@ -342,15 +363,15 @@
     char  ch_spacing;
     char  rds_std;
     char  hlsi;
-    int	  band_low_limit;
-    int	  band_high_limit;
+    int   band_low_limit;
+    int   band_high_limit;
 } ;
 
 /* ----- HCI Command request ----- */
 struct hci_fm_trans_conf_req_struct {
     char  emphasis;
     char  rds_std;
-    int	  band_low_limit;
+    int   band_low_limit;
     int   band_high_limit;
 } ;
 
@@ -467,21 +488,27 @@
     char sinr_samples;
     char low_th;
     char high_th;
-
 } ;
 
 struct hci_fm_blend_table {
-    char ucBlendType;
-    char ucBlendRampRateUp;
-    char ucBlendDebounceNumSampleUp;
-    char ucBlendDebounceIdxUp;
-    char ucBlendSinrIdxSkipStep;
-    char scBlendSinrHi;
-    char scBlendRmssiHi;
-    char ucBlendIndexHi;
-    char ucBlendIndex[MAX_BLEND_INDEX];
+    char BlendType;
+    char BlendRampRateUp;
+    char BlendDebounceNumSampleUp;
+    char BlendDebounceIdxUp;
+    char BlendSinrIdxSkipStep;
+    char BlendSinrHi;
+    char BlendRmssiHi;
+    char BlendIndexHi;
+    char BlendIndex[MAX_BLEND_INDEX];
 } ;
 
+struct hci_fm_def_data_rd {
+    char mode;
+    char length;
+    char param_len;
+    char param;
+};
+
 /*HCI events*/
 #define HCI_EV_TUNE_STATUS              0x01
 #define HCI_EV_RDS_LOCK_STATUS          0x02
@@ -521,22 +548,22 @@
 /*RT PLUS*/
 #define DUMMY_CLASS             0
 #define RT_PLUS_LEN_1_TAG       3
-#define RT_ERT_FLAG_BIT	        5
+#define RT_ERT_FLAG_BIT         5
 
 /*TAG1*/
-#define TAG1_MSB_OFFSET	        3
-#define TAG1_MSB_MASK	        7
-#define TAG1_LSB_OFFSET	        5
+#define TAG1_MSB_OFFSET         3
+#define TAG1_MSB_MASK           7
+#define TAG1_LSB_OFFSET         5
 #define TAG1_POS_MSB_MASK       31
 #define TAG1_POS_MSB_OFFSET     1
 #define TAG1_POS_LSB_OFFSET     7
-#define TAG1_LEN_OFFSET	        1
+#define TAG1_LEN_OFFSET         1
 #define TAG1_LEN_MASK           63
 
 /*TAG2*/
-#define TAG2_MSB_OFFSET	        5
+#define TAG2_MSB_OFFSET         5
 #define TAG2_MSB_MASK           1
-#define TAG2_LSB_OFFSET	        3
+#define TAG2_LSB_OFFSET         3
 #define TAG2_POS_MSB_MASK       7
 #define TAG2_POS_MSB_OFFSET     3
 #define TAG2_POS_LSB_OFFSET     5
@@ -544,7 +571,7 @@
 
 #define AGT_MASK                31
 /*Extract 5 left most bits of lsb of 2nd block*/
-#define AGT(x) 	             (x & AGT_MASK)
+#define AGT(x)               (x & AGT_MASK)
 /*16 bits of 4th block*/
 #define AID(lsb, msb)        ((msb << 8) | (lsb))
 /*Extract 5 right most bits of msb of 2nd block*/
@@ -554,9 +581,9 @@
 #define RT_PLUS_AID          0x4bd7
 
 /*ERT*/
-#define ERT_AID	             0x6552
-#define CARRIAGE_RETURN	     0x000D
-#define MAX_ERT_SEGMENT	     31
+#define ERT_AID              0x6552
+#define CARRIAGE_RETURN      0x000D
+#define MAX_ERT_SEGMENT      31
 #define ERT_FORMAT_DIR_BIT   1
 
 #define EXTRACT_BIT(data, bit_pos) ((data & (1 << bit_pos)) >> bit_pos)
@@ -683,8 +710,7 @@
 } ;
 
 struct hci_fm_data_rd_rsp {
-    char    status;
-    char    ret_data_len;
+    char    data_len;
     char    data[DEFAULT_DATA_SIZE];
 } ;
 
@@ -694,7 +720,6 @@
 } ;
 
 struct hci_fm_dbg_param_rsp {
-    char    status;
     char    blend;
     char    soft_mute;
     char    inf_blend;
@@ -704,35 +729,35 @@
     char    in_det_out;
 } ;
 
-#define CLKSPURID_INDEX0	0
-#define CLKSPURID_INDEX1	5
-#define CLKSPURID_INDEX2	10
-#define CLKSPURID_INDEX3	15
-#define CLKSPURID_INDEX4	20
-#define CLKSPURID_INDEX5	25
+#define CLKSPURID_INDEX0    0
+#define CLKSPURID_INDEX1    5
+#define CLKSPURID_INDEX2    10
+#define CLKSPURID_INDEX3    15
+#define CLKSPURID_INDEX4    20
+#define CLKSPURID_INDEX5    25
 
-#define MAX_SPUR_FREQ_LIMIT	30
-#define CKK_SPUR		0x3B
-#define SPUR_DATA_SIZE		0x4
-#define SPUR_ENTRIES_PER_ID	0x5
+#define MAX_SPUR_FREQ_LIMIT 30
+#define CKK_SPUR        0x3B
+#define SPUR_DATA_SIZE      0x4
+#define SPUR_ENTRIES_PER_ID 0x5
 
 #define COMPUTE_SPUR(val)         ((((val) - (76000)) / (50)))
 #define GET_FREQ(val, bit)        ((bit == 1) ? ((val) >> 8) : ((val) & 0xFF))
 #define GET_SPUR_ENTRY_LEVEL(val) ((val) / (5))
 
 struct hci_fm_spur_data {
-    int	  freq[MAX_SPUR_FREQ_LIMIT];
+    int   freq[MAX_SPUR_FREQ_LIMIT];
     char  rmssi[MAX_SPUR_FREQ_LIMIT];
     char  enable[MAX_SPUR_FREQ_LIMIT];
 } ;
 
 
 /* HCI dev events */
-#define RADIO_HCI_DEV_REG			1
-#define RADIO_HCI_DEV_WRITE			2
+#define RADIO_HCI_DEV_REG           1
+#define RADIO_HCI_DEV_WRITE         2
 
-#define hci_req_lock(d)		mutex_lock(&d->req_lock)
-#define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
+#define hci_req_lock(d)     mutex_lock(&d->req_lock)
+#define hci_req_unlock(d)   mutex_unlock(&d->req_lock)
 
 /* FM RDS */
 #define RDS_PTYPE 2
@@ -824,7 +849,7 @@
 #define SRCH_MODE       0x07
 #define SRCH_DIR        0x08 /* 0-up 1-down */
 #define SCAN_DWELL      0x70
-#define SRCH_ON	        0x80
+#define SRCH_ON         0x80
 
 /* I/O Control */
 #define IOC_HRD_MUTE    0x03
@@ -835,12 +860,12 @@
 #define IOC_ANTENNA     0x01
 
 /* RDS Control */
-#define RDS_ON	    0x01
+#define RDS_ON      0x01
 #define RDS_BUF_SZ  100
 
 /* constants */
-#define  RDS_BLOCKS_NUM	(4)
-#define BYTES_PER_BLOCK	(3)
+#define  RDS_BLOCKS_NUM (4)
+#define BYTES_PER_BLOCK (3)
 #define MAX_PS_LENGTH   (108)
 #define MAX_RT_LENGTH   (64)
 #define RDS_GRP_CNTR_LEN (36)
@@ -861,7 +886,7 @@
 #define GET_LSB(x)((x) & 0xFF)
 
 /* control options */
-#define CTRL_ON	    (1)
+#define CTRL_ON     (1)
 #define CTRL_OFF    (0)
 
 /*Diagnostic commands*/
@@ -885,7 +910,7 @@
 #define MAX_CALIB_SIZE 75
 
 /* Channel validity */
-#define INVALID_CHANNEL	    (0)
+#define INVALID_CHANNEL     (0)
 #define VALID_CHANNEL       (1)
 
 struct hci_fm_set_cal_req_proc {
@@ -1170,7 +1195,44 @@
     struct hci_fm_ssbi_req    ssbi_data_accs;
     struct hci_fm_ssbi_peek   ssbi_peek_reg;
     struct hci_fm_ch_det_threshold ch_det_threshold;
+    struct hci_fm_data_rd_rsp def_data;
+    struct hci_fm_blend_table blend_tbl;
 };
+
+#define set_bit(flag, bit_pos)      ((flag) |= (1 << (bit_pos)))
+#define clear_bit(flag, bit_pos)    ((flag) &= (~(1 << (bit_pos))))
+#define test_bit(flag, bit_pos)     ((flag) & (1 << (bit_pos)))
+#define clear_all_bit(flag)         ((flag) &= (~0xFFFFFFFF))
+#define CMD_CHDET_SINR_TH           (1)
+#define CMD_CHDET_SINR_SAMPLE       (2)
+#define CMD_CHDET_INTF_TH_LOW       (3)
+#define CMD_CHDET_INTF_TH_HIGH      (4)
+
+#define CMD_DEFRD_AF_RMSSI_TH       (1)
+#define CMD_DEFRD_AF_RMSSI_SAMPLE   (2)
+#define CMD_DEFRD_GD_CH_RMSSI_TH    (3)
+#define CMD_DEFRD_SEARCH_ALGO       (4)
+#define CMD_DEFRD_SINR_FIRST_STAGE  (5)
+#define CMD_DEFRD_RMSSI_FIRST_STAGE (6)
+#define CMD_DEFRD_CF0TH12           (7)
+#define CMD_DEFRD_TUNE_POWER        (8)
+#define CMD_DEFRD_REPEATCOUNT       (9)
+
+#define CMD_STNPARAM_RSSI           (1)
+#define CMD_STNPARAM_SINR           (2)
+#define CMD_STNPARAM_INTF_DET_TH    (3)
+
+#define CMD_STNDBGPARAM_BLEND       (1)
+#define CMD_STNDBGPARAM_SOFTMUTE    (2)
+#define CMD_STNDBGPARAM_INFBLEND    (3)
+#define CMD_STNDBGPARAM_INFSOFTMUTE (4)
+#define CMD_STNDBGPARAM_PILOTPLL    (5)
+#define CMD_STNDBGPARAM_IOVERC      (6)
+#define CMD_STNDBGPARAM_INFDETOUT   (7)
+
+#define CMD_BLENDTBL_SINR_HI        (1)
+#define CMD_BLENDTBL_RMSSI_HI       (2)
+
 int hci_fm_disable_recv_req();
 int helium_search_list(struct hci_fm_search_station_list_req *s_list);
 int helium_search_rds_stations(struct hci_fm_search_rds_station_req *rds_srch);
@@ -1194,6 +1256,11 @@
 int hci_ssbi_peek_reg(struct hci_fm_ssbi_peek *data);
 int hci_fm_get_ch_det_th();
 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_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();
 
 #endif /* __UAPI_RADIO_HCI_CORE_H */
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index 561c92a..2a29f64 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -36,6 +36,7 @@
 #include "radio-helium.h"
 #include "fm_hci.h"
 #include <dlfcn.h>
+#include <errno.h>
 
 fm_vendor_callbacks_t *jni_cb;
 int hci_fm_get_signal_threshold();
@@ -52,6 +53,12 @@
 static char utf_8_flag;
 static char rt_ert_flag;
 static char formatting_dir;
+static uint32_t ch_det_th_mask_flag;
+static uint32_t def_data_rd_mask_flag;
+static uint32_t blend_tbl_mask_flag;
+static uint32_t station_param_mask_flag;
+static uint32_t station_dbg_param_mask_flag;
+uint64_t flag;
 
 #define LOG_TAG "radio_helium"
 static void radio_hci_req_complete(char result)
@@ -76,6 +83,8 @@
     jni_cb->thread_evt_cb(0);
     radio_hci_req_complete(rsp->status);
     jni_cb->enabled_cb();
+    if (rsp->status == FM_HC_STATUS_SUCCESS)
+        radio->mode = FM_RECV;
 }
 
 static void hci_cc_conf_rsp(char *ev_rsp)
@@ -181,20 +190,179 @@
 
 static void hci_cc_get_ch_det_threshold_rsp(char *ev_buff)
 {
-    char status;
-
+    int status;
+    int val = 0;
     if (ev_buff == NULL) {
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
         return;
     }
     status = ev_buff[0];
-    ALOGE("%s:%s, status =%d\n", LOG_TAG, __func__,status);
-    if (status < 0) {
+    ALOGV("%s:%s, status =%d\n", LOG_TAG, __func__,status);
+    if (status != 0) {
         ALOGE("%s:%s,ssbi peek failed=%d\n", LOG_TAG, __func__, status);
-    }
-    memcpy(&radio->ch_det_threshold, &ev_buff[1],
+    } else {
+        memcpy(&radio->ch_det_threshold, &ev_buff[1],
                         sizeof(struct hci_fm_ch_det_threshold));
-    radio_hci_req_complete(status);
+        radio_hci_req_complete(status);
+
+        if (test_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_TH))
+            val = radio->ch_det_threshold.sinr;
+        else if (test_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_SAMPLE))
+            val = radio->ch_det_threshold.sinr_samples;
+        else if (test_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_LOW))
+            val = radio->ch_det_threshold.low_th;
+        else if (test_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_HIGH))
+            val = radio->ch_det_threshold.high_th;
+    }
+    clear_all_bit(ch_det_th_mask_flag);
+    jni_cb->fm_get_ch_det_thr_cb(val, status);
+}
+
+static void hci_cc_set_ch_det_threshold_rsp(char *ev_buff)
+{
+    int status = ev_buff[0];
+
+    jni_cb->fm_set_ch_det_thr_cb(status);
+}
+
+static void hci_cc_sig_threshold_rsp(char *ev_buff)
+{
+    int status, val = -1;
+    ALOGD("hci_cc_sig_threshold_rsp");
+
+    status = ev_buff[0];
+
+    if (status != 0) {
+        ALOGE("%s: status= 0x%x", __func__, status);
+    } else {
+        val = ev_buff[1];
+    }
+    jni_cb->fm_get_sig_thres_cb(val, status);
+}
+
+static void hci_cc_default_data_read_rsp(char *ev_buff)
+{
+    int status, val= 0, data_len = 0;
+
+    if (ev_buff == NULL) {
+        ALOGE("Response buffer is null");
+        return;
+    }
+    status = ev_buff[0];
+    if (status == 0) {
+        data_len = ev_buff[1];
+        ALOGV("hci_cc_default_data_read_rsp:data_len = %d", data_len);
+        memcpy(&radio->def_data, &ev_buff[1], data_len + sizeof(char));
+
+        if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_AF_RMSSI_TH)) {
+            val = radio->def_data.data[AF_RMSSI_TH_OFFSET];
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_AF_RMSSI_SAMPLE)) {
+            val = radio->def_data.data[AF_RMSSI_SAMPLES_OFFSET];
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_GD_CH_RMSSI_TH)) {
+            val = radio->def_data.data[GD_CH_RMSSI_TH_OFFSET];
+            if (val > MAX_GD_CH_RMSSI_TH)
+                val -= 256;
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_SEARCH_ALGO)) {
+            val = radio->def_data.data[SRCH_ALGO_TYPE_OFFSET];
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_SINR_FIRST_STAGE)) {
+            val = radio->def_data.data[SINRFIRSTSTAGE_OFFSET];
+            if (val > MAX_SINR_FIRSTSTAGE)
+                val -= 256;
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_RMSSI_FIRST_STAGE)) {
+            val = radio->def_data.data[RMSSIFIRSTSTAGE_OFFSET];
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_CF0TH12)) {
+            val = (radio->def_data.data[CF0TH12_BYTE1_OFFSET] |
+                    (radio->def_data.data[CF0TH12_BYTE2_OFFSET] << 8));
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_TUNE_POWER)) {
+        } else if (test_bit(def_data_rd_mask_flag, CMD_DEFRD_REPEATCOUNT)) {
+            val = radio->def_data.data[RX_REPEATE_BYTE_OFFSET];
+        }
+    } else {
+        ALOGE("%s: Error: Status= 0x%x", __func__, status);
+    }
+    clear_all_bit(def_data_rd_mask_flag);
+    jni_cb->fm_def_data_read_cb(val, status);
+}
+
+static void hci_cc_default_data_write_rsp(char *ev_buff)
+{
+    int status = ev_buff[0];
+
+    jni_cb->fm_def_data_write_cb(status);
+}
+
+static void hci_cc_get_blend_tbl_rsp(char *ev_buff)
+{
+    int status, val;
+
+    if (ev_buff == NULL) {
+        ALOGE("%s:response buffer in null", LOG_TAG);
+        return;
+    }
+
+    status = ev_buff[0];
+    if (status != 0) {
+        ALOGE("%s: status = 0x%x", LOG_TAG, status);
+    } else {
+        memcpy(&radio->blend_tbl, &ev_buff[1],
+                sizeof(struct hci_fm_blend_table));
+
+        ALOGE("hci_cc_get_blend_tbl_rsp: data");
+        int i;
+        for (i = 0; i < 8; i++)
+            ALOGE("data[%d] = 0x%x", i, ev_buff[1 + i]);
+        if (test_bit(blend_tbl_mask_flag, CMD_BLENDTBL_SINR_HI)) {
+            val = radio->blend_tbl.BlendSinrHi;
+        } else if (test_bit(blend_tbl_mask_flag, CMD_BLENDTBL_RMSSI_HI)) {
+            val = radio->blend_tbl.BlendRmssiHi;
+        }
+    }
+    clear_all_bit(blend_tbl_mask_flag);
+    jni_cb->fm_get_blend_cb(val, status);
+}
+
+static void hci_cc_set_blend_tbl_rsp(char *ev_buff)
+{
+    int status = ev_buff[0];
+
+    jni_cb->fm_set_blend_cb(status);
+}
+
+static void hci_cc_station_rsp(char *ev_buff)
+{
+    int val, status = ev_buff[0];
+
+    if (status == FM_HC_STATUS_SUCCESS) {
+        memcpy(&radio->fm_st_rsp.station_rsp.station_freq, &ev_buff[1],
+                sizeof(struct hci_fm_station_rsp) - sizeof(char));
+        if (test_bit(station_param_mask_flag, CMD_STNPARAM_RSSI)) {
+                val = radio->fm_st_rsp.station_rsp.rssi;
+        } else if (test_bit(station_param_mask_flag, CMD_STNPARAM_SINR)) {
+            val = radio->fm_st_rsp.station_rsp.sinr;
+        }
+    }
+    ALOGE("hci_cc_station_rsp: val =%x, status = %x", val, status);
+
+    jni_cb->fm_get_station_param_cb(val, status);
+    clear_all_bit(station_param_mask_flag);
+}
+
+static void hci_cc_dbg_param_rsp(char *ev_buff)
+{
+    int val, status = ev_buff[0];
+
+    if (status == FM_HC_STATUS_SUCCESS) {
+        memcpy(&radio->st_dbg_param, &ev_buff[1],
+                sizeof(struct hci_fm_dbg_param_rsp));
+        if (test_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_INFDETOUT)) {
+            val = radio->st_dbg_param.in_det_out;
+        } else if (test_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_IOVERC)) {
+            val = radio->st_dbg_param.io_verc;
+        }
+    }
+    ALOGE("hci_cc_dbg_param_rsp: val =%x, status = %x", val, status);
+    jni_cb->fm_get_station_debug_param_cb(val, status);
+    clear_all_bit(station_dbg_param_mask_flag);
 }
 
 static inline void hci_cmd_complete_event(char *buff)
@@ -233,11 +401,11 @@
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP_PROCESS):
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL):
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL):
-    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD):
-    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL):
-    case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
             hci_cc_rsp(pbuf);
             break;
+    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD):
+            hci_cc_set_ch_det_threshold_rsp(pbuf);
+            break;
     case hci_common_cmd_op_pack(HCI_OCF_FM_RESET):
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_POKE_REG):
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_POKE_DATA):
@@ -257,17 +425,34 @@
             hci_cc_ssbi_peek_rsp(buff);
             break;
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD):
-            hci_cc_get_ch_det_threshold_rsp(buff);
-            break;
-/*    case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
-            hci_cc_get_spur_tbl(buff);
+            hci_cc_get_ch_det_threshold_rsp(pbuf);
             break;
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_SIGNAL_THRESHOLD):
-            hci_cc_sig_threshold_rsp(buff);
+            hci_cc_sig_threshold_rsp(pbuf);
+            break;
+    case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_READ):
+            hci_cc_default_data_read_rsp(pbuf);
+            break;
+    case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
+            hci_cc_default_data_write_rsp(pbuf);
+            break;
+    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL):
+            hci_cc_get_blend_tbl_rsp(pbuf);
+            break;
+    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL):
+            hci_cc_set_blend_tbl_rsp(pbuf);
             break;
 
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_STATION_PARAM_REQ):
-            hci_cc_station_rsp(buff);
+            hci_cc_station_rsp(pbuf);
+            break;
+
+    case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
+            hci_cc_dbg_param_rsp(pbuf);
+            break;
+
+/*    case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
+            hci_cc_get_spur_tbl(buff);
             break;
 
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ):
@@ -282,17 +467,10 @@
             hci_cc_af_list_rsp(buff);
             break;
 
-    case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_READ):
-            hci_cc_riva_read_default_rsp(buff);
-            break;
-
     case hci_common_cmd_op_pack(HCI_OCF_FM_GET_FEATURE_LIST):
             hci_cc_feature_list_rsp(buff);
             break;
 
-    case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
-            hci_cc_dbg_param_rsp(buff);
-            break;
     case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
             hci_cc_rds_grp_cntrs_rsp(buff);
             break;
@@ -300,9 +478,6 @@
             hci_cc_do_calibration_rsp(buff);
             break;
 
-    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL):
-            hci_cc_get_blend_tbl_rsp(buff);
-            break;
     default:
             ALOGE("opcode 0x%x", opcode);
             break; */
@@ -733,7 +908,7 @@
     }
 }
 
-void radio_hci_event_packet(char *evt_buf)
+static void radio_hci_event_packet(char *evt_buf)
 {
     char evt;
 
@@ -947,8 +1122,11 @@
     char temp_val = 0;
     unsigned int rds_grps_proc = 0;
     char *data;
+    struct hci_fm_def_data_wr_req def_data_wrt;
+
 
     ALOGE("%s:cmd: %x, val: %d",LOG_TAG, cmd, val);
+
     switch (cmd) {
     case HCI_FM_HELIUM_AUDIO_MUTE:
         saved_val = radio->mute_mode.hard_mute;
@@ -960,10 +1138,16 @@
         }
         break;
     case HCI_FM_HELIUM_SRCHMODE:
+        if (is_valid_srch_mode(val))
             radio->g_search_mode = val;
+        else
+            ret = -EINVAL;
         break;
     case HCI_FM_HELIUM_SCANDWELL:
+        if (is_valid_scan_dwell_prd(val))
             radio->g_scan_time = val;
+        else
+            ret = -EINVAL;
         break;
     case HCI_FM_HELIUM_SRCHON:
         helium_search_req(val, SRCH_DIR_UP);
@@ -989,18 +1173,28 @@
         ret = helium_set_sig_threshold_req(temp_val);
         if (ret < 0) {
             ALOGE("%s:Error while setting signal threshold\n", LOG_TAG);
-            goto END;
+            goto end;
         }
         break;
     case HCI_FM_HELIUM_SRCH_PTY:
-         radio->srch_rds.srch_pty = val;
-         radio->srch_st_list.srch_pty = val;
+        if (is_valid_pty(val)) {
+            radio->srch_rds.srch_pty = val;
+            radio->srch_st_list.srch_pty = val;
+        } else {
+            ret = -EINVAL;
+        }
          break;
     case HCI_FM_HELIUM_SRCH_PI:
-         radio->srch_rds.srch_pi = val;
+         if (is_valid_pi(val))
+             radio->srch_rds.srch_pi = val;
+         else
+             ret = -EINVAL;
          break;
     case HCI_FM_HELIUM_SRCH_CNT:
-         radio->srch_st_list.srch_list_max = val;
+         if (is_valid_srch_station_cnt(val))
+             radio->srch_st_list.srch_list_max = val;
+         else
+             ret = -EINVAL;
          break;
     case HCI_FM_HELIUM_SPACING:
          saved_val = radio->recv_conf.ch_spacing;
@@ -1009,7 +1203,7 @@
          if (ret < 0) {
              ALOGE("%s:Error in setting channel spacing", LOG_TAG);
              radio->recv_conf.ch_spacing = saved_val;
-             goto END;
+             goto end;
         }
         break;
     case HCI_FM_HELIUM_EMPHASIS:
@@ -1019,7 +1213,7 @@
          if (ret < 0) {
              ALOGE("%s:Error in setting emphasis", LOG_TAG);
              radio->recv_conf.emphasis = saved_val;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_RDS_STD:
@@ -1029,7 +1223,7 @@
          if (ret < 0) {
              ALOGE("%s:Error in rds_std", LOG_TAG);
              radio->recv_conf.rds_std = saved_val;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_RDSON:
@@ -1039,7 +1233,7 @@
          if (ret < 0) {
              ALOGE("%s:Error in rds_std", LOG_TAG);
              radio->recv_conf.rds_std = saved_val;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_RDSGROUP_MASK:
@@ -1052,7 +1246,7 @@
          if (ret < 0) {
              ALOGE("%s:error in setting group mask\n", LOG_TAG);
              radio->rds_grp.rds_grp_enable_mask = saved_val;
-             goto END;
+             goto end;
         }
         break;
     case HCI_FM_HELIUM_RDSGROUP_PROC:
@@ -1062,7 +1256,7 @@
          ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
          if (ret < 0) {
              radio->g_rds_grp_proc_ps = saved_val;
-             goto END;
+             goto end;
          }
          break;
 
@@ -1071,7 +1265,7 @@
          ret = hci_fm_get_rds_grpcounters_req(val);
          if (ret < 0) {
              radio->g_rds_grp_proc_ps = saved_val;
-             goto END;
+             goto end;
          }
          break;
 
@@ -1079,7 +1273,7 @@
          ALOGD("%s: set notch filter  notch=%d ", LOG_TAG,val);
          ret = hci_fm_set_notch_filter_req(val);
          if (ret < 0) {
-            goto END;
+            goto end;
          }
          break;
 
@@ -1093,7 +1287,7 @@
          ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
          if (ret < 0) {
              radio->g_rds_grp_proc_ps = saved_val;
-             goto END;
+             goto end;
         }
         break;
     case HCI_FM_HELIUM_AF_JUMP:
@@ -1106,7 +1300,7 @@
         ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
         if (ret < 0) {
             radio->g_rds_grp_proc_ps = saved_val;
-            goto END;
+            goto end;
         }
         break;
     case HCI_FM_HELIUM_LP_MODE:
@@ -1117,7 +1311,7 @@
         ret = helium_set_antenna_req(temp_val);
         if (ret < 0) {
             ALOGE("%s:Set Antenna failed retval = %x", LOG_TAG, ret);
-            goto END;
+            goto end;
         }
         radio->g_antenna =  val;
         break;
@@ -1128,7 +1322,7 @@
          if (ret < 0) {
              ALOGE("%s:Error while setting FM soft mute %d", LOG_TAG, ret);
              radio->mute_mode.soft_mute = saved_val;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_FREQ:
@@ -1156,7 +1350,7 @@
         } else {
             ret = -1;
             ALOGE("%s: riva access len is not valid\n", LOG_TAG);
-            goto END;
+            goto end;
         }
         break;
     case HCI_FM_HELIUM_RIVA_PEEK:
@@ -1172,7 +1366,7 @@
          } else {
              ALOGE("%s: riva access len is not valid for poke\n", LOG_TAG);
              ret = -1;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_SSBI_ACCS_ADDR:
@@ -1190,97 +1384,142 @@
          if (!is_valid_sinr_samples(val)) {
              ALOGE("%s: sinr samples count is not valid\n", __func__);
              ret = -1;
-             goto END;
+             goto end;
          }
-         ret = hci_fm_get_ch_det_th();
-         if (ret < 0) {
-             ALOGE("Failed to get chnl det thresholds  %d", ret);
-             goto END;
-         }
-         saved_val = radio->ch_det_threshold.sinr_samples;
          radio->ch_det_threshold.sinr_samples = val;
          ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
          if (ret < 0) {
              ALOGE("Failed to set SINR samples  %d", ret);
-             radio->ch_det_threshold.sinr_samples = saved_val;
-             goto END;
+             goto end;
          }
          break;
     case HCI_FM_HELIUM_SINR_THRESHOLD:
          if (!is_valid_sinr_th(val)) {
-             ALOGE("%s: sinr threshold is not valid\n");
+             ALOGE("%s: sinr threshold is not valid\n", __func__);
              ret = -1;
-             goto END;
+             goto end;
          }
-         ret = hci_fm_get_ch_det_th();
-         if (ret < 0) {
-             ALOGE("Failed to get chnl det thresholds  %d", ret);
-             goto END;
-         }
-         saved_val = radio->ch_det_threshold.sinr;
          radio->ch_det_threshold.sinr = val;
          ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
-         if (ret < 0) {
-             ALOGE("Failed to set SINR threshold %d", ret);
-             radio->ch_det_threshold.sinr = saved_val;
-             goto END;
-         }
          break;
     case HCI_FM_HELIUM_INTF_LOW_THRESHOLD:
          if (!is_valid_intf_det_low_th(val)) {
              ALOGE("%s: intf det low threshold is not valid\n", __func__);
              ret = -1;
-             goto END;
+             goto end;
          }
-         ret = hci_fm_get_ch_det_th();
-         if (ret < 0) {
-             ALOGE("Failed to get chnl det thresholds  %d", ret);
-             goto END;
-         }
-         saved_val = radio->ch_det_threshold.low_th;
          radio->ch_det_threshold.low_th = val;
          ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
-         if (ret < 0) {
-             ALOGE("Failed to Set Low det threshold %d", ret);
-             radio->ch_det_threshold.low_th = saved_val;
-             goto END;
-         }
          break;
     case HCI_FM_HELIUM_INTF_HIGH_THRESHOLD:
          if (!is_valid_intf_det_hgh_th(val)) {
              ALOGE("%s: intf high threshold is not valid\n", __func__);
              ret = -1;
-             goto END;
+             goto end;
          }
-         ret = hci_fm_get_ch_det_th();
-         if (ret < 0) {
-             ALOGE("Failed to get chnl det thresholds  %d", ret);
-             goto END;
-         }
-         saved_val = radio->ch_det_threshold.high_th;
          radio->ch_det_threshold.high_th = val;
          ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
-         if (ret < 0) {
-             ALOGE("Failed to set High det threshold %d ", ret);
-             radio->ch_det_threshold.high_th = saved_val;
-             goto END;
+         break;
+    case HCI_FM_HELIUM_SINRFIRSTSTAGE:
+         def_data_wrt.mode = FM_SRCH_CONFG_MODE;
+         def_data_wrt.length = FM_SRCH_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[SINRFIRSTSTAGE_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_RMSSIFIRSTSTAGE:
+         def_data_wrt.mode = FM_SRCH_CONFG_MODE;
+         def_data_wrt.length = FM_SRCH_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[RMSSIFIRSTSTAGE_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_CF0TH12:
+         def_data_wrt.mode = FM_SRCH_CONFG_MODE;
+         def_data_wrt.length = FM_SRCH_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[CF0TH12_BYTE1_OFFSET] = (val & 0xFF);
+         def_data_wrt.data[CF0TH12_BYTE2_OFFSET] = ((val >> 8) & 0xFF);
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_SRCHALGOTYPE:
+         def_data_wrt.mode = FM_SRCH_CONFG_MODE;
+         def_data_wrt.length = FM_SRCH_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[SRCH_ALGO_TYPE_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_AF_RMSSI_TH:
+         def_data_wrt.mode = FM_AFJUMP_CONFG_MODE;
+         def_data_wrt.length = FM_AFJUMP_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[AF_RMSSI_TH_OFFSET] = (val & 0xFF);
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_GOOD_CH_RMSSI_TH:
+         def_data_wrt.mode = FM_AFJUMP_CONFG_MODE;
+         def_data_wrt.length = FM_AFJUMP_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[GD_CH_RMSSI_TH_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_AF_RMSSI_SAMPLES:
+         def_data_wrt.mode = FM_AFJUMP_CONFG_MODE;
+         def_data_wrt.length = FM_AFJUMP_CNFG_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[AF_RMSSI_SAMPLES_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_RXREPEATCOUNT:
+         def_data_wrt.mode = RDS_PS0_XFR_MODE;
+         def_data_wrt.length = RDS_PS0_LEN;
+         memcpy(&def_data_wrt.data, &radio->def_data.data,
+                 radio->def_data.data_len);
+         def_data_wrt.data[AF_RMSSI_SAMPLES_OFFSET] = val;
+         ret = hci_fm_default_data_write_req(&def_data_wrt);
+         break;
+    case HCI_FM_HELIUM_BLEND_SINRHI:
+         if (!is_valid_blend_value(val)) {
+             ALOGE("%s: sinr samples count is not valid\n", __func__);
+             ret = -1;
+             goto end;
          }
+         radio->blend_tbl.BlendSinrHi = val;
+         ret = hci_fm_set_blend_tbl_req(&radio->blend_tbl);
+         break;
+    case HCI_FM_HELIUM_BLEND_RMSSIHI:
+         if (!is_valid_blend_value(val)) {
+             ALOGE("%s: sinr samples count is not valid\n", __func__);
+             ret = -1;
+             goto end;
+         }
+         radio->blend_tbl.BlendRmssiHi = val;
+         ret = hci_fm_set_blend_tbl_req(&radio->blend_tbl);
          break;
     default:
         ALOGE("%s:%s: Not a valid FM CMD!!", LOG_TAG, __func__);
         ret = 0;
         break;
     }
-END:
+end:
     if (ret < 0)
         ALOGE("%s:%s: %d cmd failed", LOG_TAG, __func__, cmd);
     return ret;
 }
 
-static void get_fm_ctrl(int cmd, int val)
+static int get_fm_ctrl(int cmd, int val)
 {
     int ret = 0;
+    struct hci_fm_def_data_rd_req def_data_rd;
 
+    ALOGE("%s: cmd = 0x%x", __func__, cmd);
     switch(cmd) {
     case HCI_FM_HELIUM_FREQ:
         val = radio->fm_st_rsp.station_rsp.station_freq;
@@ -1292,24 +1531,127 @@
         val = radio->recv_conf.band_low_limit;
         break;
     case HCI_FM_HELIUM_SINR_SAMPLES:
+        set_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_SAMPLE);
         ret = hci_fm_get_ch_det_th();
-         if (ret == 0)
-             val = radio->ch_det_threshold.sinr_samples;
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_SAMPLE);
         break;
     case HCI_FM_HELIUM_SINR_THRESHOLD:
+        set_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_TH);
         ret = hci_fm_get_ch_det_th();
-        if (ret == 0)
-            val = radio->ch_det_threshold.sinr;
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_TH);
         break;
     case HCI_FM_HELIUM_INTF_LOW_THRESHOLD:
+        set_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_LOW);
         ret = hci_fm_get_ch_det_th();
-        if (ret == 0)
-            val = radio->ch_det_threshold.low_th;
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_LOW);
         break;
     case HCI_FM_HELIUM_INTF_HIGH_THRESHOLD:
+        set_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_HIGH);
         ret = hci_fm_get_ch_det_th();
-        if (ret == 0)
-            val = radio->ch_det_threshold.high_th;
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(ch_det_th_mask_flag, CMD_CHDET_INTF_TH_HIGH);
+        break;
+    case HCI_FM_HELIUM_SINRFIRSTSTAGE:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_SINR_FIRST_STAGE);
+        def_data_rd.mode = FM_SRCH_CONFG_MODE;
+        def_data_rd.length = FM_SRCH_CNFG_LEN;
+        goto cmd;
+    case HCI_FM_HELIUM_RMSSIFIRSTSTAGE:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_RMSSI_FIRST_STAGE);
+        def_data_rd.mode = FM_SRCH_CONFG_MODE;
+        def_data_rd.length = FM_SRCH_CNFG_LEN;
+        goto cmd;
+    case HCI_FM_HELIUM_CF0TH12:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_CF0TH12);
+        def_data_rd.mode = FM_SRCH_CONFG_MODE;
+        def_data_rd.length = FM_SRCH_CNFG_LEN;
+        goto cmd;
+    case HCI_FM_HELIUM_SRCHALGOTYPE:
+        def_data_rd.mode = FM_SRCH_CONFG_MODE;
+        def_data_rd.length = FM_SRCH_CNFG_LEN;
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_SEARCH_ALGO);
+        goto cmd;
+    case HCI_FM_HELIUM_AF_RMSSI_TH:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_AF_RMSSI_TH);
+        def_data_rd.mode = FM_AFJUMP_CONFG_MODE;
+        def_data_rd.length = FM_AFJUMP_CNFG_LEN;
+        goto cmd;
+    case HCI_FM_HELIUM_GOOD_CH_RMSSI_TH:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_GD_CH_RMSSI_TH);
+        def_data_rd.mode = FM_AFJUMP_CONFG_MODE;
+        def_data_rd.length = FM_AFJUMP_CNFG_LEN;
+        goto cmd;
+    case HCI_FM_HELIUM_AF_RMSSI_SAMPLES:
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_AF_RMSSI_SAMPLE);
+        def_data_rd.mode = FM_AFJUMP_CONFG_MODE;
+        def_data_rd.length = FM_AFJUMP_CNFG_LEN;
+
+cmd:
+        def_data_rd.param_len = 0;
+        def_data_rd.param = 0;
+
+        ret = hci_fm_default_data_read_req(&def_data_rd);
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_all_bit(def_data_rd_mask_flag);
+        break;
+    case HCI_FM_HELIUM_RXREPEATCOUNT:
+        def_data_rd.mode = RDS_PS0_XFR_MODE;
+        def_data_rd.length = RDS_PS0_LEN;
+        def_data_rd.param_len = 0;
+        def_data_rd.param = 0;
+        set_bit(def_data_rd_mask_flag, CMD_DEFRD_REPEATCOUNT);
+
+        ret = hci_fm_default_data_read_req(&def_data_rd);
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(def_data_rd_mask_flag, CMD_DEFRD_REPEATCOUNT);
+        break;
+    case HCI_FM_HELIUM_BLEND_SINRHI:
+        set_bit(blend_tbl_mask_flag, CMD_BLENDTBL_SINR_HI);
+        ret = hci_fm_get_blend_req();
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(blend_tbl_mask_flag, CMD_BLENDTBL_SINR_HI);
+    case HCI_FM_HELIUM_BLEND_RMSSIHI:
+        set_bit(blend_tbl_mask_flag, CMD_BLENDTBL_RMSSI_HI);
+        ret = hci_fm_get_blend_req();
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(blend_tbl_mask_flag, CMD_BLENDTBL_RMSSI_HI);
+        break;
+    case HCI_FM_HELIUM_IOVERC:
+        set_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_IOVERC);
+        ret = hci_fm_get_station_dbg_param_req();
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_IOVERC);
+        break;
+    case HCI_FM_HELIUM_INTDET:
+        set_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_INFDETOUT);
+        ret = hci_fm_get_station_dbg_param_req();
+        if (ret != FM_HC_STATUS_SUCCESS)
+            clear_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_INFDETOUT);
+        break;
+    case HCI_FM_HELIUM_GET_SINR:
+        if (radio->mode == FM_RECV) {
+            set_bit(station_param_mask_flag, CMD_STNPARAM_SINR);
+            ret = hci_fm_get_station_cmd_param_req();
+            if (ret != FM_HC_STATUS_SUCCESS)
+                clear_bit(station_param_mask_flag, CMD_STNPARAM_SINR);
+        } else {
+            ALOGE("HCI_FM_HELIUM_GET_SINR: radio is not in recv mode");
+            ret = -EINVAL;
+        }
+        break;
+    case HCI_FM_HELIUM_RMSSI:
+        if (radio->mode == FM_RECV) {
+            set_bit(station_param_mask_flag, CMD_STNPARAM_RSSI);
+            ret = hci_fm_get_station_cmd_param_req();
+            if (ret != FM_HC_STATUS_SUCCESS)
+                clear_bit(station_param_mask_flag, CMD_STNPARAM_RSSI);
+        } else if (radio->mode == FM_TRANS) {
+            ALOGE("HCI_FM_HELIUM_RMSSI: radio is not in recv mode");
+            ret = -EINVAL;
+        }
         break;
     default:
         break;
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index df79d75..ea0b3c2 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -47,32 +47,28 @@
     FM_HDR *hdr = (FM_HDR *) malloc(p_len);
     if (!hdr) {
         ALOGE("%s:hdr allocation failed", LOG_TAG);
-        return -1;
+        return -FM_HC_STATUS_NOMEM;
     }
 
-    ALOGE("%s:%s: Sizeof FM_HDR: %d", LOG_TAG, __func__, sizeof(FM_HDR));
-    ALOGE("%s:opcode: %x", LOG_TAG, opcode);
+    ALOGV("%s:opcode: %x", LOG_TAG, opcode);
 
-    hdr->protocol_byte = 0x11;
+    hdr->protocol_byte = RADIO_HCI_COMMAND_PKT;
     hdr->opcode = opcode;
     hdr->plen = len;
     if (len)
         memcpy(hdr->cmd_params, (uint8_t *)param, len);
-    ALOGE("%s:calling transmit", __func__);
-    transmit(hdr);
-    ALOGE("%s:transmit success",__func__);
-    return 0;
+    ret = transmit(hdr);
+    ALOGV("%s:transmit done. status = %d", __func__, ret);
+    return ret;
 }
 
 int hci_fm_get_signal_threshold()
 {
+    uint16_t opcode = 0;
 
-    FM_HDR *hdr = (FM_HDR *) malloc(sizeof(FM_HDR));
-    hdr->protocol_byte = FM_CMD;
-    hdr->opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, HCI_OCF_FM_GET_SIGNAL_THRESHOLD);
-    hdr->plen   = 0;
-    transmit(hdr);
-    return 0;
+    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+            HCI_OCF_FM_GET_SIGNAL_THRESHOLD);
+    return send_fm_cmd_pkt(opcode, 0, NULL);
 }
 
 int hci_fm_enable_recv_req()
@@ -109,7 +105,7 @@
 
    if (s_list == NULL) {
        ALOGE("%s:%s, search list param is null\n", LOG_TAG, __func__);
-       return -1;
+       return -EINVAL;
    }
    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                 HCI_OCF_FM_SEARCH_STATIONS_LIST);
@@ -122,7 +118,7 @@
 
    if (rds_srch == NULL) {
        ALOGE("%s:%s, rds stations param is null\n", LOG_TAG, __func__);
-       return -1;
+       return -EINVAL;
    }
    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                 HCI_OCF_FM_SEARCH_RDS_STATIONS);
@@ -135,7 +131,7 @@
 
    if (srch == NULL) {
        ALOGE("%s:%s, search station param is null\n", LOG_TAG, __func__);
-       return -1;
+       return -EINVAL;
    }
    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                 HCI_OCF_FM_SEARCH_STATIONS);
@@ -157,7 +153,7 @@
 
     if (conf == NULL) {
         ALOGE("%s:%s, recv conf is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                               HCI_OCF_FM_SET_RECV_CONF_REQ);
@@ -198,11 +194,11 @@
 
     if (th == NULL) {
         ALOGE("%s:Threshold value NULL", LOG_TAG);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                                HCI_OCF_FM_SET_SIGNAL_THRESHOLD);
-    return send_fm_cmd_pkt(opcode, sizeof(th), th);
+    return send_fm_cmd_pkt(opcode, sizeof(th), &th);
 }
 
 int helium_rds_grp_mask_req(struct hci_fm_rds_grp_req *rds_grp_msk)
@@ -251,7 +247,7 @@
 
     if (mute == NULL) {
         ALOGE("%s:%s, mute mode is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                                HCI_OCF_FM_SET_MUTE_MODE_REQ);
@@ -263,7 +259,7 @@
     uint16_t opcode = 0;
     int tune_freq = param;
 
-    ALOGE("%s:tune_freq: %d", LOG_TAG, tune_freq);
+    ALOGV("%s:tune_freq: %d", LOG_TAG, tune_freq);
     opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
                                   HCI_OCF_FM_TUNE_STATION_REQ);
     return send_fm_cmd_pkt(opcode, sizeof(tune_freq), &tune_freq);
@@ -277,7 +273,7 @@
 
     if (stereo_mode_req == NULL) {
         ALOGE("%s:%s, stere mode req is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                              HCI_OCF_FM_SET_STEREO_MODE_REQ);
@@ -291,7 +287,7 @@
 
     if (data == NULL) {
         ALOGE("%s:%s, peek data req is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
                 HCI_OCF_FM_PEEK_DATA);
@@ -304,7 +300,7 @@
 
     if (data == NULL) {
         ALOGE("%s:%s, poke data req is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
                 HCI_OCF_FM_POKE_DATA);
@@ -317,7 +313,7 @@
 
     if (data == NULL) {
         ALOGE("%s:%s,SSBI poke data req is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
                 HCI_OCF_FM_SSBI_POKE_REG);
@@ -330,7 +326,7 @@
 
     if (data == NULL) {
         ALOGE("%s:%s,SSBI peek data req is null\n", LOG_TAG, __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
                 HCI_OCF_FM_SSBI_PEEK_REG);
@@ -339,8 +335,9 @@
 
 int hci_fm_get_ch_det_th()
 {
+    ALOGV("%s", __func__);
     uint16_t opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
-			HCI_OCF_FM_GET_CH_DET_THRESHOLD);
+            HCI_OCF_FM_GET_CH_DET_THRESHOLD);
     return send_fm_cmd_pkt(opcode, 0, NULL);
 }
 
@@ -350,9 +347,81 @@
 
     if (ch_det_th == NULL) {
         ALOGE("%s,%s channel det thrshld is null\n", LOG_TAG,  __func__);
-        return -1;
+        return -EINVAL;
     }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                             HCI_OCF_FM_SET_CH_DET_THRESHOLD);
     return send_fm_cmd_pkt(opcode, sizeof((*ch_det_th)), ch_det_th);
 }
+
+int hci_fm_default_data_read_req(struct hci_fm_def_data_rd_req *def_data_rd)
+{
+    uint16_t opcode = 0;
+
+    if (def_data_rd == NULL) {
+        ALOGE("Def data read param is null");
+        return -EINVAL;
+    }
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+            HCI_OCF_FM_DEFAULT_DATA_READ);
+    return send_fm_cmd_pkt(opcode, sizeof(struct hci_fm_def_data_rd_req),
+            def_data_rd);
+}
+
+int hci_fm_get_blend_req()
+{
+    uint16_t opcode = 0;
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+            HCI_OCF_FM_GET_BLND_TBL);
+    return send_fm_cmd_pkt(opcode, 0, NULL);
+}
+
+int hci_fm_set_blend_tbl_req(struct hci_fm_blend_table *blnd_tbl)
+{
+    int opcode = 0;
+
+    if (blnd_tbl == NULL) {
+        ALOGE("Req param is null");
+        return -EINVAL;
+    }
+
+    opcode =  hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+            HCI_OCF_FM_SET_BLND_TBL);
+    return send_fm_cmd_pkt(opcode, sizeof(struct hci_fm_blend_table),
+            blnd_tbl);
+}
+
+int hci_fm_default_data_write_req(struct hci_fm_def_data_wr_req * data_wrt)
+{
+    int opcode = 0;
+
+    if (data_wrt == NULL) {
+        ALOGE("req param is null");
+        return -EINVAL;
+    }
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+            HCI_OCF_FM_DEFAULT_DATA_WRITE);
+    return send_fm_cmd_pkt(opcode, data_wrt->length + sizeof(char) * 2,
+            data_wrt);
+}
+
+int hci_fm_get_station_cmd_param_req()
+{
+    int opcode = 0;
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+            HCI_OCF_FM_GET_STATION_PARAM_REQ);
+    return send_fm_cmd_pkt(opcode, 0,  NULL);
+}
+
+int hci_fm_get_station_dbg_param_req()
+{
+    int opcode = 0;
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+            HCI_OCF_FM_STATION_DBG_PARAM);
+    return send_fm_cmd_pkt(opcode, 0, NULL);
+}