diff options
author | Mike Isely <isely@pobox.com> | 2008-04-21 02:47:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:49 -0400 |
commit | 1cb03b76d09d20accfa5c1664c16ba6566f539a0 (patch) | |
tree | 8c58f23151ab54f71472b80f6d0d29df25ddbb9f /drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |
parent | d3f8d8fb304a8b9a81eae16ff7b50f5379f2437e (diff) |
V4L/DVB (7719): pvrusb2: Implement input selection enforcement
In the pvrusb2 driver, different interfaces (e.g. V4L, DVB) have
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-v4l2.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 249d7488e482..b415141b2859 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -57,7 +57,6 @@ struct pvr2_v4l2_fh { | |||
57 | struct pvr2_v4l2_fh *vprev; | 57 | struct pvr2_v4l2_fh *vprev; |
58 | wait_queue_head_t wait_data; | 58 | wait_queue_head_t wait_data; |
59 | int fw_mode_flag; | 59 | int fw_mode_flag; |
60 | int prev_input_val; | ||
61 | }; | 60 | }; |
62 | 61 | ||
63 | struct pvr2_v4l2 { | 62 | struct pvr2_v4l2 { |
@@ -900,20 +899,6 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file) | |||
900 | v4l2_prio_close(&vp->prio, &fhp->prio); | 899 | v4l2_prio_close(&vp->prio, &fhp->prio); |
901 | file->private_data = NULL; | 900 | file->private_data = NULL; |
902 | 901 | ||
903 | /* Restore the previous input selection, if it makes sense | ||
904 | to do so. */ | ||
905 | if (fhp->dev_info->v4l_type == VFL_TYPE_RADIO) { | ||
906 | struct pvr2_ctrl *cp; | ||
907 | int pval; | ||
908 | cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | ||
909 | pvr2_ctrl_get_value(cp,&pval); | ||
910 | /* Only restore if we're still selecting the radio */ | ||
911 | if (pval == PVR2_CVAL_INPUT_RADIO) { | ||
912 | pvr2_ctrl_set_value(cp,fhp->prev_input_val); | ||
913 | pvr2_hdw_commit_ctl(hdw); | ||
914 | } | ||
915 | } | ||
916 | |||
917 | if (fhp->vnext) { | 902 | if (fhp->vnext) { |
918 | fhp->vnext->vprev = fhp->vprev; | 903 | fhp->vnext->vprev = fhp->vprev; |
919 | } else { | 904 | } else { |
@@ -944,6 +929,8 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) | |||
944 | struct pvr2_v4l2_fh *fhp; | 929 | struct pvr2_v4l2_fh *fhp; |
945 | struct pvr2_v4l2 *vp; | 930 | struct pvr2_v4l2 *vp; |
946 | struct pvr2_hdw *hdw; | 931 | struct pvr2_hdw *hdw; |
932 | unsigned int input_mask = 0; | ||
933 | int ret = 0; | ||
947 | 934 | ||
948 | dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); | 935 | dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); |
949 | 936 | ||
@@ -969,6 +956,29 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) | |||
969 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); | 956 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); |
970 | pvr2_channel_init(&fhp->channel,vp->channel.mc_head); | 957 | pvr2_channel_init(&fhp->channel,vp->channel.mc_head); |
971 | 958 | ||
959 | if (dip->v4l_type == VFL_TYPE_RADIO) { | ||
960 | /* Opening device as a radio, legal input selection subset | ||
961 | is just the radio. */ | ||
962 | input_mask = (1 << PVR2_CVAL_INPUT_RADIO); | ||
963 | } else { | ||
964 | /* Opening the main V4L device, legal input selection | ||
965 | subset includes all analog inputs. */ | ||
966 | input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) | | ||
967 | (1 << PVR2_CVAL_INPUT_TV) | | ||
968 | (1 << PVR2_CVAL_INPUT_COMPOSITE) | | ||
969 | (1 << PVR2_CVAL_INPUT_SVIDEO)); | ||
970 | } | ||
971 | ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask); | ||
972 | if (ret) { | ||
973 | pvr2_channel_done(&fhp->channel); | ||
974 | pvr2_trace(PVR2_TRACE_STRUCT, | ||
975 | "Destroying pvr_v4l2_fh id=%p (input mask error)", | ||
976 | fhp); | ||
977 | |||
978 | kfree(fhp); | ||
979 | return ret; | ||
980 | } | ||
981 | |||
972 | fhp->vnext = NULL; | 982 | fhp->vnext = NULL; |
973 | fhp->vprev = vp->vlast; | 983 | fhp->vprev = vp->vlast; |
974 | if (vp->vlast) { | 984 | if (vp->vlast) { |
@@ -979,18 +989,6 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) | |||
979 | vp->vlast = fhp; | 989 | vp->vlast = fhp; |
980 | fhp->vhead = vp; | 990 | fhp->vhead = vp; |
981 | 991 | ||
982 | /* Opening the /dev/radioX device implies a mode switch. | ||
983 | So execute that here. Note that you can get the | ||
984 | IDENTICAL effect merely by opening the normal video | ||
985 | device and setting the input appropriately. */ | ||
986 | if (dip->v4l_type == VFL_TYPE_RADIO) { | ||
987 | struct pvr2_ctrl *cp; | ||
988 | cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | ||
989 | pvr2_ctrl_get_value(cp,&fhp->prev_input_val); | ||
990 | pvr2_ctrl_set_value(cp,PVR2_CVAL_INPUT_RADIO); | ||
991 | pvr2_hdw_commit_ctl(hdw); | ||
992 | } | ||
993 | |||
994 | fhp->file = file; | 992 | fhp->file = file; |
995 | file->private_data = fhp; | 993 | file->private_data = fhp; |
996 | v4l2_prio_open(&vp->prio,&fhp->prio); | 994 | v4l2_prio_open(&vp->prio,&fhp->prio); |