Cleanup of hci layer

Remove unused variables and functions. Synchronized threads on fm
close and make the design modular.

Change-Id: I9bcba9f2b1740b73f52f199ae09c3f08f53499c9
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 30c3d0c..a67c981 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -27,14 +27,11 @@
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __UAPI_RADIO_HCI_CORE_H
-#define __UAPI_RADIO_HCI_CORE_H
-
-#pragma pack(1)
+#ifndef __RADIO_HELIUM_H__
+#define __RADIO_HELIUM_H__
 
 #include <stdbool.h>
 
-pthread_mutex_t fm_hal;
 #define MIN_TX_TONE_VAL  0x00
 #define MAX_TX_TONE_VAL  0x07
 #define MIN_HARD_MUTE_VAL  0x00
@@ -82,11 +79,6 @@
 #define MIN_BLEND_HI  -128
 #define MAX_BLEND_HI  127
 
-
-/* ---- HCI Packet structures ---- */
-#define RADIO_HCI_COMMAND_HDR_SIZE sizeof(struct radio_hci_command_hdr)
-#define RADIO_HCI_EVENT_HDR_SIZE   sizeof(struct radio_hci_event_hdr)
-
 /* HCI data types */
 #define RADIO_HCI_COMMAND_PKT   0x11
 #define RADIO_HCI_EVENT_PKT     0x14
@@ -198,12 +190,12 @@
     ert_cb  ert_update_cb;
     disable_cb  disabled_cb;
     rds_grp_cntrs_cb rds_grp_cntrs_rsp_cb;
-	rds_grp_cntrs_ext_cb rds_grp_cntrs_ext_rsp_cb;
+    rds_grp_cntrs_ext_cb rds_grp_cntrs_ext_rsp_cb;
     fm_peek_cb fm_peek_rsp_cb;
     fm_ssbi_peek_cb fm_ssbi_peek_rsp_cb;
     fm_agc_gain_cb fm_agc_gain_rsp_cb;
     fm_ch_det_th_cb fm_ch_det_th_rsp_cb;
-    fm_ecc_evt_cb	ext_country_code_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;
@@ -214,46 +206,7 @@
     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;
-typedef struct {
-    int (*init)(const fm_vendor_callbacks_t *p_cb);
-    int (*set_fm_ctrl)(int opcode, int val);
-    void (*Get_fm_ctrl) (int opcode, int val);
-} fm_interface_t;
-
-typedef int (*fm_evt_notify_cb)(unsigned char *p_buf);
-
-typedef struct {
-    fm_evt_notify_cb fm_evt_notify;
-} fm_hal_cb;
-
-struct radio_hci_command_hdr {
-    short  opcode; /* OCF & OGF */
-    char   plen;
-} ;
-
-struct radio_hci_event_hdr {
-    char  evt;
-    char  plen;
-} ;
-
-struct radio_hci_dev {
-    char  name[8];
-    unsigned long  flags;
-    short  id;
-    char  bus;
-    char  dev_type;
-    char  dev_name[248];
-    char  dev_class[3];
-    char  features[8];
-    char  commands[64];
-    unsigned int  data_block_len;
-    unsigned long  cmd_last_tx;
-    int  req_status;
-    int  req_result;
-};
+} fm_hal_callbacks_t;
 
 /* Opcode OCF */
 /* HCI recv control commands opcode */
@@ -384,7 +337,6 @@
     int   band_high_limit;
 } ;
 
-
 /* ----- HCI Command request ----- */
 struct hci_fm_tx_ps {
     char   ps_control;
@@ -612,7 +564,7 @@
     char    mute_mode;
     char    sinr;
     char    intf_det_th;
-} ;
+}__attribute__((packed)) ;
 
 struct rds_blk_data {
     char  rdsMsb;
@@ -653,25 +605,25 @@
     short   pi_code;
     char    af_size;
     char    af_list[FM_AF_LIST_MAX_SIZE];
-} ;
+} __attribute__((packed)) ;
 
 struct hci_ev_cmd_complete {
     char    num_hci_cmd_pkts;
     short   cmd_opcode;
-} ;
+} __attribute((packed));
 
 struct hci_ev_cmd_status {
     char    status;
     char    num_hci_cmd_pkts;
     short   status_opcode;
-} ;
+} __attribute__((packed));
 
 struct hci_ev_srch_st {
     int    station_freq;
     char    rds_cap;
     char   pty;
     short   status_opcode;
-} ;
+} __attribute__((packed));
 
 struct hci_ev_rel_freq {
     char  rel_freq_msb;
@@ -687,18 +639,19 @@
 struct hci_fm_conf_rsp {
     char    status;
     struct hci_fm_recv_conf_req recv_conf_rsp;
-} ;
+} __attribute__((packed));
 
 struct hci_fm_rds_grp_cntrs_rsp {
     char    status;
     struct hci_fm_rds_grp_cntrs_params recv_rds_grp_cntrs_rsp;
-} ;
+} __attribute__((packed));
 
 
 struct hci_fm_get_trans_conf_rsp {
     char    status;
     struct hci_fm_trans_conf_req_struct trans_conf_rsp;
-} ;
+} __attribute__((packed));
+
 struct hci_fm_sig_threshold_rsp {
     char    status;
     char    sig_threshold;
@@ -711,17 +664,17 @@
 struct hci_fm_prgm_srv_rsp {
     char    status;
     struct hci_ev_prg_service prg_srv;
-} ;
+} __attribute__((packed));
 
 struct hci_fm_radio_txt_rsp {
     char    status;
     struct hci_ev_radio_text rd_txt;
-} ;
+} __attribute__((packed));
 
 struct hci_fm_af_list_rsp {
     char    status;
     struct hci_ev_af_list rd_txt;
-} ;
+} __attribute__((packed));
 
 struct hci_fm_data_rd_rsp {
     char    data_len;
@@ -763,8 +716,7 @@
     int   freq[MAX_SPUR_FREQ_LIMIT];
     char  rmssi[MAX_SPUR_FREQ_LIMIT];
     char  enable[MAX_SPUR_FREQ_LIMIT];
-} ;
-
+} __attribute__((packed));
 
 /* HCI dev events */
 #define RADIO_HCI_DEV_REG           1
@@ -961,7 +913,6 @@
 int hci_def_data_write(struct hci_fm_def_data_wr_req *arg,
        struct radio_hci_dev *hdev);
 int hci_fm_do_calibration(char *arg, struct radio_hci_dev *hdev);
-int hci_fm_do_calibration(char *arg, struct radio_hci_dev *hdev);
 
 static inline int is_valid_tone(int tone)
 {
@@ -1177,7 +1128,7 @@
         return 0;
 }
 
-struct helium_device {
+struct radio_helium_device {
     int tune_req;
     unsigned int mode;
     short pi;
@@ -1212,7 +1163,7 @@
     struct hci_fm_ch_det_threshold ch_det_threshold;
     struct hci_fm_data_rd_rsp def_data;
     struct hci_fm_blend_table blend_tbl;
-};
+} __attribute__((packed));
 
 #define set_bit(flag, bit_pos)      ((flag) |= (1 << (bit_pos)))
 #define clear_bit(flag, bit_pos)    ((flag) &= (~(1 << (bit_pos))))
