static int iris_vidioc_s_ctrl()

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;
}