Merge "radio: iris: Bound check user space values"
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 188673d..9f18508 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -2391,6 +2391,7 @@
 		struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	radio->search_on = 0;
 	iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
 }
 
@@ -2920,6 +2921,7 @@
 {
 	int retval = 0;
 	enum search_t srch;
+	int saved_val;
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
@@ -2927,6 +2929,7 @@
 	}
 
 	srch = radio->g_search_mode & SRCH_MODE;
+	saved_val = radio->search_on;
 	radio->search_on = on;
 	if (on) {
 		switch (srch) {
@@ -2961,6 +2964,8 @@
 		retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
 	}
 
+	if (retval < 0)
+		radio->search_on = saved_val;
 	return retval;
 }
 
@@ -3013,18 +3018,22 @@
 static int iris_recv_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+	int saved_val;
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
-
+	saved_val = radio->region;
 	radio->region = req_region;
 
 	retval = hci_set_fm_recv_conf(
 			&radio->recv_conf,
 			radio->fm_hdev);
 
+	if (retval < 0)
+		radio->region = saved_val;
+
 	return retval;
 }
 
@@ -3032,16 +3041,22 @@
 static int iris_trans_set_region(struct iris_device *radio, int req_region)
 {
 	int retval;
+	int saved_val;
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
 		return -EINVAL;
 	}
+
+	saved_val = radio->region;
 	radio->region = req_region;
 
 	retval = hci_set_fm_trans_conf(
 			&radio->trans_conf,
 				radio->fm_hdev);
+
+	if (retval < 0)
+		radio->region = saved_val;
 	return retval;
 }
 
@@ -3129,30 +3144,44 @@
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
 	if (unlikely(ctrl == NULL)) {
 		FMDERR("%s, v4l2 ctrl is null\n", __func__);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = radio->mute_mode.hard_mute;
+		if (is_valid_hard_mute(radio->mute_mode.hard_mute))
+			ctrl->value = radio->mute_mode.hard_mute;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
-		ctrl->value = radio->g_search_mode;
+		if (is_valid_srch_mode(radio->g_search_mode))
+			ctrl->value = radio->g_search_mode;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
-		ctrl->value = radio->g_scan_time;
+		if (is_valid_scan_dwell_prd(radio->g_scan_time))
+			ctrl->value = radio->g_scan_time;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHON:
 		ctrl->value = radio->search_on;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_STATE:
-		ctrl->value = radio->mode;
+		if (is_valid_fm_state(radio->mode))
+			ctrl->value = radio->mode;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_IOVERC:
 		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
@@ -3162,68 +3191,115 @@
 		break;
 	case V4L2_CID_PRIVATE_IRIS_INTDET:
 		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
-		if (retval < 0)
-			return retval;
-		ctrl->value = radio->st_dbg_param.in_det_out;
+		if (retval == 0)
+			ctrl->value = radio->st_dbg_param.in_det_out;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_REGION:
 		ctrl->value = radio->region;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
 		retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Error in get signal threshold %d\n", retval);
-			return retval;
-		}
-		ctrl->value = radio->sig_th.sig_threshold;
+		if ((retval == 0) &&
+			is_valid_sig_th(radio->sig_th.sig_threshold))
+			ctrl->value = radio->sig_th.sig_threshold;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
-		ctrl->value = radio->srch_rds.srch_pty;
+		if (is_valid_pty(radio->srch_rds.srch_pty))
+			ctrl->value = radio->srch_rds.srch_pty;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
-		ctrl->value = radio->srch_rds.srch_pi;
+		if (is_valid_pi(radio->srch_rds.srch_pi))
+			ctrl->value = radio->srch_rds.srch_pi;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
-		ctrl->value = radio->srch_st_result.num_stations_found;
+		if (is_valid_srch_station_cnt(
+			radio->srch_st_result.num_stations_found))
+			ctrl->value = radio->srch_st_result.num_stations_found;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.emphasis;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->recv_conf.emphasis))
+				ctrl->value = radio->recv_conf.emphasis;
+			else
+				retval = -EINVAL;
 		} else if (radio->mode == FM_TRANS) {
-			ctrl->value = radio->trans_conf.emphasis;
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->trans_conf.emphasis))
+				ctrl->value = radio->trans_conf.emphasis;
+			else
+				retval = -EINVAL;
 		} else {
-			FMDERR("Error in radio mode"
-				" %d\n", retval);
-			return -EINVAL;
+			retval = -EINVAL;
+			FMDERR("Error in radio mode"" %d\n", retval);
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDS_STD:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.rds_std;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else if (radio->mode == FM_TRANS) {
-			ctrl->value = radio->trans_conf.rds_std;
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->trans_conf.rds_std))
+				ctrl->value = radio->trans_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SPACING:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.ch_spacing;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_chan_spacing(
+						radio->recv_conf.ch_spacing))
+				ctrl->value = radio->recv_conf.ch_spacing;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSON:
 		if (radio->mode == FM_RECV) {
-			ctrl->value = radio->recv_conf.rds_std;
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
 		} else {
+			retval = -EINVAL;
 			FMDERR("Error in radio mode"
 				" %d\n", retval);
-			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
@@ -3243,7 +3319,12 @@
 		ctrl->value = radio->g_antenna;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
-		ctrl->value = radio->mute_mode.soft_mute;
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if ((retval == 0) &&
+			is_valid_soft_mute(radio->mute_mode.soft_mute))
+			ctrl->value = radio->mute_mode.soft_mute;
+		else
+			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION:
 		retval = iris_do_calibration(radio);
@@ -3252,47 +3333,30 @@
 		if (radio->mode == FM_RECV) {
 			retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD,
 						 radio->fm_hdev);
-			if (retval < 0) {
-				FMDERR("Get SINR Failed");
-				return retval;
-			}
-			ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
-
+			if (retval == 0)
+				ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
 		} else
 			retval = -EINVAL;
 		break;
 	case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get High det threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.high_th;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.high_th;
 		break;
 	case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get Low det threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.low_th;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.low_th;
 		break;
 	case V4L2_CID_PRIVATE_SINR_THRESHOLD:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get SINR threshold failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->ch_det_threshold.sinr;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr;
 		break;
 	case V4L2_CID_PRIVATE_SINR_SAMPLES:
 		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get SINR samples failed %x", retval);
