FM-HAL: Add support for FM Core functionalities
FM-HAL Layer contains the core FM Functionality required
for carrying out various FM operations such as FM Enable,
FM Tune, FM Seek, FM Search, FM Disable etc..
FM-HAL layer interacts with the FM-HCI layer for sending
commands and receiving events to and from Controller.
Change-Id: I0ac1c9c80671e43aafa30ce2b68f5ee695c9d764
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
new file mode 100644
index 0000000..cb85bcc
--- /dev/null
+++ b/helium/radio-helium.h
@@ -0,0 +1,1137 @@
+/*
+Copyright (c) 2015, 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
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+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)
+
+#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
+#define MAX_HARD_MUTE_VAL 0x03
+#define MIN_SRCH_MODE 0x00
+#define MAX_SRCH_MODE 0x09
+#define MIN_SCAN_DWELL 0x00
+#define MAX_SCAN_DWELL 0x0F
+#define MIN_SIG_TH 0x00
+#define MAX_SIG_TH 0x03
+#define MIN_PTY 0X00
+#define MAX_PTY 0x1F
+#define MIN_PI 0x0000
+#define MAX_PI 0xFFFF
+#define MIN_SRCH_STATIONS_CNT 0x00
+#define MAX_SRCH_STATIONS_CNT 0x14
+#define MIN_CHAN_SPACING 0x00
+#define MAX_CHAN_SPACING 0x02
+#define MIN_EMPHASIS 0x00
+#define MAX_EMPHASIS 0x01
+#define MIN_RDS_STD 0x00
+#define MAX_RDS_STD 0x02
+#define MIN_ANTENNA_VAL 0x00
+#define MAX_ANTENNA_VAL 0x01
+#define MIN_TX_PS_REPEAT_CNT 0x01
+#define MAX_TX_PS_REPEAT_CNT 0x0F
+#define MIN_SOFT_MUTE 0x00
+#define MAX_SOFT_MUTE 0x01
+#define MIN_PEEK_ACCESS_LEN 0x01
+#define MAX_PEEK_ACCESS_LEN 0xF9
+#define MIN_RESET_CNTR 0x00
+#define MAX_RESET_CNTR 0x01
+#define MIN_HLSI 0x00
+#define MAX_HLSI 0x02
+#define MIN_NOTCH_FILTER 0x00
+#define MAX_NOTCH_FILTER 0x02
+#define MIN_INTF_DET_OUT_LW_TH 0x00
+#define MAX_INTF_DET_OUT_LW_TH 0xFF
+#define MIN_INTF_DET_OUT_HG_TH 0x00
+#define MAX_INTF_DET_OUT_HG_TH 0xFF
+#define MIN_SINR_TH -128
+#define MAX_SINR_TH 127
+#define MIN_SINR_SAMPLES 0x01
+#define MAX_SINR_SAMPLES 0xFF
+#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
+/*HCI reponce packets*/
+#define MAX_RIVA_PEEK_RSP_SIZE 251
+/* default data access */
+#define DEFAULT_DATA_OFFSET 2
+#define DEFAULT_DATA_SIZE 249
+/* Power levels are 0-7, but SOC will expect values from 0-255
+ * So the each level step size will be 255/7 = 36 */
+#define FM_TX_PWR_LVL_STEP_SIZE 36
+#define FM_TX_PWR_LVL_0 0 /* Lowest power lvl that can be set for Tx */
+#define FM_TX_PWR_LVL_MAX 7 /* Max power lvl for Tx */
+#define FM_TX_PHY_CFG_MODE 0x3c
+#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
+/**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 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 AF_LIST_MAX (FM_AF_LIST_MAX_SIZE / 4) /* Each AF frequency consist
+ of sizeof(int) bytes */
+#define MAX_BLEND_INDEX 49
+/* HCI timeouts */
+#define RADIO_HCI_TIMEOUT (10000) /* 10 seconds */
+
+typedef enum {
+ ASSOCIATE_JVM,
+ DISASSOCIATE_JVM
+} bt_cb_thread_evt;
+
+#define TUNE_PARAM 16
+#define SIZE_ARRAY(x) (sizeof(x) / sizeof((x)[0]))
+typedef void (*enb_result_cb)();
+typedef void (*tune_rsp_cb)(int Freq);
+typedef void (*seek_rsp_cb)(int Freq);
+typedef void (*scan_rsp_cb)();
+typedef void (*srch_list_rsp_cb)(uint16_t *scan_tbl);
+typedef void (*stereo_mode_cb)(bool status);
+typedef void (*rds_avl_sts_cb)(bool status);
+typedef void (*af_list_cb)(uint16_t *af_list);
+typedef void (*rt_cb)(char *rt);
+typedef void (*ps_cb)(char *ps);
+typedef void (*oda_cb)();
+typedef void (*rt_plus_cb)(char *rt_plus);
+typedef void (*ert_cb)(char *ert);
+typedef void (*disable_cb)();
+typedef void (*callback_thread_event)(unsigned int evt);
+
+typedef struct {
+ size_t size;
+
+ enb_result_cb enabled_cb;
+ tune_rsp_cb tune_cb;
+ seek_rsp_cb seek_cmpl_cb;
+ scan_rsp_cb scan_next_cb;
+ srch_list_rsp_cb srch_list_cb;
+ stereo_mode_cb stereo_status_cb;
+ rds_avl_sts_cb rds_avail_status_cb;
+ af_list_cb af_list_update_cb;
+ rt_cb rt_update_cb;
+ ps_cb ps_update_cb;
+ oda_cb oda_update_cb;
+ rt_plus_cb rt_plus_update_cb;
+ ert_cb ert_update_cb;
+ disable_cb disabled_cb;
+ callback_thread_event thread_evt_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;
+};
+
+/* Opcode OCF */
+/* HCI recv control commands opcode */
+#define HCI_OCF_FM_ENABLE_RECV_REQ 0x0001
+#define HCI_OCF_FM_DISABLE_RECV_REQ 0x0002
+#define HCI_OCF_FM_GET_RECV_CONF_REQ 0x0003
+#define HCI_OCF_FM_SET_RECV_CONF_REQ 0x0004
+#define HCI_OCF_FM_SET_MUTE_MODE_REQ 0x0005
+#define HCI_OCF_FM_SET_STEREO_MODE_REQ 0x0006
+#define HCI_OCF_FM_SET_ANTENNA 0x0007
+#define HCI_OCF_FM_SET_SIGNAL_THRESHOLD 0x0008
+#define HCI_OCF_FM_GET_SIGNAL_THRESHOLD 0x0009
+#define HCI_OCF_FM_GET_STATION_PARAM_REQ 0x000A
+#define HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ 0x000B
+#define HCI_OCF_FM_GET_RADIO_TEXT_REQ 0x000C
+#define HCI_OCF_FM_GET_AF_LIST_REQ 0x000D
+#define HCI_OCF_FM_SEARCH_STATIONS 0x000E
+#define HCI_OCF_FM_SEARCH_RDS_STATIONS 0x000F
+#define HCI_OCF_FM_SEARCH_STATIONS_LIST 0x0010
+#define HCI_OCF_FM_CANCEL_SEARCH 0x0011
+#define HCI_OCF_FM_RDS_GRP 0x0012
+#define HCI_OCF_FM_RDS_GRP_PROCESS 0x0013
+#define HCI_OCF_FM_EN_WAN_AVD_CTRL 0x0014
+#define HCI_OCF_FM_EN_NOTCH_CTRL 0x0015
+#define HCI_OCF_FM_SET_EVENT_MASK 0x0016
+#define HCI_OCF_FM_SET_CH_DET_THRESHOLD 0x0017
+#define HCI_OCF_FM_GET_CH_DET_THRESHOLD 0x0018
+#define HCI_OCF_FM_SET_BLND_TBL 0x001B
+#define HCI_OCF_FM_GET_BLND_TBL 0x001C
+/* HCI trans control commans opcode*/
+#define HCI_OCF_FM_ENABLE_TRANS_REQ 0x0001
+#define HCI_OCF_FM_DISABLE_TRANS_REQ 0x0002
+#define HCI_OCF_FM_GET_TRANS_CONF_REQ 0x0003
+#define HCI_OCF_FM_SET_TRANS_CONF_REQ 0x0004
+#define HCI_OCF_FM_RDS_RT_REQ 0x0008
+#define HCI_OCF_FM_RDS_PS_REQ 0x0009
+
+
+/* HCI common control commands opcode */
+#define HCI_OCF_FM_TUNE_STATION_REQ 0x0001
+#define HCI_OCF_FM_DEFAULT_DATA_READ 0x0002
+#define HCI_OCF_FM_DEFAULT_DATA_WRITE 0x0003
+#define HCI_OCF_FM_RESET 0x0004
+#define HCI_OCF_FM_GET_FEATURE_LIST 0x0005
+#define HCI_OCF_FM_DO_CALIBRATION 0x0006
+#define HCI_OCF_FM_SET_CALIBRATION 0x0007
+#define HCI_OCF_FM_SET_SPUR_TABLE 0x0008
+#define HCI_OCF_FM_GET_SPUR_TABLE 0x0009
+
+/*HCI Status parameters commands*/
+#define HCI_OCF_FM_READ_GRP_COUNTERS 0x0001
+
+/*HCI Diagnostic commands*/
+#define HCI_OCF_FM_PEEK_DATA 0x0002
+#define HCI_OCF_FM_POKE_DATA 0x0003
+#define HCI_OCF_FM_SSBI_PEEK_REG 0x0004
+#define HCI_OCF_FM_SSBI_POKE_REG 0x0005
+#define HCI_OCF_FM_STATION_DBG_PARAM 0x0007
+#define HCI_FM_SET_INTERNAL_TONE_GENRATOR 0x0008
+
+/* Opcode OGF */
+#define HCI_OGF_FM_RECV_CTRL_CMD_REQ 0x0013
+#define HCI_OGF_FM_TRANS_CTRL_CMD_REQ 0x0014
+#define HCI_OGF_FM_COMMON_CTRL_CMD_REQ 0x0015
+#define HCI_OGF_FM_STATUS_PARAMETERS_CMD_REQ 0x0016
+#define HCI_OGF_FM_TEST_CMD_REQ 0x0017
+#define HCI_OGF_FM_DIAGNOSTIC_CMD_REQ 0x003F
+
+/* Command opcode pack/unpack */
+#define hci_opcode_pack(ogf, ocf) (short) ((ocf & 0x03ff)|(ogf << 10))
+#define hci_opcode_ogf(op) (op >> 10)
+#define hci_opcode_ocf(op) (op & 0x03ff)
+#define hci_recv_ctrl_cmd_op_pack(ocf) \
+ (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) \
+ (short) hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ, 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) \
+ (short) hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ, ocf)
+
+
+/* HCI commands with no arguments*/
+#define HCI_FM_ENABLE_RECV_CMD 1
+#define HCI_FM_DISABLE_RECV_CMD 2
+#define HCI_FM_GET_RECV_CONF_CMD 3
+#define HCI_FM_GET_STATION_PARAM_CMD 4
+#define HCI_FM_GET_SIGNAL_TH_CMD 5
+#define HCI_FM_GET_PROGRAM_SERVICE_CMD 6
+#define HCI_FM_GET_RADIO_TEXT_CMD 7
+#define HCI_FM_GET_AF_LIST_CMD 8
+#define HCI_FM_CANCEL_SEARCH_CMD 9
+#define HCI_FM_RESET_CMD 10
+#define HCI_FM_GET_FEATURES_CMD 11
+#define HCI_FM_STATION_DBG_PARAM_CMD 12
+#define HCI_FM_ENABLE_TRANS_CMD 13
+#define HCI_FM_DISABLE_TRANS_CMD 14
+#define HCI_FM_GET_TX_CONFIG 15
+#define HCI_FM_GET_DET_CH_TH_CMD 16
+#define HCI_FM_GET_BLND_TBL_CMD 17
+
+/* Defines for FM TX*/
+#define TX_PS_DATA_LENGTH 108
+#define TX_RT_DATA_LENGTH 64
+#define PS_STRING_LEN 9
+
+/* ----- HCI Command request ----- */
+struct hci_fm_recv_conf_req {
+ char emphasis;
+ char ch_spacing;
+ char rds_std;
+ char hlsi;
+ 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_high_limit;
+} ;
+
+
+/* ----- HCI Command request ----- */
+struct hci_fm_tx_ps {
+ char ps_control;
+ short pi;
+ char pty;
+ char ps_repeatcount;
+ char ps_num;
+ char ps_data[TX_PS_DATA_LENGTH];
+} ;
+
+struct hci_fm_tx_rt {
+ char rt_control;
+ short pi;
+ char pty;
+ char rt_len;
+ char rt_data[TX_RT_DATA_LENGTH];
+} ;
+
+struct hci_fm_mute_mode_req {
+ char hard_mute;
+ char soft_mute;
+} ;
+
+struct hci_fm_stereo_mode_req {
+ char stereo_mode;
+ char sig_blend;
+ char intf_blend;
+ char most_switch;
+} ;
+
+struct hci_fm_search_station_req {
+ char srch_mode;
+ char scan_time;
+ char srch_dir;
+} ;
+
+struct hci_fm_search_rds_station_req {
+ struct hci_fm_search_station_req srch_station;
+ char srch_pty;
+ short srch_pi;
+} ;
+
+struct hci_fm_search_station_list_req {
+ char srch_list_mode;
+ char srch_list_dir;
+ int srch_list_max;
+ char srch_pty;
+} ;
+
+struct hci_fm_rds_grp_req {
+ int rds_grp_enable_mask;
+ int rds_buf_size;
+ char en_rds_change_filter;
+} ;
+
+struct hci_fm_en_avd_ctrl_req {
+ char no_freqs;
+ char freq_index;
+ char lo_shft;
+ short freq_min;
+ short freq_max;
+} ;
+
+struct hci_fm_def_data_rd_req {
+ char mode;
+ char length;
+ char param_len;
+ char param;
+} ;
+
+struct hci_fm_def_data_wr_req {
+ char mode;
+ char length;
+ char data[DEFAULT_DATA_SIZE];
+} ;
+
+struct hci_fm_riva_data {
+ char subopcode;
+ int start_addr;
+ char length;
+} ;
+
+struct hci_fm_riva_poke {
+ struct hci_fm_riva_data cmd_params;
+ char data[MAX_RIVA_PEEK_RSP_SIZE];
+} ;
+
+struct hci_fm_ssbi_req {
+ short start_addr;
+ char data;
+} ;
+struct hci_fm_ssbi_peek {
+ short start_address;
+} ;
+
+struct hci_fm_ch_det_threshold {
+ char sinr;
+ 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];
+} ;
+
+/*HCI events*/
+#define HCI_EV_TUNE_STATUS 0x01
+#define HCI_EV_RDS_LOCK_STATUS 0x02
+#define HCI_EV_STEREO_STATUS 0x03
+#define HCI_EV_SERVICE_AVAILABLE 0x04
+#define HCI_EV_SEARCH_PROGRESS 0x05
+#define HCI_EV_SEARCH_RDS_PROGRESS 0x06
+#define HCI_EV_SEARCH_LIST_PROGRESS 0x07
+#define HCI_EV_RDS_RX_DATA 0x08
+#define HCI_EV_PROGRAM_SERVICE 0x09
+#define HCI_EV_RADIO_TEXT 0x0A
+#define HCI_EV_FM_AF_LIST 0x0B
+#define HCI_EV_TX_RDS_GRP_AVBLE 0x0C
+#define HCI_EV_TX_RDS_GRP_COMPL 0x0D
+#define HCI_EV_TX_RDS_CONT_GRP_COMPL 0x0E
+#define HCI_EV_CMD_COMPLETE 0x0F
+#define HCI_EV_CMD_STATUS 0x10
+#define HCI_EV_TUNE_COMPLETE 0x11
+#define HCI_EV_SEARCH_COMPLETE 0x12
+#define HCI_EV_SEARCH_RDS_COMPLETE 0x13
+#define HCI_EV_SEARCH_LIST_COMPLETE 0x14
+
+#define HCI_REQ_DONE 0
+#define HCI_REQ_PEND 1
+#define HCI_REQ_CANCELED 2
+#define HCI_REQ_STATUS 3
+
+#define MAX_RAW_RDS_GRPS 21
+
+#define RDSGRP_DATA_OFFSET 0x1
+
+/*RT PLUS*/
+#define DUMMY_CLASS 0
+#define RT_PLUS_LEN_1_TAG 3
+#define RT_ERT_FLAG_BIT 5
+
+/*TAG1*/
+#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_MASK 63
+
+/*TAG2*/
+#define TAG2_MSB_OFFSET 5
+#define TAG2_MSB_MASK 1
+#define TAG2_LSB_OFFSET 3
+#define TAG2_POS_MSB_MASK 7
+#define TAG2_POS_MSB_OFFSET 3
+#define TAG2_POS_LSB_OFFSET 5
+#define TAG2_LEN_MASK 31
+
+#define AGT_MASK 31
+/*Extract 5 left most bits of lsb of 2nd block*/
+#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*/
+#define GTC(blk2msb) (blk2msb >> 3)
+
+#define GRP_3A 0x6
+#define RT_PLUS_AID 0x4bd7
+
+/*ERT*/
+#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)
+
+struct hci_ev_tune_status {
+ char sub_event;
+ int station_freq;
+ char serv_avble;
+ char rssi;
+ char stereo_prg;
+ char rds_sync_status;
+ char mute_mode;
+ char sinr;
+ char intf_det_th;
+} ;
+
+struct rds_blk_data {
+ char rdsMsb;
+ char rdsLsb;
+ char blockStatus;
+} ;
+
+struct rds_grp_data {
+ struct rds_blk_data rdsBlk[4];
+} ;
+
+struct hci_ev_rds_rx_data {
+ char num_rds_grps;
+ struct rds_grp_data rds_grp_data[MAX_RAW_RDS_GRPS];
+} ;
+
+struct hci_ev_prg_service {
+ short pi_prg_id;
+ char pty_prg_type;
+ char ta_prg_code_type;
+ char ta_ann_code_flag;
+ char ms_switch_code_flag;
+ char dec_id_ctrl_code_flag;
+ char ps_num;
+ char prg_service_name[119];
+} ;
+
+struct hci_ev_radio_text {
+ short pi_prg_id;
+ char pty_prg_type;
+ char ta_prg_code_type;
+ char txt_ab_flag;
+ char radio_txt[64];
+} ;
+
+struct hci_ev_af_list {
+ int tune_freq;
+ short pi_code;
+ char af_size;
+ char af_list[FM_AF_LIST_MAX_SIZE];
+} ;
+
+struct hci_ev_cmd_complete {
+ char num_hci_cmd_pkts;
+ short cmd_opcode;
+} ;
+
+struct hci_ev_cmd_status {
+ char status;
+ char num_hci_cmd_pkts;
+ short status_opcode;
+} ;
+
+struct hci_ev_srch_st {
+ int station_freq;
+ char rds_cap;
+ char pty;
+ short status_opcode;
+} ;
+
+struct hci_ev_rel_freq {
+ char rel_freq_msb;
+ char rel_freq_lsb;
+
+} ;
+struct hci_ev_srch_list_compl {
+ char num_stations_found;
+ struct hci_ev_rel_freq rel_freq[20];
+} ;
+
+/* ----- HCI Event Response ----- */
+struct hci_fm_conf_rsp {
+ char status;
+ struct hci_fm_recv_conf_req recv_conf_rsp;
+} ;
+
+struct hci_fm_get_trans_conf_rsp {
+ char status;
+ struct hci_fm_trans_conf_req_struct trans_conf_rsp;
+} ;
+struct hci_fm_sig_threshold_rsp {
+ char status;
+ char sig_threshold;
+} ;
+
+struct hci_fm_station_rsp {
+ struct hci_ev_tune_status station_rsp;
+} ;
+
+struct hci_fm_prgm_srv_rsp {
+ char status;
+ struct hci_ev_prg_service prg_srv;
+} ;
+
+struct hci_fm_radio_txt_rsp {
+ char status;
+ struct hci_ev_radio_text rd_txt;
+} ;
+
+struct hci_fm_af_list_rsp {
+ char status;
+ struct hci_ev_af_list rd_txt;
+} ;
+
+struct hci_fm_data_rd_rsp {
+ char status;
+ char ret_data_len;
+ char data[DEFAULT_DATA_SIZE];
+} ;
+
+struct hci_fm_feature_list_rsp {
+ char status;
+ char feature_mask;
+} ;
+
+struct hci_fm_dbg_param_rsp {
+ char status;
+ char blend;
+ char soft_mute;
+ char inf_blend;
+ char inf_soft_mute;
+ char pilot_pil;
+ char io_verc;
+ 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 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];
+ 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 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
+#define RDS_PID_LOWER 1
+#define RDS_PID_HIGHER 0
+#define RDS_OFFSET 5
+#define RDS_PS_LENGTH_OFFSET 7
+#define RDS_STRING 8
+#define RDS_PS_DATA_OFFSET 8
+#define RDS_CONFIG_OFFSET 3
+#define RDS_AF_JUMP_OFFSET 4
+#define PI_CODE_OFFSET 4
+#define AF_SIZE_OFFSET 6
+#define AF_LIST_OFFSET 7
+#define RT_A_B_FLAG_OFFSET 4
+/*FM states*/
+
+enum radio_state_t {
+ FM_OFF,
+ FM_RECV,
+ FM_TRANS,
+ FM_RESET,
+ FM_CALIB,
+ FM_TURNING_OFF,
+ FM_RECV_TURNING_ON,
+ FM_TRANS_TURNING_ON,
+ FM_MAX_NO_STATES,
+};
+
+enum emphasis_type {
+ FM_RX_EMP75 = 0x0,
+ FM_RX_EMP50 = 0x1
+};
+
+enum channel_space_type {
+ FM_RX_SPACE_200KHZ = 0x0,
+ FM_RX_SPACE_100KHZ = 0x1,
+ FM_RX_SPACE_50KHZ = 0x2
+};
+
+enum high_low_injection {
+ AUTO_HI_LO_INJECTION = 0x0,
+ LOW_SIDE_INJECTION = 0x1,
+ HIGH_SIDE_INJECTION = 0x2
+};
+
+enum fm_rds_type {
+ FM_RX_RDBS_SYSTEM = 0x0,
+ FM_RX_RDS_SYSTEM = 0x1
+};
+
+enum hlm_region_t {
+ HELIUM_REGION_US,
+ HELIUM_REGION_EU,
+ HELIUM_REGION_JAPAN,
+ HELIUM_REGION_JAPAN_WIDE,
+ HELIUM_REGION_OTHER
+};
+
+/* Search options */
+enum search_t {
+ SEEK,
+ SCAN,
+ SCAN_FOR_STRONG,
+ SCAN_FOR_WEAK,
+ RDS_SEEK_PTY,
+ RDS_SCAN_PTY,
+ RDS_SEEK_PI,
+ RDS_AF_JUMP,
+};
+
+enum spur_entry_levels {
+ ENTRY_0,
+ ENTRY_1,
+ ENTRY_2,
+ ENTRY_3,
+ ENTRY_4,
+ ENTRY_5,
+};
+
+/* Band limits */
+#define REGION_US_EU_BAND_LOW 87500
+#define REGION_US_EU_BAND_HIGH 108000
+#define REGION_JAPAN_STANDARD_BAND_LOW 76000
+#define REGION_JAPAN_STANDARD_BAND_HIGH 90000
+#define REGION_JAPAN_WIDE_BAND_LOW 90000
+#define REGION_JAPAN_WIDE_BAND_HIGH 108000
+
+#define SRCH_MODE 0x07
+#define SRCH_DIR 0x08 /* 0-up 1-down */
+#define SCAN_DWELL 0x70
+#define SRCH_ON 0x80
+
+/* I/O Control */
+#define IOC_HRD_MUTE 0x03
+#define IOC_SFT_MUTE 0x01
+#define IOC_MON_STR 0x01
+#define IOC_SIG_BLND 0x01
+#define IOC_INTF_BLND 0x01
+#define IOC_ANTENNA 0x01
+
+/* RDS Control */
+#define RDS_ON 0x01
+#define RDS_BUF_SZ 100
+
+/* constants */
+#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)
+#define RX_RT_DATA_LENGTH (63)
+/* Search direction */
+#define SRCH_DIR_UP (0)
+#define SRCH_DIR_DOWN (1)
+
+/*Search RDS stations*/
+#define SEARCH_RDS_STNS_MODE_OFFSET 4
+
+/*Search Station list */
+#define PARAMS_PER_STATION 0x08
+#define STN_NUM_OFFSET 0x01
+#define STN_FREQ_OFFSET 0x02
+#define KHZ_TO_MHZ 1000
+#define GET_MSB(x)((x >> 8) & 0xFF)
+#define GET_LSB(x)((x) & 0xFF)
+
+/* control options */
+#define CTRL_ON (1)
+#define CTRL_OFF (0)
+
+/*Diagnostic commands*/
+
+#define RIVA_PEEK_OPCODE 0x0D
+#define RIVA_POKE_OPCODE 0x0C
+
+#define PEEK_DATA_OFSET 0x1
+#define RIVA_PEEK_PARAM 0x6
+#define RIVA_PEEK_LEN_OFSET 0x6
+#define SSBI_PEEK_LEN 0x01
+/*Calibration data*/
+#define PROCS_CALIB_MODE 1
+#define PROCS_CALIB_SIZE 23
+#define DC_CALIB_MODE 2
+#define DC_CALIB_SIZE 48
+#define RSB_CALIB_MODE 3
+#define RSB_CALIB_SIZE 4
+#define CALIB_DATA_OFSET 2
+#define CALIB_MODE_OFSET 1
+#define MAX_CALIB_SIZE 75
+
+/* Channel validity */
+#define INVALID_CHANNEL (0)
+#define VALID_CHANNEL (1)
+
+struct hci_fm_set_cal_req_proc {
+ char mode;
+ /*Max process calibration data size*/
+ char data[PROCS_CALIB_SIZE];
+} ;
+
+struct hci_fm_set_cal_req_dc {
+ char mode;
+ /*Max DC calibration data size*/
+ char data[DC_CALIB_SIZE];
+} ;
+
+struct hci_cc_do_calibration_rsp {
+ char status;
+ char mode;
+ char data[MAX_CALIB_SIZE];
+} ;
+
+struct hci_fm_set_spur_table_req {
+ char mode;
+ char no_of_freqs_entries;
+ char spur_data[FM_SPUR_TBL_SIZE];
+} ;
+/* Low Power mode*/
+#define SIG_LEVEL_INTR (1 << 0)
+#define RDS_SYNC_INTR (1 << 1)
+#define AUDIO_CTRL_INTR (1 << 2)
+#define AF_JUMP_ENABLE (1 << 4)
+
+int hci_def_data_read(struct hci_fm_def_data_rd_req *arg,
+ struct radio_hci_dev *hdev);
+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)
+{
+ if ((tone >= MIN_TX_TONE_VAL) &&
+ (tone <= MAX_TX_TONE_VAL))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_hard_mute(int hard_mute)
+{
+ if ((hard_mute >= MIN_HARD_MUTE_VAL) &&
+ (hard_mute <= MAX_HARD_MUTE_VAL))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_srch_mode(int srch_mode)
+{
+ if ((srch_mode >= MIN_SRCH_MODE) &&
+ (srch_mode <= MAX_SRCH_MODE))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_scan_dwell_prd(int scan_dwell_prd)
+{
+ if ((scan_dwell_prd >= MIN_SCAN_DWELL) &&
+ (scan_dwell_prd <= MAX_SCAN_DWELL))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_sig_th(int sig_th)
+{
+ if ((sig_th >= MIN_SIG_TH) &&
+ (sig_th <= MAX_SIG_TH))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_pty(int pty)
+{
+ if ((pty >= MIN_PTY) &&
+ (pty <= MAX_PTY))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_pi(int pi)
+{
+ if ((pi >= MIN_PI) &&
+ (pi <= MAX_PI))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_srch_station_cnt(int cnt)
+{
+ if ((cnt >= MIN_SRCH_STATIONS_CNT) &&
+ (cnt <= MAX_SRCH_STATIONS_CNT))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_chan_spacing(int spacing)
+{
+ if ((spacing >= MIN_CHAN_SPACING) &&
+ (spacing <= MAX_CHAN_SPACING))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_emphasis(int emphasis)
+{
+ if ((emphasis >= MIN_EMPHASIS) &&
+ (emphasis <= MAX_EMPHASIS))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_rds_std(int rds_std)
+{
+ if ((rds_std >= MIN_RDS_STD) &&
+ (rds_std <= MAX_RDS_STD))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_antenna(int antenna_type)
+{
+ if ((antenna_type >= MIN_ANTENNA_VAL) &&
+ (antenna_type <= MAX_ANTENNA_VAL))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_ps_repeat_cnt(int cnt)
+{
+ if ((cnt >= MIN_TX_PS_REPEAT_CNT) &&
+ (cnt <= MAX_TX_PS_REPEAT_CNT))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_soft_mute(int soft_mute)
+{
+ if ((soft_mute >= MIN_SOFT_MUTE) &&
+ (soft_mute <= MAX_SOFT_MUTE))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_peek_len(int len)
+{
+ if ((len >= MIN_PEEK_ACCESS_LEN) &&
+ (len <= MAX_PEEK_ACCESS_LEN))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_reset_cntr(int cntr)
+{
+ if ((cntr >= MIN_RESET_CNTR) &&
+ (cntr <= MAX_RESET_CNTR))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_hlsi(int hlsi)
+{
+ if ((hlsi >= MIN_HLSI) &&
+ (hlsi <= MAX_HLSI))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_notch_filter(int filter)
+{
+ if ((filter >= MIN_NOTCH_FILTER) &&
+ (filter <= MAX_NOTCH_FILTER))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_intf_det_low_th(int th)
+{
+ if ((th >= MIN_INTF_DET_OUT_LW_TH) &&
+ (th <= MAX_INTF_DET_OUT_LW_TH))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_intf_det_hgh_th(int th)
+{
+ if ((th >= MIN_INTF_DET_OUT_HG_TH) &&
+ (th <= MAX_INTF_DET_OUT_HG_TH))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_sinr_th(int th)
+{
+ if ((th >= MIN_SINR_TH) &&
+ (th <= MAX_SINR_TH))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_sinr_samples(int samples_cnt)
+{
+ if ((samples_cnt >= MIN_SINR_SAMPLES) &&
+ (samples_cnt <= MAX_SINR_SAMPLES))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_fm_state(int state)
+{
+ if ((state >= 0) && (state < FM_MAX_NO_STATES))
+ return 1;
+ else
+ return 0;
+}
+
+static inline int is_valid_blend_value(int val)
+{
+ if ((val >= MIN_BLEND_HI) && (val <= MAX_BLEND_HI))
+ return 1;
+ else
+ return 0;
+}
+
+struct helium_device {
+ int tune_req;
+ unsigned int mode;
+ short pi;
+ char pty;
+ char ps_repeatcount;
+ char prev_trans_rds;
+ char af_jump_bit;
+ struct hci_fm_mute_mode_req mute_mode;
+ struct hci_fm_stereo_mode_req stereo_mode;
+ struct hci_fm_station_rsp fm_st_rsp;
+ struct hci_fm_search_station_req srch_st;
+ struct hci_fm_search_rds_station_req srch_rds;
+ struct hci_fm_search_station_list_req srch_st_list;
+ struct hci_fm_recv_conf_req recv_conf;
+ struct hci_fm_trans_conf_req_struct trans_conf;
+ struct hci_fm_rds_grp_req rds_grp;
+ unsigned char g_search_mode;
+ unsigned char power_mode;
+ int search_on;
+ unsigned char spur_table_size;
+ unsigned char g_scan_time;
+ unsigned int g_antenna;
+ unsigned int g_rds_grp_proc_ps;
+ unsigned char event_mask;
+ enum hlm_region_t region;
+ struct hci_fm_dbg_param_rsp st_dbg_param;
+ struct hci_ev_srch_list_compl srch_st_result;
+};
+#endif /* __UAPI_RADIO_HCI_CORE_H */