aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-12-30 16:31:22 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:34:35 -0500
commitc74e0062684bc034a003289e2e2023f0e9ff747c (patch)
tree746324235464c72d96c9b833de55933035dbab3d
parentcdef8bd8c6ab69407afaf78226cc9861f916c83d (diff)
V4L/DVB (5059): Pvrusb2: Be smarter about mode restoration
Switch back to the previous input selection when the radio device is closed - but only do that if the current input selection is still the radio (i.e. it appears that it hasn't been messed with). Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 8b9089cc32fe..0ecad5b3c029 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -57,6 +57,7 @@ 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;
60}; 61};
61 62
62struct pvr2_v4l2 { 63struct pvr2_v4l2 {
@@ -837,13 +838,12 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
837 struct pvr2_v4l2_fh *fhp = file->private_data; 838 struct pvr2_v4l2_fh *fhp = file->private_data;
838 struct pvr2_v4l2 *vp = fhp->vhead; 839 struct pvr2_v4l2 *vp = fhp->vhead;
839 struct pvr2_context *mp = fhp->vhead->channel.mc_head; 840 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
841 struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
840 842
841 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); 843 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
842 844
843 if (fhp->rhp) { 845 if (fhp->rhp) {
844 struct pvr2_stream *sp; 846 struct pvr2_stream *sp;
845 struct pvr2_hdw *hdw;
846 hdw = fhp->channel.mc_head->hdw;
847 pvr2_hdw_set_streaming(hdw,0); 847 pvr2_hdw_set_streaming(hdw,0);
848 sp = pvr2_ioread_get_stream(fhp->rhp); 848 sp = pvr2_ioread_get_stream(fhp->rhp);
849 if (sp) pvr2_stream_set_callback(sp,NULL,NULL); 849 if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
@@ -855,6 +855,20 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
855 file->private_data = NULL; 855 file->private_data = NULL;
856 856
857 pvr2_context_enter(mp); do { 857 pvr2_context_enter(mp); do {
858 /* Restore the previous input selection, if it makes sense
859 to do so. */
860 if (fhp->dev_info->v4l_type == VFL_TYPE_RADIO) {
861 struct pvr2_ctrl *cp;
862 int pval;
863 cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
864 pvr2_ctrl_get_value(cp,&pval);
865 /* Only restore if we're still selecting the radio */
866 if (pval == PVR2_CVAL_INPUT_RADIO) {
867 pvr2_ctrl_set_value(cp,fhp->prev_input_val);
868 pvr2_hdw_commit_ctl(hdw);
869 }
870 }
871
858 if (fhp->vnext) { 872 if (fhp->vnext) {
859 fhp->vnext->vprev = fhp->vprev; 873 fhp->vnext->vprev = fhp->vprev;
860 } else { 874 } else {
@@ -913,17 +927,6 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
913 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); 927 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
914 pvr2_channel_init(&fhp->channel,vp->channel.mc_head); 928 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
915 929
916 /* Opening the /dev/radioX device implies a mode switch.
917 So execute that here. Note that you can get the
918 IDENTICAL effect merely by opening the normal video
919 device and setting the input appropriately. */
920 if (dip->v4l_type == VFL_TYPE_RADIO) {
921 pvr2_ctrl_set_value(
922 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
923 PVR2_CVAL_INPUT_RADIO);
924 pvr2_hdw_commit_ctl(hdw);
925 }
926
927 fhp->vnext = NULL; 930 fhp->vnext = NULL;
928 fhp->vprev = vp->vlast; 931 fhp->vprev = vp->vlast;
929 if (vp->vlast) { 932 if (vp->vlast) {
@@ -933,6 +936,18 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
933 } 936 }
934 vp->vlast = fhp; 937 vp->vlast = fhp;
935 fhp->vhead = vp; 938 fhp->vhead = vp;
939
940 /* Opening the /dev/radioX device implies a mode switch.
941 So execute that here. Note that you can get the
942 IDENTICAL effect merely by opening the normal video
943 device and setting the input appropriately. */
944 if (dip->v4l_type == VFL_TYPE_RADIO) {
945 struct pvr2_ctrl *cp;
946 cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
947 pvr2_ctrl_get_value(cp,&fhp->prev_input_val);
948 pvr2_ctrl_set_value(cp,PVR2_CVAL_INPUT_RADIO);
949 pvr2_hdw_commit_ctl(hdw);
950 }
936 } while (0); pvr2_context_exit(vp->channel.mc_head); 951 } while (0); pvr2_context_exit(vp->channel.mc_head);
937 952
938 fhp->file = file; 953 fhp->file = file;
@@ -1117,6 +1132,11 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1117 dip->config = pvr2_config_mpeg; 1132 dip->config = pvr2_config_mpeg;
1118 dip->minor_type = pvr2_v4l_type_video; 1133 dip->minor_type = pvr2_v4l_type_video;
1119 nr_ptr = video_nr; 1134 nr_ptr = video_nr;
1135 if (!dip->stream) {
1136 err("Failed to set up pvrusb2 v4l video dev"
1137 " due to missing stream instance");
1138 return;
1139 }
1120 break; 1140 break;
1121 case VFL_TYPE_VBI: 1141 case VFL_TYPE_VBI:
1122 dip->config = pvr2_config_vbi; 1142 dip->config = pvr2_config_vbi;
@@ -1135,13 +1155,6 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1135 return; 1155 return;
1136 } 1156 }
1137 1157
1138 /* radio device doesn 't need its own stream */
1139 if (!dip->stream && dip->v4l_type == VFL_TYPE_GRABBER) {
1140 err("Failed to set up pvrusb2 v4l dev"
1141 " due to missing stream instance");
1142 return;
1143 }
1144
1145 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template)); 1158 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1146 dip->devbase.release = pvr2_video_device_release; 1159 dip->devbase.release = pvr2_video_device_release;
1147 1160