diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-01-31 13:27:37 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-05 17:47:37 +0400 |
commit | 7556ba9bfb2ef0f2709fba40e77c7cc488645c79 (patch) | |
tree | 9c8d532e0d08d2f755eab1b25caa7dbf76cd80c5 /drivers | |
parent | c5d8907faa93757aa440fd2e584e4db4b8edc14a (diff) | |
download | linux-7556ba9bfb2ef0f2709fba40e77c7cc488645c79.tar.xz |
[media] tlg2300: fix frequency handling
The usual set of problems: the frequency isn't clamped to the frequency range,
no tuner index check and the frequency isn't initialized properly on module
load.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/usb/tlg2300/pd-common.h | 4 | ||||
-rw-r--r-- | drivers/media/usb/tlg2300/pd-video.c | 20 |
2 files changed, 14 insertions, 10 deletions
diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 052cb0c9530c..55fe66e440e3 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -36,8 +36,8 @@ #define V4L_PAL_VBI_FRAMESIZE (V4L_PAL_VBI_LINES * 1440 * 2) #define V4L_NTSC_VBI_FRAMESIZE (V4L_NTSC_VBI_LINES * 1440 * 2) -#define TUNER_FREQ_MIN (45000000) -#define TUNER_FREQ_MAX (862000000) +#define TUNER_FREQ_MIN (45000000U) +#define TUNER_FREQ_MAX (862000000U) struct vbi_data { struct video_device v_dev; diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 8ab28945a347..da7cbd4c4477 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -940,7 +940,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i) return 0; } -static struct poseidon_control *check_control_id(__u32 id) +static struct poseidon_control *check_control_id(u32 id) { struct poseidon_control *control = &controls[0]; int array_size = ARRAY_SIZE(controls); @@ -1134,21 +1134,21 @@ static int vidioc_g_frequency(struct file *file, void *fh, return 0; } -static int set_frequency(struct poseidon *pd, __u32 frequency) +static int set_frequency(struct poseidon *pd, u32 *frequency) { s32 ret = 0, param, cmd_status; struct running_context *context = &pd->video_data.context; - param = frequency * 62500 / 1000; - if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000) - return -EINVAL; + *frequency = clamp(*frequency, + TUNER_FREQ_MIN / 62500, TUNER_FREQ_MAX / 62500); + param = (*frequency) * 62500 / 1000; mutex_lock(&pd->lock); ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status); ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); msleep(250); /* wait for a while until the hardware is ready. */ - context->freq = frequency; + context->freq = *frequency; mutex_unlock(&pd->lock); return ret; } @@ -1159,12 +1159,14 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct front_face *front = fh; struct poseidon *pd = front->pd; + if (freq->tuner) + return -EINVAL; logs(front); #ifdef CONFIG_PM pd->pm_suspend = pm_video_suspend; pd->pm_resume = pm_video_resume; #endif - return set_frequency(pd, freq->frequency); + return set_frequency(pd, &freq->frequency); } static int vidioc_reqbufs(struct file *file, void *fh, @@ -1351,7 +1353,7 @@ static int restore_v4l2_context(struct poseidon *pd, vidioc_s_input(NULL, front, context->sig_index); pd_vidioc_s_tuner(pd, context->audio_idx); pd_vidioc_s_fmt(pd, &context->pix); - set_frequency(pd, context->freq); + set_frequency(pd, &context->freq); return 0; } @@ -1615,8 +1617,10 @@ int pd_video_init(struct poseidon *pd) { struct video_data *video = &pd->video_data; struct vbi_data *vbi = &pd->vbi_data; + u32 freq = TUNER_FREQ_MIN / 62500; int ret = -ENOMEM; + set_frequency(pd, &freq); video->v_dev = pd_video_template; video->v_dev.v4l2_dev = &pd->v4l2_dev; video_set_drvdata(&video->v_dev, pd); |