@@ -1281,4 +1232,17 @@
 int hci_fm_get_station_dbg_param_req();
 int hci_fm_get_station_cmd_param_req();
 
+struct fm_hal_t {
+    struct radio_helium_device *radio;
+    fm_hal_callbacks_t *jni_cb;
+    void *private_data;
+};
+
+struct fm_interface_t {
+    int (*init)(const fm_hal_callbacks_t *p_cb);
+    int (*set_fm_ctrl)(int opcode, int val);
+    void (*Get_fm_ctrl) (int opcode, int val);
+};
+
 #endif /* __UAPI_RADIO_HCI_CORE_H */
+
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index e6ab1b1..f22c6f5 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -34,15 +34,13 @@
 #include <utils/Log.h>
 #include "radio-helium-commands.h"
 #include "radio-helium.h"
-#include "fm_hci.h"
+#include "fm_hci_api.h"
 #include <dlfcn.h>
 #include <errno.h>
 
-fm_vendor_callbacks_t *jni_cb;
 int hci_fm_get_signal_threshold();
 int hci_fm_enable_recv_req();
 int hci_fm_mute_mode_req(struct hci_fm_mute_mode_req );
-struct helium_device *radio;
 static int oda_agt;
 static int grp_mask;
 static int rt_plus_carrier = -1;
@@ -59,6 +57,7 @@
 static uint32_t station_param_mask_flag;
 static uint32_t station_dbg_param_mask_flag;
 uint64_t flag;
+struct fm_hal_t *hal = NULL;
 
 #define LOG_TAG "radio_helium"
 static void radio_hci_req_complete(char result)
@@ -80,11 +79,11 @@
         return;
     }
     rsp = (struct hci_fm_conf_rsp *)ev_rsp;
-    jni_cb->thread_evt_cb(0);
+    hal->jni_cb->thread_evt_cb(0);
     radio_hci_req_complete(rsp->status);
-    jni_cb->enabled_cb();
+    hal->jni_cb->enabled_cb();
     if (rsp->status == FM_HC_STATUS_SUCCESS)
-        radio->mode = FM_RECV;
+        hal->radio->mode = FM_RECV;
 }
 
 static void hci_cc_conf_rsp(char *ev_rsp)
@@ -98,7 +97,7 @@
     rsp = (struct hci_fm_conf_rsp *)ev_rsp;
     radio_hci_req_complete(rsp->status);
     if (!rsp->status) {
-        radio->recv_conf = rsp->recv_conf_rsp;
+        hal->radio->recv_conf = rsp->recv_conf_rsp;
     }
 }
 
@@ -111,19 +110,15 @@
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
         return;
     }
-    ALOGE("%s:enetred %s calling ", LOG_TAG, __func__);
+    ALOGV("%s++", __func__);
     status = (char) *ev_buff;
     radio_hci_req_complete(status);
-    if (radio->mode == FM_TURNING_OFF) {
-        radio->mode = FM_OFF;
-        jni_cb->disabled_cb();
-        jni_cb->thread_evt_cb(1);
-        //close the userial port and power off the chip
-        ret = fm_power(FM_RADIO_DISABLE);
-        ALOGI("fm power off status = %d", ret);
-        ALOGI("%s:calling fm userial close\n", LOG_TAG );
-        fm_userial_close();
-    //  fm_power(FM_RADIO_DISABLE);
+    if (hal->radio->mode == FM_TURNING_OFF) {
+        ALOGD("%s:calling fm close\n", LOG_TAG );
+        fm_hci_close(hal->private_data);
+        hal->radio->mode = FM_OFF;
+        hal->jni_cb->disabled_cb();
+        hal->jni_cb->thread_evt_cb(1);
     }
 }
 
@@ -152,7 +147,7 @@
     if (status < 0) {
         ALOGE("%s:%s, read rds_grp_cntrs failed status=%d\n", LOG_TAG, __func__,status);
     }
-    jni_cb->rds_grp_cntrs_rsp_cb(&ev_buff[1]);
+    hal->jni_cb->rds_grp_cntrs_rsp_cb(&ev_buff[1]);
 }
 
 static void hci_cc_rds_grp_cntrs_ext_rsp(char *ev_buff)
@@ -168,7 +163,7 @@
     if (status < 0) {
         ALOGE("%s:%s, read rds_grp_cntrs_ext failed status=%d\n", LOG_TAG, __func__,status);
     }
-    jni_cb->rds_grp_cntrs_ext_rsp_cb(&ev_buff[1]);
+    hal->jni_cb->rds_grp_cntrs_ext_rsp_cb(&ev_buff[1]);
 }
 
 static void hci_cc_riva_peek_rsp(char *ev_buff)
@@ -184,7 +179,7 @@
     if (status < 0) {
         ALOGE("%s:%s, peek failed=%d\n", LOG_TAG, __func__, status);
     }
-    jni_cb->fm_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
+    hal->jni_cb->fm_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
     radio_hci_req_complete(status);
 }
 
@@ -201,7 +196,7 @@
     if (status < 0) {
         ALOGE("%s:%s,ssbi peek failed=%d\n", LOG_TAG, __func__, status);
     }
-    jni_cb->fm_ssbi_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
+    hal->jni_cb->fm_ssbi_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
     radio_hci_req_complete(status);
 }
 
@@ -218,7 +213,7 @@
     if (status != 0) {
         ALOGE("%s:%s,agc gain failed=%d\n", LOG_TAG, __func__, status);
     } else {
-        jni_cb->fm_agc_gain_rsp_cb(&ev_buff[1]);
+        hal->jni_cb->fm_agc_gain_rsp_cb(&ev_buff[1]);
     }
     radio_hci_req_complete(status);
 }
@@ -236,28 +231,28 @@
     if (status != 0) {
         ALOGE("%s:%s,ssbi peek failed=%d\n", LOG_TAG, __func__, status);
     } else {
-        memcpy(&radio->ch_det_threshold, &ev_buff[1],
+        memcpy(&hal->radio->ch_det_threshold, &ev_buff[1],
                         sizeof(struct hci_fm_ch_det_threshold));
         radio_hci_req_complete(status);
 
         if (test_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_TH))
-            val = radio->ch_det_threshold.sinr;
+            val = hal->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;
+            val = hal->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;
+            val = hal->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;
+            val = hal->radio->ch_det_threshold.high_th;
     }
     clear_all_bit(ch_det_th_mask_flag);
-    jni_cb->fm_get_ch_det_thr_cb(val, status);
+    hal->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);
+    hal->jni_cb->fm_set_ch_det_thr_cb(status);
 }
 
 static void hci_cc_sig_threshold_rsp(char *ev_buff)
@@ -272,7 +267,7 @@
     } else {
         val = ev_buff[1];
     }
-    jni_cb->fm_get_sig_thres_cb(val, status);
+    hal->jni_cb->fm_get_sig_thres_cb(val, status);
 }
 
 static void hci_cc_default_data_read_rsp(char *ev_buff)
@@ -287,43 +282,43 @@
     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));