-			return retval;
-		}
-
-		ctrl->value = radio->ch_det_threshold.sinr_samples;
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr_samples;
 		break;
 	case V4L2_CID_PRIVATE_VALID_CHANNEL:
 		ctrl->value = radio->is_station_valid;
@@ -3304,13 +3368,11 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get AF Jump Threshold failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
+			msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
+			ctrl->value = ((msb << 8) | lsb);
 		}
-		lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
-		msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
-		ctrl->value = ((msb << 8) | lsb);
 		break;
 	case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
 		rd.mode = FM_RDS_CNFG_MODE;
@@ -3319,11 +3381,9 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("Get AF jump rmssi samples failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
 		break;
 	case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3332,13 +3392,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("get good channel rmssi th failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
+			if (ctrl->value > MAX_GD_CH_RMSSI_TH)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
-		if (ctrl->value > MAX_GD_CH_RMSSI_TH)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_SRCHALGOTYPE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3347,11 +3406,9 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("get search algo type failed %x", retval);
-			return retval;
-		}
-		ctrl->value = radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
 		break;
 	case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3360,13 +3417,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_SINR_FIRSTSTAGE)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
-		if (ctrl->value > MAX_SINR_FIRSTSTAGE)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3375,13 +3431,12 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
+				ctrl->value -= 256;
 		}
-		ctrl->value = radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
-		if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
-			ctrl->value -= 256;
 		break;
 	case V4L2_CID_PRIVATE_CF0TH12:
 		rd.mode = FM_RX_CONFG_MODE;
@@ -3390,26 +3445,31 @@
 		rd.param = 0;
 
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
-		if (retval < 0) {
-			FMDERR("default data read failed %x", retval);
-			return retval;
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[CF0TH12_BYTE1_OFFSET];
+			cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
+			ctrl->value |= (cf0 << 8);
+			cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
+			ctrl->value |= (cf0 << 16);
+			cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
+			if (cf0 > 127)
+				cf0 -= 256;
+			ctrl->value |= (cf0 << 24);
 		}
-		ctrl->value = radio->default_data.data[CF0TH12_BYTE1_OFFSET];
-		cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
-		ctrl->value |= (cf0 << 8);
-		cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
-		ctrl->value |= (cf0 << 16);
-		cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
-		if (cf0 > 127)
-			cf0 -= 256;
-		ctrl->value |= (cf0 << 24);
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
 	if (retval < 0)
 		FMDERR("get control failed with %d, id: %d\n",
 			retval, ctrl->id);
