in drivers/media/radio/radio-iris.c [3970:4991]
static int iris_vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct iris_device *radio = video_get_drvdata(video_devdata(file));
int retval = 0;
unsigned int rds_grps_proc = 0;
__u8 temp_val = 0;
int saved_val;
unsigned long arg = 0;
struct hci_fm_tx_ps tx_ps = {0};
struct hci_fm_tx_rt tx_rt = {0};
struct hci_fm_def_data_rd_req rd;
struct hci_fm_def_data_wr_req wrd;
char sinr_th, sinr;
__u8 intf_det_low_th, intf_det_high_th, intf_det_out;
unsigned int spur_freq;
if (unlikely(radio == NULL)) {
FMDERR(":radio is null");
retval = -EINVAL;
goto END;
}
if (ctrl == NULL) {
FMDERR("%s, v4l2 ctrl is null\n", __func__);
retval = -EINVAL;
goto END;
}
FMDBG("id 0x%x", ctrl->id);
switch (ctrl->id) {
case V4L2_CID_PRIVATE_IRIS_TX_TONE:
if (!is_valid_tone(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: tone value is not valid\n", __func__);
goto END;
}
saved_val = radio->tone_freq;
radio->tone_freq = ctrl->value;
retval = radio_hci_request(radio->fm_hdev,
hci_fm_tone_generator, arg,
RADIO_HCI_TIMEOUT);
if (retval < 0) {
FMDERR("Error while setting the tone %d", retval);
radio->tone_freq = saved_val;
}
break;
case V4L2_CID_AUDIO_VOLUME:
break;
case V4L2_CID_AUDIO_MUTE:
if (!is_valid_hard_mute(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: hard mute value is not valid\n", __func__);
goto END;
}
saved_val = radio->mute_mode.hard_mute;
radio->mute_mode.hard_mute = ctrl->value;
retval = hci_set_fm_mute_mode(
&radio->mute_mode,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error while set FM hard mute"" %d\n",
retval);
radio->mute_mode.hard_mute = saved_val;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
if (is_valid_srch_mode(ctrl->value)) {
radio->g_search_mode = ctrl->value;
} else {
FMDERR("%s: srch mode is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
if (is_valid_scan_dwell_prd(ctrl->value)) {
radio->g_scan_time = ctrl->value;
} else {
FMDERR("%s: scandwell period is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCHON:
iris_search(radio, ctrl->value, SRCH_DIR_UP);
break;
case V4L2_CID_PRIVATE_IRIS_STATE:
switch (ctrl->value) {
case FM_RECV:
if (radio->mode != FM_OFF) {
FMDERR("FM mode is not off %d\n", radio->mode);
retval = -EINVAL;
goto END;
}
if (is_enable_rx_possible(radio) != 0) {
FMDERR("%s: fm is not in proper state\n",
__func__);
retval = -EINVAL;
goto END;
}
radio->mode = FM_RECV_TURNING_ON;
retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Enabling RECV FM fail %d\n", retval);
radio->mode = FM_OFF;
goto END;
} else {
retval = initialise_recv(radio);
if (retval < 0) {
FMDERR("Error while initialising");
FMDERR("radio %d\n", retval);
hci_cmd(HCI_FM_DISABLE_RECV_CMD,
radio->fm_hdev);
radio->mode = FM_OFF;
goto END;
}
}
if (radio->mode == FM_RECV_TURNING_ON) {
radio->mode = FM_RECV;
iris_q_event(radio, IRIS_EVT_RADIO_READY);
}
break;
case FM_TRANS:
if (is_enable_tx_possible(radio) != 0) {
retval = -EINVAL;
goto END;
}
radio->mode = FM_TRANS_TURNING_ON;
retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Enabling TRANS FM fail %d\n", retval);
radio->mode = FM_OFF;
goto END;
} else {
retval = initialise_trans(radio);
if (retval < 0) {
FMDERR("Error while initialising");
FMDERR("radio %d\n", retval);
hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
radio->fm_hdev);
radio->mode = FM_OFF;
goto END;
}
}
if (radio->mode == FM_TRANS_TURNING_ON) {
radio->mode = FM_TRANS;
iris_q_event(radio, IRIS_EVT_RADIO_READY);
}
break;
case FM_OFF:
radio->spur_table_size = 0;
switch (radio->mode) {
case FM_RECV:
radio->mode = FM_TURNING_OFF;
retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Err on disable recv FM");
FMDERR("%d\n", retval);
radio->mode = FM_RECV;
goto END;
}
break;
case FM_TRANS:
radio->mode = FM_TURNING_OFF;
retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Err disabling trans FM");
FMDERR("%d\n", retval);
radio->mode = FM_TRANS;
goto END;
}
break;
default:
retval = -EINVAL;
}
break;
default:
retval = -EINVAL;
}
break;
case V4L2_CID_PRIVATE_IRIS_REGION:
if (radio->mode == FM_RECV) {
retval = iris_recv_set_region(radio, ctrl->value);
} else {
if (radio->mode == FM_TRANS) {
retval = iris_trans_set_region(radio,
ctrl->value);
} else {
FMDERR("%s: fm is not in proper state\n",
__func__);
retval = -EINVAL;
goto END;
}
}
break;
case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
if (!is_valid_sig_th(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: sig threshold is not valid\n", __func__);
goto END;
}
temp_val = ctrl->value;
retval = hci_fm_set_signal_threshold(
&temp_val,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error while setting signal threshold\n");
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
if (is_valid_pty(ctrl->value)) {
radio->srch_rds.srch_pty = ctrl->value;
radio->srch_st_list.srch_pty = ctrl->value;
} else {
FMDERR("%s: pty is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
if (is_valid_pi(ctrl->value)) {
radio->srch_rds.srch_pi = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: Pi is not valid\n", __func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
if (is_valid_srch_station_cnt(ctrl->value)) {
radio->srch_st_list.srch_list_max = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: srch station count is not valid\n",
__func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SPACING:
if (!is_valid_chan_spacing(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: channel spacing is not valid\n", __func__);
goto END;
}
if (radio->mode == FM_RECV) {
saved_val = radio->recv_conf.ch_spacing;
radio->recv_conf.ch_spacing = ctrl->value;
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in setting channel spacing");
radio->recv_conf.ch_spacing = saved_val;
goto END;
}
}
break;
case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
if (!is_valid_emphasis(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s, emphasis is not valid\n", __func__);
goto END;
}
switch (radio->mode) {
case FM_RECV:
saved_val = radio->recv_conf.emphasis;
radio->recv_conf.emphasis = ctrl->value;
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in setting emphasis");
radio->recv_conf.emphasis = saved_val;
goto END;
}
break;
case FM_TRANS:
saved_val = radio->trans_conf.emphasis;
radio->trans_conf.emphasis = ctrl->value;
retval = hci_set_fm_trans_conf(
&radio->trans_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in setting emphasis");
radio->trans_conf.emphasis = saved_val;
goto END;
}
break;
default:
retval = -EINVAL;
FMDERR("FM mode is unknown %d\n", radio->mode);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RDS_STD:
if (!is_valid_rds_std(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: rds std is not valid\n", __func__);
goto END;
}
switch (radio->mode) {
case FM_RECV:
saved_val = radio->recv_conf.rds_std;
radio->recv_conf.rds_std = ctrl->value;
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in rds_std");
radio->recv_conf.rds_std = saved_val;
goto END;
}
break;
case FM_TRANS:
saved_val = radio->trans_conf.rds_std;
radio->trans_conf.rds_std = ctrl->value;
retval = hci_set_fm_trans_conf(
&radio->trans_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in rds_Std");
radio->trans_conf.rds_std = saved_val;
goto END;
}
break;
default:
retval = -EINVAL;
FMDERR("%s: fm is not in proper state\n", __func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RDSON:
if (!is_valid_rds_std(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: rds std is not valid\n", __func__);
goto END;
}
switch (radio->mode) {
case FM_RECV:
saved_val = radio->recv_conf.rds_std;
radio->recv_conf.rds_std = ctrl->value;
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in rds_std");
radio->recv_conf.rds_std = saved_val;
goto END;
}
break;
case FM_TRANS:
saved_val = radio->trans_conf.rds_std;
radio->trans_conf.rds_std = ctrl->value;
retval = hci_set_fm_trans_conf(
&radio->trans_conf,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error in rds_Std");
radio->trans_conf.rds_std = saved_val;
goto END;
}
break;
default:
retval = -EINVAL;
FMDERR("%s: fm is not in proper state\n", __func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
saved_val = radio->rds_grp.rds_grp_enable_mask;
grp_mask = (grp_mask | oda_agt | ctrl->value);
radio->rds_grp.rds_grp_enable_mask = grp_mask;
radio->rds_grp.rds_buf_size = 1;
radio->rds_grp.en_rds_change_filter = 0;
retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
if (retval < 0) {
FMDERR("error in setting group mask\n");
radio->rds_grp.rds_grp_enable_mask = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
saved_val = radio->g_rds_grp_proc_ps;
rds_grps_proc = radio->g_rds_grp_proc_ps | ctrl->value;
radio->g_rds_grp_proc_ps = (rds_grps_proc >> RDS_CONFIG_OFFSET);
retval = hci_fm_rds_grps_process(
&radio->g_rds_grp_proc_ps,
radio->fm_hdev);
if (retval < 0) {
radio->g_rds_grp_proc_ps = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
radio->rds_grp.rds_buf_size = ctrl->value;
break;
case V4L2_CID_PRIVATE_IRIS_PSALL:
saved_val = radio->g_rds_grp_proc_ps;
rds_grps_proc = (ctrl->value << RDS_CONFIG_OFFSET);
radio->g_rds_grp_proc_ps |= rds_grps_proc;
retval = hci_fm_rds_grps_process(
&radio->g_rds_grp_proc_ps,
radio->fm_hdev);
if (retval < 0) {
radio->g_rds_grp_proc_ps = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_AF_JUMP:
saved_val = radio->g_rds_grp_proc_ps;
/*Clear the current AF jump settings*/
radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
radio->af_jump_bit = ctrl->value;
rds_grps_proc = 0x00;
rds_grps_proc = (ctrl->value << RDS_AF_JUMP_OFFSET);
radio->g_rds_grp_proc_ps |= rds_grps_proc;
retval = hci_fm_rds_grps_process(
&radio->g_rds_grp_proc_ps,
radio->fm_hdev);
if (retval < 0) {
radio->g_rds_grp_proc_ps = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_LP_MODE:
set_low_power_mode(radio, ctrl->value);
break;
case V4L2_CID_PRIVATE_IRIS_ANTENNA:
if (!is_valid_antenna(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: antenna type is not valid\n", __func__);
goto END;
}
temp_val = ctrl->value;
retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
if (retval < 0) {
FMDERR("Set Antenna failed retval = %x", retval);
goto END;
}
radio->g_antenna = ctrl->value;
break;
case V4L2_CID_RDS_TX_PTY:
if (is_valid_pty(ctrl->value)) {
radio->pty = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: pty is not valid\n", __func__);
goto END;
}
break;
case V4L2_CID_RDS_TX_PI:
if (is_valid_pi(ctrl->value)) {
radio->pi = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: pi is not valid\n", __func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
tx_ps.ps_control = 0x00;
retval = radio_hci_request(radio->fm_hdev, hci_trans_ps_req,
(unsigned long)&tx_ps, RADIO_HCI_TIMEOUT);
break;
case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
tx_rt.rt_control = 0x00;
retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
break;
case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
if (is_valid_ps_repeat_cnt(ctrl->value)) {
radio->ps_repeatcount = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: ps repeat count is not valid\n", __func__);
goto END;
}
break;
case V4L2_CID_TUNE_POWER_LEVEL:
if (ctrl->value > FM_TX_PWR_LVL_MAX)
ctrl->value = FM_TX_PWR_LVL_MAX;
if (ctrl->value < FM_TX_PWR_LVL_0)
ctrl->value = FM_TX_PWR_LVL_0;
rd.mode = FM_TX_PHY_CFG_MODE;
rd.length = FM_TX_PHY_CFG_LEN;
rd.param_len = 0x00;
rd.param = 0x00;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("Default data read failed for PHY_CFG %d\n",
retval);
goto END;
}
memset(&wrd, 0, sizeof(wrd));
wrd.mode = FM_TX_PHY_CFG_MODE;
wrd.length = FM_TX_PHY_CFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[FM_TX_PWR_GAIN_OFFSET] =
(ctrl->value) * FM_TX_PWR_LVL_STEP_SIZE;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("Default write failed for PHY_TXGAIN %d\n",
retval);
break;
case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
if (!is_valid_soft_mute(ctrl->value)) {
retval = -EINVAL;
FMDERR("%s: soft mute is not valid\n", __func__);
goto END;
}
saved_val = radio->mute_mode.soft_mute;
radio->mute_mode.soft_mute = ctrl->value;
retval = hci_set_fm_mute_mode(
&radio->mute_mode,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error while setting FM soft mute"" %d\n",
retval);
radio->mute_mode.soft_mute = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR:
radio->riva_data_req.cmd_params.start_addr = ctrl->value;
break;
case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN:
if (is_valid_peek_len(ctrl->value)) {
radio->riva_data_req.cmd_params.length = ctrl->value;
} else {
retval = -EINVAL;
FMDERR("%s: riva access len is not valid\n", __func__);
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
if (radio->riva_data_req.cmd_params.length <=
MAX_RIVA_PEEK_RSP_SIZE) {
#ifdef CONFIG_COMPAT
retval = copy_from_user(
radio->riva_data_req.data,
(void *)(__s64)ctrl->value,
radio->riva_data_req.cmd_params.length);
#else
retval = copy_from_user(
radio->riva_data_req.data,
(void *)ctrl->value,
radio->riva_data_req.cmd_params.length);
#endif
if (retval != 0) {
retval = -retval;
goto END;
}
radio->riva_data_req.cmd_params.subopcode =
RIVA_POKE_OPCODE;
retval = hci_poke_data(
&radio->riva_data_req,
radio->fm_hdev);
} else {
FMDERR("Can not copy into driver's buffer.\n");
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
radio->ssbi_data_accs.start_addr = ctrl->value;
break;
case V4L2_CID_PRIVATE_IRIS_SSBI_POKE:
radio->ssbi_data_accs.data = ctrl->value;
retval = hci_ssbi_poke_reg(&radio->ssbi_data_accs ,
radio->fm_hdev);
break;
case V4L2_CID_PRIVATE_IRIS_RIVA_PEEK:
radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
ctrl->value = hci_peek_data(&radio->riva_data_req.cmd_params ,
radio->fm_hdev);
break;
case V4L2_CID_PRIVATE_IRIS_SSBI_PEEK:
radio->ssbi_peek_reg.start_address = ctrl->value;
hci_ssbi_peek_reg(&radio->ssbi_peek_reg, radio->fm_hdev);
break;
case V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS:
if (is_valid_reset_cntr(ctrl->value)) {
temp_val = ctrl->value;
hci_read_grp_counters(&temp_val, radio->fm_hdev);
} else {
FMDERR("%s: reset counter value is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_HLSI:
if (!is_valid_hlsi(ctrl->value)) {
FMDERR("%s: hlsi value is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
radio->fm_hdev);
if (retval)
goto END;
saved_val = radio->recv_conf.hlsi;
radio->recv_conf.hlsi = ctrl->value;
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
if (retval < 0)
radio->recv_conf.hlsi = saved_val;
break;
case V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER:
if (is_valid_notch_filter(ctrl->value)) {
temp_val = ctrl->value;
retval = hci_set_notch_filter(&temp_val,
radio->fm_hdev);
} else {
FMDERR("%s: notch filter is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
break;
case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
if (!is_valid_intf_det_hgh_th(ctrl->value)) {
FMDERR("%s: intf high threshold is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get chnl det thresholds %d", retval);
goto END;
}
saved_val = radio->ch_det_threshold.high_th;
radio->ch_det_threshold.high_th = ctrl->value;
retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to set High det threshold %d ", retval);
radio->ch_det_threshold.high_th = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
if (!is_valid_intf_det_low_th(ctrl->value)) {
FMDERR("%s: intf det low threshold is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get chnl det thresholds %d", retval);
goto END;
}
saved_val = radio->ch_det_threshold.low_th;
radio->ch_det_threshold.low_th = ctrl->value;
retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to Set Low det threshold %d", retval);
radio->ch_det_threshold.low_th = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_SINR_THRESHOLD:
if (!is_valid_sinr_th(ctrl->value)) {
FMDERR("%s: sinr threshold is not valid\n", __func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get chnl det thresholds %d", retval);
goto END;
}
saved_val = radio->ch_det_threshold.sinr;
radio->ch_det_threshold.sinr = ctrl->value;
retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to set SINR threshold %d", retval);
radio->ch_det_threshold.sinr = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_SINR_SAMPLES:
if (!is_valid_sinr_samples(ctrl->value)) {
FMDERR("%s: sinr samples count is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get chnl det thresholds %d", retval);
goto END;
}
saved_val = radio->ch_det_threshold.sinr_samples;
radio->ch_det_threshold.sinr_samples = ctrl->value;
retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to set SINR samples %d", retval);
radio->ch_det_threshold.sinr_samples = saved_val;
goto END;
}
break;
case V4L2_CID_PRIVATE_IRIS_SRCH_ALGORITHM:
case V4L2_CID_PRIVATE_IRIS_SET_AUDIO_PATH:
/*
These private controls are place holders to keep the
driver compatible with changes done in the frameworks
which are specific to TAVARUA.
*/
retval = 0;
break;
case V4L2_CID_PRIVATE_SPUR_FREQ:
if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
FMDERR("%s: Spur Table Full!\n", __func__);
retval = -1;
} else
radio->spur_data.freq[radio->spur_table_size] =
ctrl->value;
break;
case V4L2_CID_PRIVATE_SPUR_FREQ_RMSSI:
if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
FMDERR("%s: Spur Table Full!\n", __func__);
retval = -1;
} else
radio->spur_data.rmssi[radio->spur_table_size] =
ctrl->value;
break;
case V4L2_CID_PRIVATE_SPUR_SELECTION:
if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
FMDERR("%s: Spur Table Full!\n", __func__);
retval = -1;
} else {
radio->spur_data.enable[radio->spur_table_size] =
ctrl->value;
radio->spur_table_size++;
}
break;
case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
update_spur_table(radio);
break;
case V4L2_CID_PRIVATE_VALID_CHANNEL:
retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("%s: Failed to determine channel's validity\n",
__func__);
goto END;
} else {
sinr_th = radio->ch_det_threshold.sinr;
intf_det_low_th = radio->ch_det_threshold.low_th;
intf_det_high_th = radio->ch_det_threshold.high_th;
}
if (!is_valid_sinr_th(sinr_th) ||
!is_valid_intf_det_low_th(intf_det_low_th) ||
!is_valid_intf_det_hgh_th(intf_det_high_th)) {
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("%s: Failed to determine channel's validity\n",
__func__);
goto END;
} else
sinr = radio->fm_st_rsp.station_rsp.sinr;
retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("%s: Failed to determine channel's validity\n",
__func__);
goto END;
} else
intf_det_out = radio->st_dbg_param.in_det_out;
if ((sinr >= sinr_th) && (intf_det_out >= intf_det_low_th) &&
(intf_det_out <= intf_det_high_th))
radio->is_station_valid = VALID_CHANNEL;
else
radio->is_station_valid = INVALID_CHANNEL;
break;
case V4L2_CID_PRIVATE_AF_RMSSI_TH:
rd.mode = FM_RDS_CNFG_MODE;
rd.length = FM_RDS_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RDS_CNFG_MODE;
wrd.length = FM_RDS_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[AF_RMSSI_TH_LSB_OFFSET] = ((ctrl->value) & 255);
wrd.data[AF_RMSSI_TH_MSB_OFFSET] = ((ctrl->value) >> 8);
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set AF jump RMSSI threshold failed\n");
break;
case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
rd.mode = FM_RDS_CNFG_MODE;
rd.length = FM_RDS_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RDS_CNFG_MODE;
wrd.length = FM_RDS_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[AF_RMSSI_SAMPLES_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set AF jump RMSSI Samples failed\n");
break;
case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
rd.mode = FM_RX_CONFG_MODE;
rd.length = FM_RX_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RX_CONFG_MODE;
wrd.length = FM_RX_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[GD_CH_RMSSI_TH_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set good channel RMSSI th failed\n");
break;
case V4L2_CID_PRIVATE_SRCHALGOTYPE:
rd.mode = FM_RX_CONFG_MODE;
rd.length = FM_RX_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RX_CONFG_MODE;
wrd.length = FM_RX_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[SRCH_ALGO_TYPE_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set Search Algo Type failed\n");
break;
case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
rd.mode = FM_RX_CONFG_MODE;
rd.length = FM_RX_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RX_CONFG_MODE;
wrd.length = FM_RX_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[SINRFIRSTSTAGE_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set SINR First Stage failed\n");
break;
case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
rd.mode = FM_RX_CONFG_MODE;
rd.length = FM_RX_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RX_CONFG_MODE;
wrd.length = FM_RX_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[RMSSIFIRSTSTAGE_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set RMSSI First Stage failed\n");
break;
case V4L2_CID_PRIVATE_CF0TH12:
rd.mode = FM_RX_CONFG_MODE;
rd.length = FM_RX_CNFG_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed %x", retval);
goto END;
}
wrd.mode = FM_RX_CONFG_MODE;
wrd.length = FM_RX_CNFG_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[CF0TH12_BYTE1_OFFSET] = (ctrl->value & 255);
wrd.data[CF0TH12_BYTE2_OFFSET] = ((ctrl->value >> 8) & 255);
wrd.data[CF0TH12_BYTE3_OFFSET] = ((ctrl->value >> 16) & 255);
wrd.data[CF0TH12_BYTE4_OFFSET] = ((ctrl->value >> 24) & 255);
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set CF0 Threshold failed\n");
break;
case V4L2_CID_PRIVATE_RXREPEATCOUNT:
rd.mode = RDS_PS0_XFR_MODE;
rd.length = RDS_PS0_LEN;
rd.param_len = 0;
rd.param = 0;
retval = hci_def_data_read(&rd, radio->fm_hdev);
if (retval < 0) {
FMDERR("default data read failed for PS0 %x", retval);
goto END;
}
wrd.mode = RDS_PS0_XFR_MODE;
wrd.length = RDS_PS0_LEN;
memcpy(&wrd.data, &radio->default_data.data,
radio->default_data.ret_data_len);
wrd.data[RX_REPEATE_BYTE_OFFSET] = ctrl->value;
retval = hci_def_data_write(&wrd, radio->fm_hdev);
if (retval < 0)
FMDERR("set RxRePeat count failed\n");
break;
case V4L2_CID_PRIVATE_IRIS_GET_SPUR_TBL:
spur_freq = ctrl->value;
retval = radio_hci_request(radio->fm_hdev,
hci_fm_get_spur_tbl_data,
(unsigned long)spur_freq,
RADIO_HCI_TIMEOUT);
if (retval < 0)
FMDERR("get Spur data failed\n");
break;
case V4L2_CID_PRIVATE_BLEND_SINRHI:
if (!is_valid_blend_value(ctrl->value)) {
FMDERR("%s: blend sinr count is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get blend table %d", retval);
goto END;
}
radio->blend_tbl.scBlendSinrHi = ctrl->value;
retval = hci_set_blend_tbl_req(&radio->blend_tbl,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to set blend tble %d ", retval);
goto END;
}
break;
case V4L2_CID_PRIVATE_BLEND_RMSSIHI:
if (!is_valid_blend_value(ctrl->value)) {
FMDERR("%s: blend rmssi count is not valid\n",
__func__);
retval = -EINVAL;
goto END;
}
retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to get blend table %d", retval);
goto END;
}
radio->blend_tbl.scBlendRmssiHi = ctrl->value;
retval = hci_set_blend_tbl_req(&radio->blend_tbl,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Failed to set blend tble %d ", retval);
goto END;
}
break;
default:
retval = -EINVAL;
break;
}
END:
if (retval > 0)
retval = -EINVAL;
return retval;
}