+        memcpy(&hal->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];
+            val = hal->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];
+            val = hal->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];
+            val = hal->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];
+            val = hal->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];
+            val = hal->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];
+            val = hal->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));
+            val = (hal->radio->def_data.data[CF0TH12_BYTE1_OFFSET] |
+                    (hal->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];
+            val = hal->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);
+    hal->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);
+    hal->jni_cb->fm_def_data_write_cb(status);
 }
 
 static void hci_cc_get_blend_tbl_rsp(char *ev_buff)
@@ -339,7 +334,7 @@
     if (status != 0) {
         ALOGE("%s: status = 0x%x", LOG_TAG, status);
     } else {
-        memcpy(&radio->blend_tbl, &ev_buff[1],
+        memcpy(&hal->radio->blend_tbl, &ev_buff[1],
                 sizeof(struct hci_fm_blend_table));
 
         ALOGE("hci_cc_get_blend_tbl_rsp: data");
@@ -347,20 +342,20 @@
         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;
+            val = hal->radio->blend_tbl.BlendSinrHi;
         } else if (test_bit(blend_tbl_mask_flag, CMD_BLENDTBL_RMSSI_HI)) {
-            val = radio->blend_tbl.BlendRmssiHi;
+            val = hal->radio->blend_tbl.BlendRmssiHi;
         }
     }
     clear_all_bit(blend_tbl_mask_flag);
-    jni_cb->fm_get_blend_cb(val, status);
+    hal->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);
+    hal->jni_cb->fm_set_blend_cb(status);
 }
 
 static void hci_cc_station_rsp(char *ev_buff)
@@ -368,17 +363,17 @@
     int val, status = ev_buff[0];
 
     if (status == FM_HC_STATUS_SUCCESS) {
-        memcpy(&radio->fm_st_rsp.station_rsp.station_freq, &ev_buff[1],
+        memcpy(&hal->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;
+                val = hal->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;
+            val = hal->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);
+    hal->jni_cb->fm_get_station_param_cb(val, status);
     clear_all_bit(station_param_mask_flag);
 }
 
@@ -387,16 +382,16 @@
     int val, status = ev_buff[0];
 
     if (status == FM_HC_STATUS_SUCCESS) {
-        memcpy(&radio->st_dbg_param, &ev_buff[1],
+        memcpy(&hal->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;
+            val = hal->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;
+            val = hal->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);
+    hal->jni_cb->fm_get_station_debug_param_cb(val, status);
     clear_all_bit(station_dbg_param_mask_flag);
 }
 
@@ -549,27 +544,29 @@
 static inline void hci_ev_tune_status(char *buff)
 {
 
-    memcpy(&radio->fm_st_rsp.station_rsp, &buff[0],
+    memcpy(&hal->radio->fm_st_rsp.station_rsp, &buff[0],
                                sizeof(struct hci_ev_tune_status));
-    jni_cb->tune_cb(radio->fm_st_rsp.station_rsp.station_freq);
+    char *freq = &hal->radio->fm_st_rsp.station_rsp.station_freq;
+    ALOGD("freq = %d", hal->radio->fm_st_rsp.station_rsp.station_freq);
+    hal->jni_cb->tune_cb(hal->radio->fm_st_rsp.station_rsp.station_freq);
 
-    //    if (radio->fm_st_rsp.station_rsp.serv_avble)
+    //    if (hal->radio->fm_st_rsp.station_rsp.serv_avble)
           // todo callback for threshould
 
-    if (radio->fm_st_rsp.station_rsp.stereo_prg)
-        jni_cb->stereo_status_cb(true);
-    else if (radio->fm_st_rsp.station_rsp.stereo_prg == 0)
-        jni_cb->stereo_status_cb(false);
+    if (hal->radio->fm_st_rsp.station_rsp.stereo_prg)
+        hal->jni_cb->stereo_status_cb(true);
+    else if (hal->radio->fm_st_rsp.station_rsp.stereo_prg == 0)
+        hal->jni_cb->stereo_status_cb(false);
 
-    if (radio->fm_st_rsp.station_rsp.rds_sync_status)
-        jni_cb->rds_avail_status_cb(true);
+    if (hal->radio->fm_st_rsp.station_rsp.rds_sync_status)
+        hal->jni_cb->rds_avail_status_cb(true);
     else
-        jni_cb->rds_avail_status_cb(false);
+        hal->jni_cb->rds_avail_status_cb(false);
 }
 
 static inline void hci_ev_search_next(char *buff)
 {
-    jni_cb->scan_next_cb();
+    hal->jni_cb->scan_next_cb();
 }
 
 static inline void hci_ev_stereo_status(char *buff)
@@ -582,9 +579,9 @@
     }
     st_status =  buff[0];
     if (st_status)
-        jni_cb->stereo_status_cb(true);
+        hal->jni_cb->stereo_status_cb(true);
     else
-        jni_cb->stereo_status_cb(false);
+        hal->jni_cb->stereo_status_cb(false);
 }
 
 static void hci_ev_rds_lock_status(char *buff)
@@ -599,9 +596,9 @@
     rds_status = buff[0];
 
     if (rds_status)
-        jni_cb->rds_avail_status_cb(true);
+        hal->jni_cb->rds_avail_status_cb(true);
     else
-        jni_cb->rds_avail_status_cb(false);
+        hal->jni_cb->rds_avail_status_cb(false);
 }
 
 static inline void hci_ev_program_service(char *buff)
@@ -625,7 +622,7 @@
     memcpy(data+RDS_OFFSET, &buff[RDS_PS_DATA_OFFSET], len-RDS_OFFSET);
 
     ALOGE("SSK call ps-callback");
-    jni_cb->ps_update_cb(data);
+    hal->jni_cb->ps_update_cb(data);
 
     free(data);
 }
@@ -658,7 +655,7 @@
     memcpy(data+RDS_OFFSET, &buff[RDS_OFFSET], len);
     data[len+RDS_OFFSET] = 0x00;
 
-    jni_cb->rt_update_cb(data);
+    hal->jni_cb->rt_update_cb(data);
     free(data);
 }
 
@@ -679,7 +676,7 @@
     }
     memcpy(&ev.af_list[0], &buff[AF_LIST_OFFSET],
                                         ev.af_size * sizeof(int));
-    jni_cb->af_list_update_cb(&ev);
+    hal->jni_cb->af_list_update_cb(&ev);
 }
 
 static inline void hci_ev_search_compl(char *buff)
@@ -688,8 +685,8 @@
         ALOGE("%s:%s,buffer is null\n", LOG_TAG, __func__);
         return;
     }
-    radio->search_on = 0;
-    jni_cb->seek_cmpl_cb(radio->fm_st_rsp.station_rsp.station_freq);
+    hal->radio->search_on = 0;
+    hal->jni_cb->seek_cmpl_cb(hal->radio->fm_st_rsp.station_rsp.station_freq);
 }
 
 static inline void hci_ev_srch_st_list_compl(char *buff)