+
 	return retval;
 }
 
@@ -3423,27 +3483,36 @@
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
 	if (unlikely((ctrl == NULL)) || unlikely((ctrl->count == 0))
 		|| unlikely((ctrl->controls == NULL))) {
 		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 	switch ((ctrl->controls[0]).id) {
 	case V4L2_CID_PRIVATE_IRIS_READ_DEFAULT:
 		data = (ctrl->controls[0]).string;
 		memset(&default_data_rd, 0, sizeof(default_data_rd));
 		if (copy_from_user(&default_data_rd.mode, data,
-					sizeof(default_data_rd)))
-			return -EFAULT;
+					sizeof(default_data_rd))) {
+			retval = -EFAULT;
+			goto END;
+		}
 		retval = hci_def_data_read(&default_data_rd, radio->fm_hdev);
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
 
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
@@ -3462,13 +3531,15 @@
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
 	if (unlikely((ctrl == NULL)) || unlikely((ctrl->count == 0))
 		|| unlikely((ctrl->controls == NULL))) {
 		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
 	switch ((ctrl->controls[0]).id) {
@@ -3482,16 +3553,23 @@
 		data = (ctrl->controls[0]).string;
 
 		if (copy_from_user(tx_ps.ps_data,
-				data, bytes_to_copy))
-				return -EFAULT;
-		tx_ps.ps_control =  0x01;
-		tx_ps.pi = radio->pi;
-		tx_ps.pty = radio->pty;
-		tx_ps.ps_repeatcount = radio->ps_repeatcount;
-		tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx ps name failed\n",
+				__func__);
+			retval = -EFAULT;
+			goto END;
+		} else {
+			tx_ps.ps_control =  0x01;
+			tx_ps.pi = radio->pi;
+			tx_ps.pty = radio->pty;
+			tx_ps.ps_repeatcount = radio->ps_repeatcount;
+			tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
 
-		retval = radio_hci_request(radio->fm_hdev, hci_trans_ps_req,
-				(unsigned long)&tx_ps, RADIO_HCI_TIMEOUT);
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_ps_req,
+							(unsigned long)&tx_ps,
+							RADIO_HCI_TIMEOUT);
+		}
 		break;
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		bytes_to_copy =
@@ -3501,16 +3579,22 @@
 		memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
 
 		if (copy_from_user(tx_rt.rt_data,
-				data, bytes_to_copy))
-				return -EFAULT;
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx rt failed\n",
+				 __func__);
+			retval = -EFAULT;
+			goto END;
+		} else {
+			tx_rt.rt_control = 0x01;
+			tx_rt.pi = radio->pi;
+			tx_rt.pty = radio->pty;
+			tx_rt.rt_len = bytes_to_copy;
 
-		tx_rt.rt_control =  0x01;
-		tx_rt.pi = radio->pi;
-		tx_rt.pty = radio->pty;
-		tx_rt.rt_len = bytes_to_copy;
-
-		retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
-				(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_rt_req,
+							(unsigned long)&tx_rt,
+							RADIO_HCI_TIMEOUT);
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT:
 		data = (ctrl->controls[0]).string;
@@ -3525,7 +3609,8 @@
 		 */
 		if (ctrl->controls[0].size > (DEFAULT_DATA_SIZE + 2)) {
 			pr_err("%s: Default data buffer overflow!\n", __func__);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto END;
 		}
 
 		/* copy only 'size' bytes of data as requested by user */
@@ -3534,7 +3619,8 @@
 		if (retval > 0) {
 			pr_err("%s: Failed to copy %d bytes of default data"
 				" passed by user\n", __func__, retval);
-			return -EFAULT;
+			retval = -EFAULT;
+			goto END;
 		}
 		FMDBG("%s: XFR Mode\t: 0x%x\n", __func__, default_data.mode);
 		FMDBG("%s: XFR Data Length\t: %d\n", __func__,
@@ -3549,7 +3635,8 @@
 		if (default_data.length != (ctrl->controls[0].size - 2)) {
 			pr_err("%s: Invalid 'length' parameter passed for "
 				"actual xfr data\n", __func__);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto END;
 		}
 		retval = hci_def_data_write(&default_data, radio->fm_hdev);
 		break;
@@ -3558,24 +3645,32 @@
 		bytes_to_copy = (ctrl->controls[0]).size;
 		if (bytes_to_copy < PROCS_CALIB_SIZE) {
 			FMDERR("data is less than required size");
-			return -EFAULT;
+			retval = -EFAULT;
+			goto END;
 		}
 		memset(proc_cal_req.data, 0, PROCS_CALIB_SIZE);
 		proc_cal_req.mode = PROCS_CALIB_MODE;
 		if (copy_from_user(&proc_cal_req.data[0],
-				data, sizeof(proc_cal_req.data)))
-				return -EFAULT;
+				data, sizeof(proc_cal_req.data))) {
+			retval = -EFAULT;
+			goto END;
+		}
 		retval = radio_hci_request(radio->fm_hdev,
 				hci_fm_set_cal_req_proc,
 				(unsigned long)&proc_cal_req,
 				 RADIO_HCI_TIMEOUT);
