diff options
author | Mike Isely <isely@pobox.com> | 2006-12-30 16:31:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:34:35 -0500 |
commit | c74e0062684bc034a003289e2e2023f0e9ff747c (patch) | |
tree | 746324235464c72d96c9b833de55933035dbab3d /drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |
parent | cdef8bd8c6ab69407afaf78226cc9861f916c83d (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>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-v4l2.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 53 |
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 | ||
62 | struct pvr2_v4l2 { | 63 | struct 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 | ||