radio: iris: adding support for TX functionality
This patch adds the functionality for FM enable, disable,
tuning, configuration and RDS functionality for FM TX
Signed-off-by: Ankur Nandwani <ankurn@codeaurora.org>
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 2194b48..2d208c3 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -55,6 +55,11 @@
int xfr_in_progress;
struct completion sync_xfr_start;
int tune_req;
+ unsigned int mode;
+
+ __u16 pi;
+ __u8 pty;
+ __u8 ps_repeatcount;
struct video_device *videodev;
@@ -75,8 +80,10 @@
struct hci_fm_search_rds_station_req srch_rds;
struct hci_fm_search_station_list_req srch_st_list;
struct hci_fm_recv_conf_req recv_conf;
+ struct hci_fm_trans_conf_req_struct trans_conf;
struct hci_fm_rds_grp_req rds_grp;
unsigned char g_search_mode;
+ unsigned int tone_freq;
unsigned char g_scan_time;
unsigned int g_antenna;
unsigned int g_rds_grp_proc_ps;
@@ -548,6 +555,28 @@
return radio_hci_send_cmd(hdev, opcode, 0, NULL);
}
+static int hci_fm_tone_generator(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+ HCI_FM_SET_INTERNAL_TONE_GENRATOR);
+ return radio_hci_send_cmd(hdev, opcode,
+ sizeof(radio->tone_freq), &radio->tone_freq);
+}
+
+static int hci_fm_enable_trans_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_ENABLE_TRANS_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
static int hci_fm_disable_recv_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -558,6 +587,16 @@
return radio_hci_send_cmd(hdev, opcode, 0, NULL);
}
+static int hci_fm_disable_trans_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_DISABLE_TRANS_REQ);
+ return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
static int hci_get_fm_recv_conf_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -582,6 +621,20 @@
recv_conf_req);
}
+static int hci_set_fm_trans_conf_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+
+ struct hci_fm_trans_conf_req_struct *trans_conf_req =
+ (struct hci_fm_trans_conf_req_struct *) param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_SET_TRANS_CONF_REQ);
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*trans_conf_req)),
+ trans_conf_req);
+}
+
static int hci_fm_get_station_param_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -605,6 +658,35 @@
mute_mode_req);
}
+
+static int hci_trans_ps_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_tx_ps *tx_ps_req =
+ (struct hci_fm_tx_ps *) param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_PS_REQ);
+
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_ps_req)),
+ tx_ps_req);
+}
+
+static int hci_trans_rt_req(struct radio_hci_dev *hdev,
+ unsigned long param)
+{
+ __u16 opcode = 0;
+ struct hci_fm_tx_rt *tx_rt_req =
+ (struct hci_fm_tx_rt *) param;
+
+ opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+ HCI_OCF_FM_RDS_RT_REQ);
+
+ return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_rt_req)),
+ tx_rt_req);
+}
+
static int hci_set_fm_stereo_mode_req(struct radio_hci_dev *hdev,
unsigned long param)
{
@@ -973,6 +1055,18 @@
return ret;
}
+static int hci_set_fm_trans_conf(struct hci_fm_trans_conf_req_struct *arg,
+ struct radio_hci_dev *hdev)
+{
+ int ret = 0;
+ struct hci_fm_trans_conf_req_struct *set_trans_conf = arg;
+
+ ret = radio_hci_request(hdev, hci_set_fm_trans_conf_req, (unsigned
+ long)set_trans_conf, RADIO_HCI_TIMEOUT);
+
+ return ret;
+}
+
static int hci_fm_tune_station(__u32 *arg, struct radio_hci_dev *hdev)
{
int ret = 0;
@@ -1184,6 +1278,9 @@
int ret = 0;
unsigned long arg = 0;
+ if (!hdev)
+ return -ENODEV;
+
switch (cmd) {
case HCI_FM_ENABLE_RECV_CMD:
ret = radio_hci_request(hdev, hci_fm_enable_recv_req, arg,
@@ -1250,6 +1347,16 @@
msecs_to_jiffies(RADIO_HCI_TIMEOUT));
break;
+ case HCI_FM_ENABLE_TRANS_CMD:
+ ret = radio_hci_request(hdev, hci_fm_enable_trans_req, arg,
+ msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+ break;
+
+ case HCI_FM_DISABLE_TRANS_CMD:
+ ret = radio_hci_request(hdev, hci_fm_disable_trans_req, arg,
+ msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+ break;
+
default:
ret = -EINVAL;
break;
@@ -1322,6 +1429,22 @@
radio_hci_req_complete(hdev, rsp->status);
}
+
+static void hci_cc_fm_trans_set_conf_rsp(struct radio_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_fm_conf_rsp *rsp = (void *)skb->data;
+ struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+ if (rsp->status)
+ return;
+
+ iris_q_event(radio, HCI_EV_CMD_COMPLETE);
+
+ radio_hci_req_complete(hdev, rsp->status);
+}
+
+
static void hci_cc_sig_threshold_rsp(struct radio_hci_dev *hdev,
struct sk_buff *skb)
{
@@ -1490,11 +1613,16 @@
case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP_PROCESS):
case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL):
case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_TRANS_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_TRANS_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_RT_REQ):
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_PS_REQ):
case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
case hci_common_cmd_op_pack(HCI_OCF_FM_RESET):
case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_POKE_REG):
case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_POKE_DATA):
case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
+ case hci_diagnostic_cmd_op_pack(HCI_FM_SET_INTERNAL_TONE_GENRATOR):
hci_cc_rsp(hdev, skb);
break;
@@ -1534,6 +1662,10 @@
hci_cc_dbg_param_rsp(hdev, skb);
break;
+ case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_SET_TRANS_CONF_REQ):
+ hci_cc_fm_trans_set_conf_rsp(hdev, skb);
+ break;
+
default:
FMDERR("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1812,52 +1944,42 @@
return retval;
}
-static int iris_set_region(struct iris_device *radio, int req_region)
+static int iris_recv_set_region(struct iris_device *radio, int req_region)
{
int retval;
radio->region = req_region;
switch (radio->region) {
case IRIS_REGION_US:
- {
- radio->recv_conf.band_low_limit = 88100;
- radio->recv_conf.band_high_limit = 108000;
- radio->recv_conf.emphasis = 0;
- radio->recv_conf.hlsi = 0;
- radio->recv_conf.ch_spacing = 0;
- radio->recv_conf.rds_std = 0;
- }
+ radio->recv_conf.band_low_limit =
+ REGION_US_EU_BAND_LOW;
+ radio->recv_conf.band_high_limit =
+ REGION_US_EU_BAND_HIGH;
break;
case IRIS_REGION_EU:
- {
- radio->recv_conf.band_low_limit = 88100;
- radio->recv_conf.band_high_limit = 108000;
- radio->recv_conf.emphasis = 0;
- radio->recv_conf.hlsi = 0;
- radio->recv_conf.ch_spacing = 0;
- radio->recv_conf.rds_std = 0;
- }
+ radio->recv_conf.band_low_limit =
+ REGION_US_EU_BAND_LOW;
+ radio->recv_conf.band_high_limit =
+ REGION_US_EU_BAND_HIGH;
break;
case IRIS_REGION_JAPAN:
- {
- radio->recv_conf.band_low_limit = 76000;
- radio->recv_conf.band_high_limit = 108000;
- radio->recv_conf.emphasis = 0;
- radio->recv_conf.hlsi = 0;
- radio->recv_conf.ch_spacing = 0;
- }
+ radio->recv_conf.band_low_limit =
+ REGION_JAPAN_STANDARD_BAND_HIGH;
+ radio->recv_conf.band_high_limit =
+ REGION_JAPAN_STANDARD_BAND_LOW;
+ break;
+ case IRIS_REGION_JAPAN_WIDE:
+ radio->recv_conf.band_low_limit =
+ REGION_JAPAN_WIDE_BAND_LOW;
+ radio->recv_conf.band_high_limit =
+ REGION_JAPAN_WIDE_BAND_HIGH;
break;
default:
- {
- radio->recv_conf.emphasis = 0;
- radio->recv_conf.hlsi = 0;
- radio->recv_conf.ch_spacing = 0;
- radio->recv_conf.rds_std = 0;
- }
+ /* The user specifies the value.
+ So nothing needs to be done */
break;
}
-
retval = hci_set_fm_recv_conf(
&radio->recv_conf,
radio->fm_hdev);
@@ -1865,6 +1987,47 @@
return retval;
}
+
+static int iris_trans_set_region(struct iris_device *radio, int req_region)
+{
+ int retval;
+ radio->region = req_region;
+
+ switch (radio->region) {
+ case IRIS_REGION_US:
+ radio->trans_conf.band_low_limit =
+ REGION_US_EU_BAND_LOW;
+ radio->trans_conf.band_high_limit =
+ REGION_US_EU_BAND_HIGH;
+ break;
+ case IRIS_REGION_EU:
+ radio->trans_conf.band_low_limit =
+ REGION_US_EU_BAND_LOW;
+ radio->trans_conf.band_high_limit =
+ REGION_US_EU_BAND_HIGH;
+ break;
+ case IRIS_REGION_JAPAN:
+ radio->trans_conf.band_low_limit =
+ REGION_JAPAN_STANDARD_BAND_HIGH;
+ radio->trans_conf.band_high_limit =
+ REGION_JAPAN_STANDARD_BAND_LOW;
+ break;
+ case IRIS_REGION_JAPAN_WIDE:
+ radio->recv_conf.band_low_limit =
+ REGION_JAPAN_WIDE_BAND_LOW;
+ radio->recv_conf.band_high_limit =
+ REGION_JAPAN_WIDE_BAND_HIGH;
+ default:
+ break;
+ }
+
+ retval = hci_set_fm_trans_conf(
+ &radio->trans_conf,
+ radio->fm_hdev);
+ return retval;
+}
+
+
static int iris_set_freq(struct iris_device *radio, unsigned int freq)
{
@@ -1940,40 +2103,44 @@
case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
break;
case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
- retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
- radio->fm_hdev);
- if (retval < 0)
- FMDERR("Error get FM recv conf"
- " %d\n", retval);
- else
+ if (radio->mode == FM_RECV) {
ctrl->value = radio->recv_conf.emphasis;
+ } else if (radio->mode == FM_TRANS) {
+ ctrl->value = radio->trans_conf.emphasis;
+ } else {
+ FMDERR("Error in radio mode"
+ " %d\n", retval);
+ return -EINVAL;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_RDS_STD:
- retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
- radio->fm_hdev);
- if (retval < 0)
- FMDERR("Error get FM recv conf"
- " %d\n", retval);
- else
+ if (radio->mode == FM_RECV) {
ctrl->value = radio->recv_conf.rds_std;
+ } else if (radio->mode == FM_TRANS) {
+ ctrl->value = radio->trans_conf.rds_std;
+ } else {
+ FMDERR("Error in radio mode"
+ " %d\n", retval);
+ return -EINVAL;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_SPACING:
- retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
- radio->fm_hdev);
- if (retval < 0)
- FMDERR("Error get FM recv conf"
- " %d\n", retval);
- else
+ if (radio->mode == FM_RECV) {
ctrl->value = radio->recv_conf.ch_spacing;
+ } else {
+ FMDERR("Error in radio mode"
+ " %d\n", retval);
+ return -EINVAL;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_RDSON:
- retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
- radio->fm_hdev);
- if (retval < 0)
- FMDERR("Error get FM recv conf"
- " %d\n", retval);
- else
+ if (radio->mode == FM_RECV) {
ctrl->value = radio->recv_conf.rds_std;
+ } else {
+ FMDERR("Error in radio mode"
+ " %d\n", retval);
+ return -EINVAL;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
ctrl->value = radio->rds_grp.rds_grp_enable_mask;
@@ -2005,7 +2172,60 @@
static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrl)
{
- return -ENOTSUPP;
+ int retval = 0;
+ int bytes_to_copy;
+ struct hci_fm_tx_ps tx_ps;
+ struct hci_fm_tx_rt tx_rt;
+
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ char *data = NULL;
+
+ switch ((ctrl->controls[0]).id) {
+ case V4L2_CID_RDS_TX_PS_NAME:
+ FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
+ /*Pass a sample PS string */
+
+ memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
+ bytes_to_copy = min((int)(ctrl->controls[0]).size,
+ MAX_PS_LENGTH);
+ 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_len = bytes_to_copy;
+
+ 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 =
+ min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
+ data = (ctrl->controls[0]).string;
+
+ memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
+
+ if (copy_from_user(tx_rt.rt_data,
+ data, bytes_to_copy))
+ return -EFAULT;
+
+ tx_rt.rt_control = 0x01;
+ tx_rt.pi = radio->pi;
+ tx_rt.pty = radio->pty;
+ tx_rt.ps_len = bytes_to_copy;
+
+ retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
+ (unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
+ break;
+ default:
+ FMDBG("Shouldn't reach here\n");
+ retval = -1;
+ }
+ return retval;
}
static int iris_vidioc_s_ctrl(struct file *file, void *priv,
@@ -2015,6 +2235,7 @@
int retval = 0;
unsigned int rds_grps_proc = 0;
__u8 temp_val = 0;
+ unsigned long arg = 0;
radio->recv_conf.emphasis = 0;
radio->recv_conf.ch_spacing = 0;
radio->recv_conf.hlsi = 0;
@@ -2024,6 +2245,12 @@
switch (ctrl->id) {
+ case VL2_CID_PRIVATE_IRIS_TX_TONE:
+ radio->tone_freq = ctrl->value;
+ retval = radio_hci_request(radio->fm_hdev,
+ hci_fm_tone_generator, arg,
+ msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+ break;
case V4L2_CID_AUDIO_VOLUME:
break;
case V4L2_CID_AUDIO_MUTE:
@@ -2046,41 +2273,74 @@
iris_search(radio, ctrl->value, SRCH_DIR_UP);
break;
case V4L2_CID_PRIVATE_IRIS_STATE:
- if (ctrl->value == FM_RECV) {
+ switch (ctrl->value) {
+ case FM_RECV:
retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
radio->fm_hdev);
- if (retval < 0) {
- FMDERR("Error while enabling FM"
+
+ radio->mode = FM_RECV;
+
+ if (retval < 0)
+ FMDERR("Error while enabling RECV FM"
" %d\n", retval);
- } else {
- radio->mute_mode.soft_mute = CTRL_ON;
- retval = hci_set_fm_mute_mode(
- &radio->mute_mode,
+ radio->mute_mode.soft_mute = CTRL_ON;
+ retval = hci_set_fm_mute_mode(
+ &radio->mute_mode,
radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Failed to enable Smute\n");
+ radio->stereo_mode.stereo_mode = CTRL_OFF;
+ radio->stereo_mode.sig_blend = CTRL_ON;
+ radio->stereo_mode.intf_blend = CTRL_ON;
+ radio->stereo_mode.most_switch = CTRL_ON;
+ retval = hci_set_fm_stereo_mode(
+ &radio->stereo_mode,
+ radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Failed to set stereo mode\n");
+
+ case FM_TRANS:
+ retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
+ radio->fm_hdev);
+ radio->mode = FM_TRANS;
+
+ if (retval < 0)
+ FMDERR("Error while enabling TRANS FM"
+ " %d\n", retval);
+ case FM_OFF:
+ switch (radio->mode) {
+ case FM_RECV:
+ retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+ radio->fm_hdev);
if (retval < 0)
- FMDERR("Failed to enable Smute\n");
- radio->stereo_mode.stereo_mode = CTRL_OFF;
- radio->stereo_mode.sig_blend = CTRL_ON;
- radio->stereo_mode.intf_blend = CTRL_ON;
- radio->stereo_mode.most_switch = CTRL_ON;
- retval = hci_set_fm_stereo_mode(
- &radio->stereo_mode,
- radio->fm_hdev);
+ FMDERR("Err on disable recv FM"
+ " %d\n", retval);
+ break;
+ case FM_TRANS:
+ retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+ radio->fm_hdev);
+
if (retval < 0)
- FMDERR("Failed to stereo mode\n");
- }
- } else if (ctrl->value == FM_OFF) {
- retval = hci_cmd(
- HCI_FM_DISABLE_RECV_CMD,
- radio->fm_hdev);
- if (retval < 0) {
- FMDERR("Error on disable FM"
+ FMDERR("Err disabling trans FM"
" %d\n", retval);
+ break;
+ default:
+ retval = -EINVAL;
}
+ default:
+ retval = -EINVAL;
}
break;
case V4L2_CID_PRIVATE_IRIS_REGION:
- retval = iris_set_region(radio, ctrl->value);
+ 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
+ retval = -EINVAL;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
temp_val = ctrl->value;
@@ -2106,13 +2366,23 @@
break;
case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
radio->recv_conf.emphasis = ctrl->value;
- retval =
- hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in setting emphasis");
+ break;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_RDS_STD:
radio->recv_conf.rds_std = ctrl->value;
- retval =
- hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
+ retval = hci_set_fm_recv_conf(
+ &radio->recv_conf,
+ radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Error in setting RDS_STD");
+ break;
+ }
break;
case V4L2_CID_PRIVATE_IRIS_RDSON:
radio->recv_conf.rds_std = ctrl->value;
@@ -2147,14 +2417,17 @@
retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
break;
case V4L2_CID_RDS_TX_PTY:
+ radio->pty = ctrl->value;
break;
case V4L2_CID_RDS_TX_PI:
+ radio->pi = ctrl->value;
break;
case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
break;
case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
break;
case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
+ radio->ps_repeatcount = ctrl->value;
break;
case V4L2_CID_TUNE_POWER_LEVEL:
break;
@@ -2206,8 +2479,8 @@
static int iris_vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
- struct iris_device *radio = video_get_drvdata(video_devdata(file));
int retval;
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
if (tuner->index > 0)
return -EINVAL;
@@ -2231,25 +2504,39 @@
struct v4l2_tuner *tuner)
{
struct iris_device *radio = video_get_drvdata(video_devdata(file));
- int retval;
+ int retval = 0;
if (tuner->index > 0)
return -EINVAL;
- radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
- radio->recv_conf.band_high_limit = tuner->rangehigh / TUNE_PARAM;
- if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
- radio->stereo_mode.stereo_mode = 0x01;
- retval = hci_set_fm_stereo_mode(
- &radio->stereo_mode,
- radio->fm_hdev);
+ if (radio->mode == FM_RECV) {
+ radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
+ radio->recv_conf.band_high_limit =
+ tuner->rangehigh / TUNE_PARAM;
+ if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
+ radio->stereo_mode.stereo_mode = 0x01;
+ retval = hci_set_fm_stereo_mode(
+ &radio->stereo_mode,
+ radio->fm_hdev);
+ } else {
+ radio->stereo_mode.stereo_mode = 0x00;
+ retval = hci_set_fm_stereo_mode(
+ &radio->stereo_mode,
+ radio->fm_hdev);
+ }
+ if (retval < 0)
+ FMDERR(": set tuner failed with %d\n", retval);
+ return retval;
} else {
- radio->stereo_mode.stereo_mode = 0x00;
- retval = hci_set_fm_stereo_mode(
- &radio->stereo_mode,
- radio->fm_hdev);
+ if (radio->mode == FM_TRANS) {
+ radio->trans_conf.band_low_limit =
+ tuner->rangelow / TUNE_PARAM;
+ radio->trans_conf.band_high_limit =
+ tuner->rangehigh / TUNE_PARAM;
+ } else {
+ return -EINVAL;
+ }
}
- if (retval < 0)
- FMDERR(": set tuner failed with %d\n", retval);
+
return retval;
}