@@ -720,7 +717,7 @@
             cnt += PARAMS_PER_STATION, stn_num++) {
 
         abs_freq = *((int *)&buff[cnt]);
-        rel_freq = abs_freq - radio->recv_conf.band_low_limit;
+        rel_freq = abs_freq - hal->radio->recv_conf.band_low_limit;
         rel_freq = (rel_freq * 20) / KHZ_TO_MHZ;
 
         ev->rel_freq[stn_num].rel_freq_lsb = GET_LSB(rel_freq);
@@ -728,7 +725,7 @@
     }
 
     len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
-    jni_cb->srch_list_cb((char*)ev);
+    hal->jni_cb->srch_list_cb((char*)ev);
     free(ev);
 }
 
@@ -772,7 +769,7 @@
         data[4] = buff[3];
         memcpy(&data[RDS_OFFSET], &buff[4], len-RDS_OFFSET);
         // data[len] = 0x00;
-        jni_cb->rt_plus_update_cb(data);
+        hal->jni_cb->rt_plus_update_cb(data);
         free(data);
      } else {
         ALOGE("%s:memory allocation failed\n", LOG_TAG);
@@ -793,8 +790,7 @@
         data[3] = buff[RDS_PID_HIGHER];
         data[4] = buff[3];
         memcpy(&data[RDS_OFFSET], &buff[4], len-RDS_OFFSET);
-        // data[len] = 0x00;
-        jni_cb->ext_country_code_cb(data);
+        hal->jni_cb->ext_country_code_cb(data);
         free(data);
     } else {
         ALOGE("%s:memory allocation failed\n", LOG_TAG);
@@ -813,7 +809,7 @@
         data[1] = utf_8_flag;
         data[2] = formatting_dir;
         memcpy((data + 3), ert_buf, ert_len);
-        jni_cb->ert_update_cb(data);
+        hal->jni_cb->ert_update_cb(data);
         free(data);
     }
 }
@@ -821,9 +817,9 @@
 static void hci_ev_hw_error(char *buff)
 {
    ALOGE("%s:%s: start", LOG_TAG, __func__);
-   jni_cb->disabled_cb();
-   jni_cb->thread_evt_cb(1);
-   fm_userial_close();
+   fm_hci_close(hal->private_data);
+   hal->jni_cb->disabled_cb();
+   hal->jni_cb->thread_evt_cb(1);
 }
 
 static void hci_buff_ert(struct rds_grp_data *rds_buf)
@@ -917,7 +913,7 @@
              formatting_dir = EXTRACT_BIT(temp.rdsBlk[2].rdsLsb,
                                                ERT_FORMAT_DIR_BIT);
              if (ert_carrier != agt)
-                 jni_cb->oda_update_cb();
+                 hal->jni_cb->oda_update_cb();
              ert_carrier = agt;
              break;
         case RT_PLUS_AID:
@@ -935,7 +931,7 @@
              rt_ert_flag = EXTRACT_BIT(temp.rdsBlk[2].rdsMsb,
                                               RT_ERT_FLAG_BIT);
              if (rt_plus_carrier != agt)
-                 jni_cb->oda_update_cb();
+                 hal->jni_cb->oda_update_cb();
              rt_plus_carrier = agt;
              break;
         default:
@@ -959,65 +955,65 @@
     char evt;
 
     ALOGE("%s:%s: Received %d bytes of HCI EVENT PKT from Controller", LOG_TAG,
-                                      __func__, ((FM_EVT_HDR *)evt_buf)->evt_len);
-    evt = ((FM_EVT_HDR *)evt_buf)->evt_code;
+                                      __func__, ((struct fm_event_header_t *)evt_buf)->evt_len);
+    evt = ((struct fm_event_header_t *)evt_buf)->evt_code;
     ALOGE("%s:evt: %d", LOG_TAG, evt);
 
     switch(evt) {
     case HCI_EV_TUNE_STATUS:
-        hci_ev_tune_status(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_tune_status(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_SEARCH_PROGRESS:
     case HCI_EV_SEARCH_RDS_PROGRESS:
     case HCI_EV_SEARCH_LIST_PROGRESS:
-        hci_ev_search_next(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_search_next(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_STEREO_STATUS:
-        hci_ev_stereo_status(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_stereo_status(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_RDS_LOCK_STATUS:
-        hci_ev_rds_lock_status(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_rds_lock_status(((struct fm_event_header_t *)evt_buf)->params);
         break;
 /*    case HCI_EV_SERVICE_AVAILABLE:
         hci_ev_service_available(hdev, skb);
         break; */
     case HCI_EV_RDS_RX_DATA:
-        hci_ev_raw_rds_group_data(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_raw_rds_group_data(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_PROGRAM_SERVICE:
-        hci_ev_program_service(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_program_service(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_RADIO_TEXT:
-        hci_ev_radio_text(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_radio_text(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_FM_AF_LIST:
-        hci_ev_af_list(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_af_list(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_CMD_COMPLETE:
         ALOGE("%s:%s: Received HCI_EV_CMD_COMPLETE", LOG_TAG, __func__);
-        hci_cmd_complete_event(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_cmd_complete_event(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_CMD_STATUS:
-        hci_cmd_status_event(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_cmd_status_event(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_SEARCH_COMPLETE:
     case HCI_EV_SEARCH_RDS_COMPLETE:
-        hci_ev_search_compl(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_search_compl(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_SEARCH_LIST_COMPLETE:
-        hci_ev_srch_st_list_compl(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_srch_st_list_compl(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_RADIO_TEXT_PLUS_ID:
-        hci_ev_rt_plus_id(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_rt_plus_id(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_RADIO_TEXT_PLUS_TAG:
-        hci_ev_rt_plus_tag(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_rt_plus_tag(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_EXT_COUNTRY_CODE:
-        hci_ev_ext_country_code(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_ext_country_code(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_HW_ERR_EVENT:
-        hci_ev_hw_error(((FM_EVT_HDR *)evt_buf)->cmd_params);
+        hci_ev_hw_error(((struct fm_event_header_t *)evt_buf)->params);
         break;
     default:
         break;
@@ -1025,10 +1021,10 @@
 }
 
 /* 'evt_buf' contains the event received from Controller */
-int fm_evt_notify(char *evt_buf)
+int process_event(void *hal, unsigned char *evt_buf)
 {
     ALOGI("%s: %s: Received event notification from FM-HCI thread. EVT CODE: %d ",
-                            LOG_TAG,  __func__, ((FM_EVT_HDR *)evt_buf)->evt_code);
+                            LOG_TAG,  __func__, ((struct fm_event_header_t *)evt_buf)->evt_code);
     radio_hci_event_packet(evt_buf);
     return 0;
 }
@@ -1040,9 +1036,9 @@
     int saved_val;
     int dir;
 
-    srch = radio->g_search_mode & SRCH_MODE;
-    saved_val = radio->search_on;
-    radio->search_on = on;
+    srch = hal->radio->g_search_mode & SRCH_MODE;
+    saved_val = hal->radio->search_on;
+    hal->radio->search_on = on;
     if (direct)
         dir = SRCH_DIR_UP;
     else
@@ -1052,24 +1048,24 @@
         switch (srch) {
         case SCAN_FOR_STRONG:
         case SCAN_FOR_WEAK:
-            radio->srch_st_list.srch_list_dir = dir;
-            radio->srch_st_list.srch_list_mode = srch;
-            retval = helium_search_list(&radio->srch_st_list);
+            hal->radio->srch_st_list.srch_list_dir = dir;
+            hal->radio->srch_st_list.srch_list_mode = srch;
+            retval = helium_search_list(&hal->radio->srch_st_list);
             break;
         case RDS_SEEK_PTY:
         case RDS_SCAN_PTY:
         case RDS_SEEK_PI:
             srch = srch - SEARCH_RDS_STNS_MODE_OFFSET;
-            radio->srch_rds.srch_station.srch_mode = srch;
-            radio->srch_rds.srch_station.srch_dir = dir;
-            radio->srch_rds.srch_station.scan_time = radio->g_scan_time;
-            retval = helium_search_rds_stations(&radio->srch_rds);
+            hal->radio->srch_rds.srch_station.srch_mode = srch;
+            hal->radio->srch_rds.srch_station.srch_dir = dir;
+            hal->radio->srch_rds.srch_station.scan_time = hal->radio->g_scan_time;
+            retval = helium_search_rds_stations(&hal->radio->srch_rds);
             break;
         default:
-            radio->srch_st.srch_mode = srch;
-            radio->srch_st.scan_time = radio->g_scan_time;
-            radio->srch_st.srch_dir = dir;
-            retval = helium_search_stations(&radio->srch_st);
+            hal->radio->srch_st.srch_mode = srch;
+            hal->radio->srch_st.scan_time = hal->radio->g_scan_time;
+            hal->radio->srch_st.srch_dir = dir;
+            retval = helium_search_stations(&hal->radio->srch_st);
             break;
         }
     } else {
@@ -1077,7 +1073,7 @@
     }
 
     if (retval < 0)
-        radio->search_on = saved_val;
+        hal->radio->search_on = saved_val;
     return retval;
 }
 
@@ -1086,12 +1082,12 @@
     int retval;
     int saved_val;
 
-    saved_val = radio->region;
-    radio->region = req_region;
+    saved_val = hal->radio->region;
+    hal->radio->region = req_region;
 
-    retval = hci_fm_set_recv_conf_req(&radio->recv_conf);
+    retval = hci_fm_set_recv_conf_req(&hal->radio->recv_conf);
     if (retval < 0)
-        radio->region = saved_val;
+        hal->radio->region = saved_val;
     return retval;
 }
 
@@ -1100,10 +1096,10 @@
     int rds_grps_proc = 0x00;
     int retval = 0;
 
-    if (radio->power_mode != lp_mode) {
+    if (hal->radio->power_mode != lp_mode) {
        if (lp_mode) {
-           radio->event_mask = 0x00;
-           if (radio->af_jump_bit)
+           hal->radio->event_mask = 0x00;
+           if (hal->radio->af_jump_bit)
                rds_grps_proc = 0x00 | AF_JUMP_ENABLE;
            else
                rds_grps_proc = 0x00;
@@ -1112,52 +1108,78 @@
                ALOGE("%s:Disable RDS failed", LOG_TAG);
                return retval;
            }
-           retval = helium_set_event_mask_req(radio->event_mask);
+           retval = helium_set_event_mask_req(hal->radio->event_mask);
        } else {
-           radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
-           retval = helium_set_event_mask_req(radio->event_mask);
+           hal->radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+           retval = helium_set_event_mask_req(hal->radio->event_mask);
            if (retval < 0) {
                ALOGE("%s:Enable Async events failed", LOG_TAG);
                return retval;
            }
-           radio->g_rds_grp_proc_ps = 0x000000FF;
-           retval = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
+           hal->radio->g_rds_grp_proc_ps = 0x000000FF;
+           retval = helium_rds_grp_process_req(hal->radio->g_rds_grp_proc_ps);
        }
-       radio->power_mode = lp_mode;
+       hal->radio->power_mode = lp_mode;
     }
     return retval;
 }
 
 
 /* Callback function to be registered with FM-HCI for event notification */
-static fm_hal_cb hal_cb = {
-    fm_evt_notify
+static struct fm_hci_callbacks_t hal_cb = {
+    process_event
 };
 
-int hal_init( fm_vendor_callbacks_t *p_cb)
+int hal_init(fm_hal_callbacks_t *cb)
 {
-    int ret = -1;
+    int ret = -FM_HC_STATUS_FAIL;
+    fm_hci_hal_t hci_hal;
 
-     radio = malloc(sizeof(struct helium_device));
-     if (!radio) {
-         ALOGE("%s:Failed to allocate memory for device", LOG_TAG);
-         return ret;
-     }
-    /* Save the JNI callback functions */
-    jni_cb = p_cb;
+    ALOGD("++%s", __func__);
+
+    memset(&hci_hal, 0, sizeof(fm_hci_hal_t));
+
+    hal = malloc(sizeof(struct fm_hal_t));
+    if (!hal) {
+        ALOGE("%s:Failed to allocate memory", __func__);
+        ret = -FM_HC_STATUS_NOMEM;
+        goto out;
+    }
+    memset(hal, 0, sizeof(struct fm_hal_t));
+    hal->jni_cb = cb;
+    hal->radio = malloc(sizeof(struct radio_helium_device));
+    if (!hal->radio) {
+        ALOGE("%s:Failed to allocate memory for device", __func__);
+        goto out;
+    }
+
+    memset(hal->radio, 0,  sizeof(struct radio_helium_device));
+
+    hci_hal.hal = hal;
+    hci_hal.cb = &hal_cb;
 
     /* Initialize the FM-HCI */
-    ALOGE("%s:%s: Initializing the event notification func with FM-HCI", LOG_TAG, __func__);
-    ret = fm_hci_init(&hal_cb);
+    ret = fm_hci_init(&hci_hal);
+    if (ret != FM_HC_STATUS_SUCCESS) {
+        ALOGE("%s:fm_hci_init failed", __func__);
+        goto out;
+    }
+    hal->private_data = hci_hal.hci;
 
-    ALOGE("%s:%s: Turning FM ON...", LOG_TAG, __func__);
-    ret = fm_power(FM_RADIO_ENABLE);
+    return FM_HC_STATUS_SUCCESS;
 
-    ALOGE("%s:%s: Firmware download and HCI Initialization in-progress...", LOG_TAG, __func__);
-    /* TODO : Start the preload timer */
-    open_serial_port();
-    pthread_mutex_init(&fm_hal, NULL);
-    return 0;
+out:
+    ALOGV("--%s", __func__);
+    if (hal) {
+        if (hal->radio) {
+            free(hal->radio);
+            hal->radio = NULL;
+        }
+        hal->jni_cb = NULL;
+        free(hal);
+        hal = NULL;
+    }
+    return ret;
 }
 
 /* Called by the JNI for performing the FM operations */
@@ -1170,27 +1192,31 @@
     char *data;
     struct hci_fm_def_data_wr_req def_data_wrt;
 
-    ALOGE("%s:cmd: %x, val: %d",LOG_TAG, cmd, val);
+    if (!hal) {
+        ALOGE("%s:ALERT: command sent before hal init", __func__);
+        return -FM_HC_STATUS_FAIL;
+    }
+    ALOGD("%s:cmd: %x, val: %d",LOG_TAG, cmd, val);
 
     switch (cmd) {
     case HCI_FM_HELIUM_AUDIO_MUTE:
-        saved_val = radio->mute_mode.hard_mute;
-        radio->mute_mode.hard_mute = val;
-        ret = hci_fm_mute_mode_req(radio->mute_mode);
+        saved_val = hal->radio->mute_mode.hard_mute;
+        hal->radio->mute_mode.hard_mute = val;
+        ret = hci_fm_mute_mode_req(hal->radio->mute_mode);
         if (ret < 0) {
             ALOGE("%s:Error while set FM hard mute %d", LOG_TAG, ret);
-            radio->mute_mode.hard_mute = saved_val;
+            hal->radio->mute_mode.hard_mute = saved_val;
         }
         break;
     case HCI_FM_HELIUM_SRCHMODE:
         if (is_valid_srch_mode(val))
-            radio->g_search_mode = val;
+            hal->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;
+            hal->radio->g_scan_time = val;
         else
             ret = -EINVAL;
         break;
@@ -1203,7 +1229,7 @@
             ret = hci_fm_enable_recv_req();
             break;
         case FM_OFF:
-            radio->mode = FM_TURNING_OFF;
+            hal->radio->mode = FM_TURNING_OFF;
             hci_fm_disable_recv_req();
             break;
         default:
@@ -1223,84 +1249,84 @@
         break;
     case HCI_FM_HELIUM_SRCH_PTY:
         if (is_valid_pty(val)) {
-            radio->srch_rds.srch_pty = val;
-            radio->srch_st_list.srch_pty = val;
+            hal->radio->srch_rds.srch_pty = val;
+            hal->radio->srch_st_list.srch_pty = val;
         } else {
             ret = -EINVAL;
         }
          break;
     case HCI_FM_HELIUM_SRCH_PI:
          if (is_valid_pi(val))
-             radio->srch_rds.srch_pi = val;
+             hal->radio->srch_rds.srch_pi = val;
          else
              ret = -EINVAL;
          break;
     case HCI_FM_HELIUM_SRCH_CNT:
          if (is_valid_srch_station_cnt(val))
-             radio->srch_st_list.srch_list_max = val;
+             hal->radio->srch_st_list.srch_list_max = val;
          else
              ret = -EINVAL;
          break;
     case HCI_FM_HELIUM_SPACING:
-         saved_val = radio->recv_conf.ch_spacing;
-         radio->recv_conf.ch_spacing = val;
-         ret = hci_fm_set_recv_conf_req(&radio->recv_conf);
+         saved_val = hal->radio->recv_conf.ch_spacing;
+         hal->radio->recv_conf.ch_spacing = val;
+         ret = hci_fm_set_recv_conf_req(&hal->radio->recv_conf);
          if (ret < 0) {
              ALOGE("%s:Error in setting channel spacing", LOG_TAG);
-             radio->recv_conf.ch_spacing = saved_val;
+             hal->radio->recv_conf.ch_spacing = saved_val;
              goto end;
         }
         break;
     case HCI_FM_HELIUM_EMPHASIS:
-         saved_val = radio->recv_conf.emphasis;
-         radio->recv_conf.emphasis = val;
-         ret = hci_fm_set_recv_conf_req(&radio->recv_conf);
+         saved_val = hal->radio->recv_conf.emphasis;
+         hal->radio->recv_conf.emphasis = val;
+         ret = hci_fm_set_recv_conf_req(&hal->radio->recv_conf);
          if (ret < 0) {
              ALOGE("%s:Error in setting emphasis", LOG_TAG);
-             radio->recv_conf.emphasis = saved_val;
+             hal->radio->recv_conf.emphasis = saved_val;
              goto end;
          }
          break;
     case HCI_FM_HELIUM_RDS_STD:
-         saved_val = radio->recv_conf.rds_std;
-         radio->recv_conf.rds_std = val;
-         ret = hci_fm_set_recv_conf_req(&radio->recv_conf);
+         saved_val = hal->radio->recv_conf.rds_std;
+         hal->radio->recv_conf.rds_std = val;
+         ret = hci_fm_set_recv_conf_req(&hal->radio->recv_conf);
          if (ret < 0) {
              ALOGE("%s:Error in rds_std", LOG_TAG);
-             radio->recv_conf.rds_std = saved_val;
+             hal->radio->recv_conf.rds_std = saved_val;
              goto end;
          }
          break;
     case HCI_FM_HELIUM_RDSON:
-         saved_val = radio->recv_conf.rds_std;
-         radio->recv_conf.rds_std = val;
-         ret = hci_fm_set_recv_conf_req(&radio->recv_conf);
+         saved_val = hal->radio->recv_conf.rds_std;
+         hal->radio->recv_conf.rds_std = val;
+         ret = hci_fm_set_recv_conf_req(&hal->radio->recv_conf);
          if (ret < 0) {
              ALOGE("%s:Error in rds_std", LOG_TAG);
-             radio->recv_conf.rds_std = saved_val;
+             hal->radio->recv_conf.rds_std = saved_val;
              goto end;
          }
          break;
     case HCI_FM_HELIUM_RDSGROUP_MASK:
-         saved_val = radio->rds_grp.rds_grp_enable_mask;
+         saved_val = hal->radio->rds_grp.rds_grp_enable_mask;
          grp_mask = (grp_mask | oda_agt | val);
-         radio->rds_grp.rds_grp_enable_mask = grp_mask;
-         radio->rds_grp.rds_buf_size = 1;
-         radio->rds_grp.en_rds_change_filter = 0;
-         ret = helium_rds_grp_mask_req(&radio->rds_grp);
+         hal->radio->rds_grp.rds_grp_enable_mask = grp_mask;
+         hal->radio->rds_grp.rds_buf_size = 1;
+         hal->radio->rds_grp.en_rds_change_filter = 0;
+         ret = helium_rds_grp_mask_req(&hal->radio->rds_grp);
          if (ret < 0) {
              ALOGE("%s:error in setting group mask\n", LOG_TAG);
-             radio->rds_grp.rds_grp_enable_mask = saved_val;
+             hal->radio->rds_grp.rds_grp_enable_mask = saved_val;
              goto end;
         }
         break;
     case HCI_FM_HELIUM_RDSGROUP_PROC:
-         saved_val = radio->g_rds_grp_proc_ps;
-         rds_grps_proc = radio->g_rds_grp_proc_ps | (val & 0xFF);
-         radio->g_rds_grp_proc_ps = rds_grps_proc;
-         ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
+         saved_val = hal->radio->g_rds_grp_proc_ps;
+         rds_grps_proc = hal->radio->g_rds_grp_proc_ps | (val & 0xFF);
+         hal->radio->g_rds_grp_proc_ps = rds_grps_proc;
+         ret = helium_rds_grp_process_req(hal->radio->g_rds_grp_proc_ps);
          if (ret < 0) {
-             radio->g_rds_grp_proc_ps = saved_val;
+             hal->radio->g_rds_grp_proc_ps = saved_val;
              goto end;
          }
          break;
@@ -1309,7 +1335,7 @@
          ALOGD("%s: rds_grp counter read  value=%d ", LOG_TAG,val);
          ret = hci_fm_get_rds_grpcounters_req(val);
          if (ret < 0) {
-             radio->g_rds_grp_proc_ps = saved_val;
+             hal->radio->g_rds_grp_proc_ps = saved_val;
              goto end;
          }
          break;
@@ -1318,7 +1344,7 @@
          ALOGD("%s: rds_grp counter read  value=%d ", LOG_TAG,val);
          ret = hci_fm_get_rds_grpcounters_ext_req(val);
          if (ret < 0) {
-            radio->g_rds_grp_proc_ps = saved_val;
+            hal->radio->g_rds_grp_proc_ps = saved_val;
             goto end ;
          }
          break;
@@ -1332,28 +1358,28 @@
          break;
 
     case HCI_FM_HELIUM_RDSD_BUF:
-         radio->rds_grp.rds_buf_size = val;
+         hal->radio->rds_grp.rds_buf_size = val;
          break;
     case HCI_FM_HELIUM_PSALL:
-         saved_val = radio->g_rds_grp_proc_ps;
+         saved_val = hal->radio->g_rds_grp_proc_ps;
          rds_grps_proc = (val << RDS_CONFIG_OFFSET);
-         radio->g_rds_grp_proc_ps |= rds_grps_proc;
-         ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
+         hal->radio->g_rds_grp_proc_ps |= rds_grps_proc;
+         ret = helium_rds_grp_process_req(hal->radio->g_rds_grp_proc_ps);
          if (ret < 0) {
-             radio->g_rds_grp_proc_ps = saved_val;
+             hal->radio->g_rds_grp_proc_ps = saved_val;
              goto end;
         }
         break;
     case HCI_FM_HELIUM_AF_JUMP:
-        saved_val = radio->g_rds_grp_proc_ps;
-        radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
-        radio->af_jump_bit = val;
+        saved_val = hal->radio->g_rds_grp_proc_ps;
+        hal->radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
+        hal->radio->af_jump_bit = val;
         rds_grps_proc = 0x00;
         rds_grps_proc = (val << RDS_AF_JUMP_OFFSET);
-        radio->g_rds_grp_proc_ps |= rds_grps_proc;
-        ret = helium_rds_grp_process_req(radio->g_rds_grp_proc_ps);
+        hal->radio->g_rds_grp_proc_ps |= rds_grps_proc;
+        ret = helium_rds_grp_process_req(hal->radio->g_rds_grp_proc_ps);
         if (ret < 0) {
-            radio->g_rds_grp_proc_ps = saved_val;
+            hal->radio->g_rds_grp_proc_ps = saved_val;
             goto end;
         }
         break;
@@ -1367,15 +1393,15 @@
             ALOGE("%s:Set Antenna failed retval = %x", LOG_TAG, ret);
             goto end;
         }
-        radio->g_antenna =  val;
+        hal->radio->g_antenna =  val;
         break;
     case HCI_FM_HELIUM_SOFT_MUTE:
-         saved_val = radio->mute_mode.soft_mute;
-         radio->mute_mode.soft_mute = val;
-         ret = helium_set_fm_mute_mode_req(&radio->mute_mode);
+         saved_val = hal->radio->mute_mode.soft_mute;
+         hal->radio->mute_mode.soft_mute = val;
+         ret = helium_set_fm_mute_mode_req(&hal->radio->mute_mode);
          if (ret < 0) {
              ALOGE("%s:Error while setting FM soft mute %d", LOG_TAG, ret);
-             radio->mute_mode.soft_mute = saved_val;
+             hal->radio->mute_mode.soft_mute = saved_val;
              goto end;
          }
          break;
@@ -1386,21 +1412,21 @@
         helium_search_req(1, val);
         break;
     case HCI_FM_HELIUM_UPPER_BAND:
-        radio->recv_conf.band_high_limit = val;
+        hal->radio->recv_conf.band_high_limit = val;
         break;
     case HCI_FM_HELIUM_LOWER_BAND:
-        radio->recv_conf.band_low_limit = val;
+        hal->radio->recv_conf.band_low_limit = val;
         break;
     case HCI_FM_HELIUM_AUDIO_MODE:
-        radio->stereo_mode.stereo_mode = ~val;
-        hci_set_fm_stereo_mode_req(&radio->stereo_mode);
+        hal->radio->stereo_mode.stereo_mode = ~val;
+        hci_set_fm_stereo_mode_req(&hal->radio->stereo_mode);
         break;
     case HCI_FM_HELIUM_RIVA_ACCS_ADDR:
-        radio->riva_data_req.cmd_params.start_addr = val;
+        hal->radio->riva_data_req.cmd_params.start_addr = val;
         break;
     case HCI_FM_HELIUM_RIVA_ACCS_LEN:
         if (is_valid_peek_len(val)) {
-            radio->riva_data_req.cmd_params.length = val;
+            hal->radio->riva_data_req.cmd_params.length = val;
         } else {
             ret = -1;
             ALOGE("%s: riva access len is not valid\n", LOG_TAG);
@@ -1408,15 +1434,15 @@
         }
         break;
     case HCI_FM_HELIUM_RIVA_PEEK:
-        radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
-        val = hci_peek_data(&radio->riva_data_req.cmd_params);
+        hal->radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
+        val = hci_peek_data(&hal->radio->riva_data_req.cmd_params);
         break;
     case HCI_FM_HELIUM_RIVA_POKE:
-         if (radio->riva_data_req.cmd_params.length <=
+         if (hal->radio->riva_data_req.cmd_params.length <=
                     MAX_RIVA_PEEK_RSP_SIZE) {
-             radio->riva_data_req.cmd_params.subopcode =
+             hal->radio->riva_data_req.cmd_params.subopcode =
                                                 RIVA_POKE_OPCODE;
-             ret = hci_poke_data(&radio->riva_data_req);
+             ret = hci_poke_data(&hal->radio->riva_data_req);
          } else {
              ALOGE("%s: riva access len is not valid for poke\n", LOG_TAG);
              ret = -1;
@@ -1424,22 +1450,22 @@
          }
          break;
     case HCI_FM_HELIUM_SSBI_ACCS_ADDR:
-        radio->ssbi_data_accs.start_addr = val;
+        hal->radio->ssbi_data_accs.start_addr = val;
         break;
     case HCI_FM_HELIUM_SSBI_POKE:
-        radio->ssbi_data_accs.data = val;
-        ret = hci_ssbi_poke_reg(&radio->ssbi_data_accs);
+        hal->radio->ssbi_data_accs.data = val;
+        ret = hci_ssbi_poke_reg(&hal->radio->ssbi_data_accs);
         break;
     case HCI_FM_HELIUM_SSBI_PEEK:
-        radio->ssbi_peek_reg.start_address = val;
-        hci_ssbi_peek_reg(&radio->ssbi_peek_reg);
+        hal->radio->ssbi_peek_reg.start_address = val;
+        hci_ssbi_peek_reg(&hal->radio->ssbi_peek_reg);
         break;
     case HCI_FM_HELIUM_AGC_UCCTRL:
-        radio->set_get_reset_agc.ucctrl = val;
+        hal->radio->set_get_reset_agc.ucctrl = val;
         break;
     case HCI_FM_HELIUM_AGC_GAIN_STATE:
-        radio->set_get_reset_agc.ucgainstate = val;
-        hci_get_set_reset_agc_req(&radio->set_get_reset_agc);
+        hal->radio->set_get_reset_agc.ucgainstate = val;
+        hci_get_set_reset_agc_req(&hal->radio->set_get_reset_agc);
         break;
     case HCI_FM_HELIUM_SINR_SAMPLES:
          if (!is_valid_sinr_samples(val)) {
@@ -1447,8 +1473,8 @@
              ret = -1;
              goto end;
          }
-         radio->ch_det_threshold.sinr_samples = val;
-         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         hal->radio->ch_det_threshold.sinr_samples = val;
+         ret = set_ch_det_thresholds_req(&hal->radio->ch_det_threshold);
          if (ret < 0) {
              ALOGE("Failed to set SINR samples  %d", ret);
              goto end;
@@ -1460,8 +1486,8 @@
              ret = -1;
              goto end;
          }
-         radio->ch_det_threshold.sinr = val;
-         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         hal->radio->ch_det_threshold.sinr = val;
+         ret = set_ch_det_thresholds_req(&hal->radio->ch_det_threshold);
          break;
     case HCI_FM_HELIUM_INTF_LOW_THRESHOLD:
          if (!is_valid_intf_det_low_th(val)) {
@@ -1469,8 +1495,8 @@
              ret = -1;
              goto end;
          }
-         radio->ch_det_threshold.low_th = val;
-         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         hal->radio->ch_det_threshold.low_th = val;
+         ret = set_ch_det_thresholds_req(&hal->radio->ch_det_threshold);
          break;
     case HCI_FM_HELIUM_INTF_HIGH_THRESHOLD:
          if (!is_valid_intf_det_hgh_th(val)) {
@@ -1478,30 +1504,30 @@
              ret = -1;
              goto end;
          }
-         radio->ch_det_threshold.high_th = val;
-         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         hal->radio->ch_det_threshold.high_th = val;
+         ret = set_ch_det_thresholds_req(&hal->radio->ch_det_threshold);
          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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
@@ -1509,40 +1535,40 @@
     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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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);
+         memcpy(&def_data_wrt.data, &hal->radio->def_data.data,
+                 hal->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;
@@ -1552,8 +1578,8 @@
              ret = -1;
              goto end;
          }
-         radio->blend_tbl.BlendSinrHi = val;
-         ret = hci_fm_set_blend_tbl_req(&radio->blend_tbl);
+         hal->radio->blend_tbl.BlendSinrHi = val;
+         ret = hci_fm_set_blend_tbl_req(&hal->radio->blend_tbl);
          break;
     case HCI_FM_HELIUM_BLEND_RMSSIHI:
          if (!is_valid_blend_value(val)) {
@@ -1561,8 +1587,8 @@
              ret = -1;
              goto end;
          }
-         radio->blend_tbl.BlendRmssiHi = val;
-         ret = hci_fm_set_blend_tbl_req(&radio->blend_tbl);
+         hal->radio->blend_tbl.BlendRmssiHi = val;
+         ret = hci_fm_set_blend_tbl_req(&hal->radio->blend_tbl);
          break;
     case HCI_FM_HELIUM_ENABLE_LPF:
          ALOGI("%s: val: %x", __func__, val);
@@ -1586,16 +1612,21 @@
     int ret = 0;
     struct hci_fm_def_data_rd_req def_data_rd;
 
+    if (!hal) {
+        ALOGE("%s:ALERT: command sent before hal_init", __func__);
+        return -FM_HC_STATUS_FAIL;
+    }
+
     ALOGE("%s: cmd = 0x%x", __func__, cmd);
     switch(cmd) {
     case HCI_FM_HELIUM_FREQ:
-        val = radio->fm_st_rsp.station_rsp.station_freq;
+        val = hal->radio->fm_st_rsp.station_rsp.station_freq;
         break;
     case HCI_FM_HELIUM_UPPER_BAND:
-        val = radio->recv_conf.band_high_limit;
+        val = hal->radio->recv_conf.band_high_limit;
         break;
     case HCI_FM_HELIUM_LOWER_BAND:
-        val = radio->recv_conf.band_low_limit;
+        val = hal->radio->recv_conf.band_low_limit;
         break;
     case HCI_FM_HELIUM_SINR_SAMPLES:
         set_bit(ch_det_th_mask_flag, CMD_CHDET_SINR_SAMPLE);
@@ -1699,7 +1730,7 @@
             clear_bit(station_dbg_param_mask_flag, CMD_STNDBGPARAM_INFDETOUT);
         break;
     case HCI_FM_HELIUM_GET_SINR:
-        if (radio->mode == FM_RECV) {
+        if (hal->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)
@@ -1710,12 +1741,12 @@
         }
         break;
     case HCI_FM_HELIUM_RMSSI:
-        if (radio->mode == FM_RECV) {
+        if (hal->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) {
+        } else if (hal->radio->mode == FM_TRANS) {
             ALOGE("HCI_FM_HELIUM_RMSSI: radio is not in recv mode");
             ret = -EINVAL;
         }
@@ -1728,7 +1759,7 @@
     return ret;
 }
 
-const fm_interface_t FM_HELIUM_LIB_INTERFACE = {
+const struct fm_interface_t FM_HELIUM_LIB_INTERFACE = {
     hal_init,
     set_fm_ctrl,
     get_fm_ctrl
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index 7945023..520ec12 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -34,9 +34,10 @@
 #include <errno.h>
 #include "radio-helium-commands.h"
 #include "radio-helium.h"
-#include "fm_hci.h"
+#include "fm_hci_api.h"
 #include <dlfcn.h>
 #define LOG_TAG "radio_helium"
+extern struct fm_hal_t *hal;
 
 static int send_fm_cmd_pkt(uint16_t opcode,  uint32_t len, void *param)
 {
@@ -44,7 +45,7 @@
     int ret = 0;
     ALOGV("Send_fm_cmd_pkt, opcode: %x", opcode);
 //    pthread_mutex_lock(&fm_hal);
-    FM_HDR *hdr = (FM_HDR *) malloc(p_len);
+    struct fm_command_header_t *hdr = (struct fm_command_header_t *) malloc(p_len);
     if (!hdr) {
         ALOGE("%s:hdr allocation failed", LOG_TAG);
         return -FM_HC_STATUS_NOMEM;
@@ -52,12 +53,13 @@
 
     ALOGV("%s:opcode: %x", LOG_TAG, opcode);
 
-    hdr->protocol_byte = RADIO_HCI_COMMAND_PKT;
+    hdr->pi = RADIO_HCI_COMMAND_PKT;
     hdr->opcode = opcode;
-    hdr->plen = len;
+    hdr->len = len;
     if (len)
-        memcpy(hdr->cmd_params, (uint8_t *)param, len);
-    ret = transmit(hdr);
+        memcpy(hdr->params, (uint8_t *)param, len);
+    ret = fm_hci_transmit(hal->private_data, hdr);
+
     ALOGV("%s:transmit done. status = %d", __func__, ret);
     return ret;
 }