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