-		if (retval < 0)
-			FMDERR("Set Process calibration failed %d", retval);
 		break;
 	default:
 		FMDBG("Shouldn't reach here\n");
 		retval = -1;
+		goto END;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
@@ -3586,6 +3681,7 @@
 	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};
@@ -3596,39 +3692,69 @@
 
 	if (unlikely(radio == NULL)) {
 		FMDERR(":radio is null");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 
 	if (unlikely(ctrl == NULL)) {
 		FMDERR("%s, v4l2 ctrl is null\n", __func__);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto END;
 	}
 	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,
 				msecs_to_jiffies(RADIO_HCI_TIMEOUT));
-		if (retval < 0)
+		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;
 		radio->mute_mode.soft_mute = IOC_SFT_MUTE;
 		retval = hci_set_fm_mute_mode(
 				&radio->mute_mode,
 				radio->fm_hdev);
-		if (retval < 0)
+		if (retval < 0) {
 			FMDERR("Error while set FM hard mute"" %d\n",
-			retval);
+				retval);
+			radio->mute_mode.hard_mute = saved_val;
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
-		radio->g_search_mode = ctrl->value;
+		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:
-		radio->g_scan_time = ctrl->value;
+		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);
@@ -3636,8 +3762,12 @@
 	case V4L2_CID_PRIVATE_IRIS_STATE:
 		switch (ctrl->value) {
 		case FM_RECV:
-			if (is_enable_rx_possible(radio) != 0)
-				return -EINVAL;
+			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);
@@ -3645,14 +3775,16 @@
 				FMDERR("Error while enabling RECV FM"
 							" %d\n", retval);
 				radio->mode = FM_OFF;
-				return retval;
+				goto END;
 			} else {
 				initialise_recv(radio);
 			}
 			break;
 		case FM_TRANS:
-			if (is_enable_tx_possible(radio) != 0)
-				return -EINVAL;
+			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);
@@ -3660,7 +3792,7 @@
 				FMDERR("Error while enabling TRANS FM"
 							" %d\n", retval);
 				radio->mode = FM_OFF;
-				return retval;
+				goto END;
 			} else {
 				initialise_trans(radio);
 			}
@@ -3676,7 +3808,7 @@
 					FMDERR("Err on disable recv FM"
 						   " %d\n", retval);
 					radio->mode = FM_RECV;
-					return retval;
+					goto END;
 				}
 				break;
 			case FM_TRANS:
@@ -3688,7 +3820,7 @@
 					FMDERR("Err disabling trans FM"
 						" %d\n", retval);
 					radio->mode = FM_TRANS;
-					return retval;
+					goto END;
 				}
 				break;
 			default:
@@ -3703,136 +3835,236 @@
 		if (radio->mode == FM_RECV) {
 			retval = iris_recv_set_region(radio, ctrl->value);
 		} else {
-			if (radio->mode == FM_TRANS)
+			if (radio->mode == FM_TRANS) {
 				retval = iris_trans_set_region(radio,
 						ctrl->value);
-			else
+			} 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");
-			break;
+			goto END;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
-		radio->srch_rds.srch_pty = ctrl->value;
-		radio->srch_st_list.srch_pty = ctrl->value;
+		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:
-		radio->srch_rds.srch_pi = ctrl->value;
+		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:
-		radio->srch_st_list.srch_list_max = ctrl->value;
+		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)
+			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)
+			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)
+			if (retval < 0) {
 				FMDERR("Error in setting emphasis");
+				radio->trans_conf.emphasis = saved_val;
+				goto END;
+			}
 			break;
 		default:
 			retval = -EINVAL;
+			FMDERR("%s, FM is not in proper state\n", __func__);
+			goto END;
+			break;
 		}
 		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)
