diff options
Diffstat (limited to 'helium')
-rw-r--r-- | helium/radio-helium.h | 104 | ||||
-rw-r--r-- | helium/radio_helium_hal.c | 565 | ||||
-rw-r--r-- | helium/radio_helium_hal_cmds.c | 14 |
3 files changed, 340 insertions, 343 deletions
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 @@ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 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 @@ pthread_mutex_t fm_hal; #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 @@ typedef struct { 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 @@ typedef struct { 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 @@ struct hci_fm_trans_conf_req_struct { int band_high_limit; } ; - /* ----- HCI Command request ----- */ struct hci_fm_tx_ps { char ps_control; @@ -612,7 +564,7 @@ struct hci_ev_tune_status { char mute_mode; char sinr; char intf_det_th; -} ; +}__attribute__((packed)) ; struct rds_blk_data { char rdsMsb; @@ -653,25 +605,25 @@ struct hci_ev_af_list { 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_ev_srch_list_compl { 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_station_rsp { 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 @@ struct hci_fm_spur_data { 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_read(struct hci_fm_def_data_rd_req *arg, 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 @@ static inline int is_valid_blend_value(int val) return 0; } -struct helium_device { +struct radio_helium_device { int tune_req; unsigned int mode; short pi; @@ -1212,7 +1163,7 @@ struct helium_device { 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_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(); +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 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 blend_tbl_mask_flag; 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 @@ static void hci_cc_fm_enable_rsp(char *ev_rsp) 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 @@ static void hci_cc_conf_rsp(char *ev_rsp) 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 @@ static void hci_cc_fm_disable_rsp(char *ev_buff) 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 @@ static void hci_cc_rds_grp_cntrs_rsp(char *ev_buff) 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 @@ static void hci_cc_rds_grp_cntrs_ext_rsp(char *ev_buff) 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 @@ static void hci_cc_riva_peek_rsp(char *ev_buff) 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 @@ static void hci_cc_ssbi_peek_rsp(char *ev_buff) 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 @@ static void hci_cc_agc_rsp(char *ev_buff) 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 @@ static void hci_cc_get_ch_det_threshold_rsp(char *ev_buff) 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 @@ static void hci_cc_sig_threshold_rsp(char *ev_buff) } 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 @@ static void hci_cc_default_data_read_rsp(char *ev_buff) 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 @@ static void hci_cc_get_blend_tbl_rsp(char *ev_buff) 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 @@ static void hci_cc_get_blend_tbl_rsp(char *ev_buff) 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 @@ 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], + 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 @@ 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], + 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_cmd_status_event(char *st_rsp) 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 @@ static inline void hci_ev_stereo_status(char *buff) } 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 @@ static void hci_ev_rds_lock_status(char *buff) 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 @@ static inline void hci_ev_program_service(char *buff) 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 @@ static inline void hci_ev_radio_text(char *buff) 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 @@ static void hci_ev_af_list(char *buff) } 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 @@ static inline void hci_ev_search_compl(char *buff) 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 @@ static inline void hci_ev_srch_st_list_compl(char *buff) 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 @@ static inline void hci_ev_srch_st_list_compl(char *buff) } 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 @@ static void hci_ev_rt_plus_tag(char *buff) 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 @@ static void hci_ev_ext_country_code(char *buff) 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 @@ static void hci_ev_ert() 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_ert() 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 @@ static void hci_ev_raw_rds_group_data(char *buff) 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 @@ static void hci_ev_raw_rds_group_data(char *buff) 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 @@ static void radio_hci_event_packet(char *evt_buf) 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 @@ static void radio_hci_event_packet(char *evt_buf) } /* '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 helium_search_req(int on, int direct) 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 @@ int helium_search_req(int on, int direct) 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 @@ int helium_search_req(int on, int direct) } if (retval < 0) - radio->search_on = saved_val; + hal->radio->search_on = saved_val; return retval; } @@ -1086,12 +1082,12 @@ int helium_recv_set_region(int req_region) 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 set_low_power_mode(int lp_mode) 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 @@ int set_low_power_mode(int lp_mode) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) } 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 @@ static int set_fm_ctrl(int cmd, int val) } 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int set_fm_ctrl(int cmd, int val) 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 @@ static int get_fm_ctrl(int cmd, int val) 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 @@ cmd: 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 @@ cmd: } 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 @@ cmd: 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 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 @@ static int send_fm_cmd_pkt(uint16_t opcode, uint32_t len, void *param) 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 @@ static int send_fm_cmd_pkt(uint16_t opcode, uint32_t len, void *param) 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; } |