+			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)
+			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;
 		}
 		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)
+			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)
+			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;
 		}
 		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)
+		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;
@@ -3842,24 +4074,45 @@
 		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);
-			return retval;
+			goto END;
 		}
 		radio->g_antenna =  ctrl->value;
 		break;
 	case V4L2_CID_RDS_TX_PTY:
-		radio->pty = ctrl->value;
+		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:
-		radio->pi = ctrl->value;
+		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;
@@ -3872,7 +4125,13 @@
 				(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
-		radio->ps_repeatcount = ctrl->value;
+		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)
@@ -3887,8 +4146,8 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("Default data read failed for PHY_CFG %d\n",
-			retval);
-			break;
+				retval);
+			goto END;
 		}
 		memset(&wrd, 0, sizeof(wrd));
 		wrd.mode = FM_TX_PHY_CFG_MODE;
@@ -3900,48 +4159,58 @@
 		retval = hci_def_data_write(&wrd, radio->fm_hdev);
 		if (retval < 0)
 			FMDERR("Default write failed for PHY_TXGAIN %d\n",
-			retval);
+				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)
+		if (retval < 0) {
 			FMDERR("Error while setting FM soft mute"" %d\n",
-			retval);
+				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 ((ctrl->value > 0) &&
-			(ctrl->value <= MAX_RIVA_PEEK_RSP_SIZE)) {
+		if (is_valid_peek_len(ctrl->value)) {
 			radio->riva_data_req.cmd_params.length = ctrl->value;
 		} else {
-			FMDERR("Length %d is more than the buffer size %d\n",
-			ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
 			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) {
-			retval = copy_from_user(radio->riva_data_req.data,
-						(void *)ctrl->value,
-						radio->riva_data_req.cmd_params.length);
-			if (retval == 0) {
-				radio->riva_data_req.cmd_params.subopcode =
-									RIVA_POKE_OPCODE;
-				retval = hci_poke_data(&radio->riva_data_req,
-							radio->fm_hdev);
-			} else {
-				retval = -EINVAL;
+		if (radio->riva_data_req.cmd_params.length <=
+		    MAX_RIVA_PEEK_RSP_SIZE) {
+			retval = copy_from_user(
+					radio->riva_data_req.data,
+					(void *)ctrl->value,
+					radio->riva_data_req.cmd_params.length);
+			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. Length %d is more than"
-			 "the buffer size %d\n", radio->riva_data_req.cmd_params.length,
-				MAX_RIVA_PEEK_RSP_SIZE);
+			FMDERR("Can not copy into driver's buffer.\n");
 			retval = -EINVAL;
+			goto END;
 		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
@@ -3962,80 +4231,133 @@
 		hci_ssbi_peek_reg(&radio->ssbi_peek_reg, radio->fm_hdev);
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS:
-		temp_val = ctrl->value;
-		hci_read_grp_counters(&temp_val, radio->fm_hdev);
+		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)
-			break;
+			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:
-		temp_val = ctrl->value;
-		retval = hci_set_notch_filter(&temp_val, radio->fm_hdev);
+		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);
-			return 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);
-			return 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);
-			return 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);
-			return 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);
-			return 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);
-			return 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);
-			return 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);
-			return retval;
+			radio->ch_det_threshold.sinr_samples = saved_val;
+			goto END;
 		}
 		break;
 
@@ -4082,18 +4404,23 @@
 		if (retval < 0) {
 			FMDERR("%s: Failed to determine channel's validity\n",
 				__func__);
-			return retval;
+			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__);
-			return retval;
+			goto END;
 		} else
 			sinr = radio->fm_st_rsp.station_rsp.sinr;
 
@@ -4101,7 +4428,7 @@
 		if (retval < 0) {
 			FMDERR("%s: Failed to determine channel's validity\n",
 				 __func__);
-			return retval;
+			goto END;
 		} else
 			intf_det_out = radio->st_dbg_param.in_det_out;
 
@@ -4120,7 +4447,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RDS_CNFG_MODE;
 		wrd.length = FM_RDS_CNFG_LEN;
@@ -4141,7 +4468,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RDS_CNFG_MODE;
 		wrd.length = FM_RDS_CNFG_LEN;
@@ -4161,7 +4488,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -4181,7 +4508,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -4201,7 +4528,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -4221,7 +4548,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -4241,7 +4568,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = FM_RX_CONFG_MODE;
 		wrd.length = FM_RX_CNFG_LEN;
@@ -4264,7 +4591,7 @@
 		retval = hci_def_data_read(&rd, radio->fm_hdev);
 		if (retval < 0) {
 			FMDERR("default data read failed for PS0 %x", retval);
-			return retval;
+			goto END;
 		}
 		wrd.mode = RDS_PS0_XFR_MODE;
 		wrd.length = RDS_PS0_LEN;
@@ -4278,7 +4605,13 @@
 		break;
 	default:
 		retval = -EINVAL;
+		break;
 	}
+
+END:
+	if (retval > 0)
+		retval = -EINVAL;
+
 	return retval;
 }
 
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index d28a8c0..a69f3f1 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -32,6 +32,50 @@
 #include <linux/mutex.h>
 #include <linux/atomic.h>
 #include "radio-iris-commands.h"
+const unsigned char MIN_TX_TONE_VAL = 0x00;
+const unsigned char MAX_TX_TONE_VAL = 0x07;
+const unsigned char MIN_HARD_MUTE_VAL = 0x00;
+const unsigned char MAX_HARD_MUTE_VAL = 0x03;
+const unsigned char MIN_SRCH_MODE = 0x00;
+const unsigned char MAX_SRCH_MODE = 0x01;
+const unsigned char MIN_SCAN_DWELL = 0x00;
+const unsigned char MAX_SCAN_DWELL = 0x0F;
+const unsigned char MIN_SIG_TH = 0x00;
+const unsigned char MAX_SIG_TH = 0x03;
+const unsigned char MIN_PTY = 0X00;
+const unsigned char MAX_PTY = 0x1F;
+const unsigned short MIN_PI = 0x0000;
+const unsigned short MAX_PI = 0xFFFF;
+const unsigned char MIN_SRCH_STATIONS_CNT = 0x00;
+const unsigned char MAX_SRCH_STATIONS_CNT = 0x14;
+const unsigned char MIN_CHAN_SPACING = 0x00;
+const unsigned char MAX_CHAN_SPACING = 0x02;
+const unsigned char MIN_EMPHASIS = 0x00;
+const unsigned char MAX_EMPHASIS = 0x01;
+const unsigned char MIN_RDS_STD = 0x00;
+const unsigned char MAX_RDS_STD = 0x02;
+const unsigned char MIN_ANTENNA_VAL = 0x00;
+const unsigned char MAX_ANTENNA_VAL = 0x01;
+const unsigned char MIN_TX_PS_REPEAT_CNT = 0x01;
+const unsigned char MAX_TX_PS_REPEAT_CNT = 0x0F;
+const unsigned char MIN_SOFT_MUTE = 0x00;
+const unsigned char MAX_SOFT_MUTE = 0x01;
+const unsigned char MIN_PEEK_ACCESS_LEN = 0x01;
+const unsigned char MAX_PEEK_ACCESS_LEN = 0xF9;
+const unsigned char MIN_RESET_CNTR = 0x00;
+const unsigned char MAX_RESET_CNTR = 0x01;
+const unsigned char MIN_HLSI = 0x00;
+const unsigned char MAX_HLSI = 0x02;
+const unsigned char MIN_NOTCH_FILTER = 0x00;
+const unsigned char MAX_NOTCH_FILTER = 0x02;
+const unsigned char MIN_INTF_DET_OUT_LW_TH = 0x00;
+const unsigned char MAX_INTF_DET_OUT_LW_TH = 0xFF;
+const unsigned char MIN_INTF_DET_OUT_HG_TH = 0x00;
+const unsigned char MAX_INTF_DET_OUT_HG_TH = 0xFF;
+const signed char MIN_SINR_TH = -128;
+const signed char MAX_SINR_TH = 127;
+const unsigned char MIN_SINR_SAMPLES = 0x01;
+const unsigned char MAX_SINR_SAMPLES = 0xFF;
 
 /* ---- HCI Packet structures ---- */
 #define RADIO_HCI_COMMAND_HDR_SIZE sizeof(struct radio_hci_command_hdr)
@@ -630,6 +674,7 @@
 	FM_TURNING_OFF,
 	FM_RECV_TURNING_ON,
 	FM_TRANS_TURNING_ON,
+	FM_MAX_NO_STATES,
 };
 
 enum emphasis_type {
@@ -828,4 +873,209 @@
 int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev);
 int hci_fm_do_calibration(__u8 *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;
+}
 #endif /* __RADIO_HCI_CORE_H */