aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-04-21 02:52:34 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:49 -0400
commite57b1c80065f7922e3ba464f54254c7ce983a3a4 (patch)
tree91130831cf07714821b0a3e399be7989e74d4da1 /drivers/media
parent1df59f0b908bfcdc35d1ea2319290ece272bf576 (diff)
V4L/DVB (7723): pvrusb2: Clean up input selection list generation in V4L interface
Change how list of possible pvrusb2 inputs is generated to include only those interfaces that make sense for the interface instance. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index b415141b2859..087a18245560 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -57,6 +57,9 @@ 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 /* Map contiguous ordinal value to input id */
61 unsigned char *input_map;
62 unsigned int input_cnt;
60}; 63};
61 64
62struct pvr2_v4l2 { 65struct pvr2_v4l2 {
@@ -66,10 +69,6 @@ struct pvr2_v4l2 {
66 69
67 struct v4l2_prio_state prio; 70 struct v4l2_prio_state prio;
68 71
69 /* Map contiguous ordinal value to input id */
70 unsigned char *input_map;
71 unsigned int input_cnt;
72
73 /* streams - Note that these must be separately, individually, 72 /* streams - Note that these must be separately, individually,
74 * allocated pointers. This is because the v4l core is going to 73 * allocated pointers. This is because the v4l core is going to
75 * manage their deletion - separately, individually... */ 74 * manage their deletion - separately, individually... */
@@ -269,11 +268,11 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
269 memset(&tmp,0,sizeof(tmp)); 268 memset(&tmp,0,sizeof(tmp));
270 tmp.index = vi->index; 269 tmp.index = vi->index;
271 ret = 0; 270 ret = 0;
272 if ((vi->index < 0) || (vi->index >= vp->input_cnt)) { 271 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
273 ret = -EINVAL; 272 ret = -EINVAL;
274 break; 273 break;
275 } 274 }
276 val = vp->input_map[vi->index]; 275 val = fh->input_map[vi->index];
277 switch (val) { 276 switch (val) {
278 case PVR2_CVAL_INPUT_TV: 277 case PVR2_CVAL_INPUT_TV:
279 case PVR2_CVAL_INPUT_DTV: 278 case PVR2_CVAL_INPUT_DTV:
@@ -321,8 +320,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
321 val = 0; 320 val = 0;
322 ret = pvr2_ctrl_get_value(cptr,&val); 321 ret = pvr2_ctrl_get_value(cptr,&val);
323 vi->index = 0; 322 vi->index = 0;
324 for (idx = 0; idx < vp->input_cnt; idx++) { 323 for (idx = 0; idx < fh->input_cnt; idx++) {
325 if (vp->input_map[idx] == val) { 324 if (fh->input_map[idx] == val) {
326 vi->index = idx; 325 vi->index = idx;
327 break; 326 break;
328 } 327 }
@@ -333,13 +332,13 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
333 case VIDIOC_S_INPUT: 332 case VIDIOC_S_INPUT:
334 { 333 {
335 struct v4l2_input *vi = (struct v4l2_input *)arg; 334 struct v4l2_input *vi = (struct v4l2_input *)arg;
336 if ((vi->index < 0) || (vi->index >= vp->input_cnt)) { 335 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
337 ret = -ERANGE; 336 ret = -ERANGE;
338 break; 337 break;
339 } 338 }
340 ret = pvr2_ctrl_set_value( 339 ret = pvr2_ctrl_set_value(
341 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), 340 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
342 vp->input_map[vi->index]); 341 fh->input_map[vi->index]);
343 break; 342 break;
344 } 343 }
345 344
@@ -838,10 +837,6 @@ static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
838 pvr2_v4l2_dev_destroy(vp->dev_radio); 837 pvr2_v4l2_dev_destroy(vp->dev_radio);
839 vp->dev_radio = NULL; 838 vp->dev_radio = NULL;
840 } 839 }
841 if (vp->input_map) {
842 kfree(vp->input_map);
843 vp->input_map = NULL;
844 }
845 840
846 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); 841 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
847 pvr2_channel_done(&vp->channel); 842 pvr2_channel_done(&vp->channel);
@@ -915,6 +910,10 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
915 pvr2_channel_done(&fhp->channel); 910 pvr2_channel_done(&fhp->channel);
916 pvr2_trace(PVR2_TRACE_STRUCT, 911 pvr2_trace(PVR2_TRACE_STRUCT,
917 "Destroying pvr_v4l2_fh id=%p",fhp); 912 "Destroying pvr_v4l2_fh id=%p",fhp);
913 if (fhp->input_map) {
914 kfree(fhp->input_map);
915 fhp->input_map = NULL;
916 }
918 kfree(fhp); 917 kfree(fhp);
919 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { 918 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
920 pvr2_v4l2_destroy_no_lock(vp); 919 pvr2_v4l2_destroy_no_lock(vp);
@@ -930,6 +929,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
930 struct pvr2_v4l2 *vp; 929 struct pvr2_v4l2 *vp;
931 struct pvr2_hdw *hdw; 930 struct pvr2_hdw *hdw;
932 unsigned int input_mask = 0; 931 unsigned int input_mask = 0;
932 unsigned int input_cnt,idx;
933 int ret = 0; 933 int ret = 0;
934 934
935 dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); 935 dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
@@ -979,6 +979,27 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
979 return ret; 979 return ret;
980 } 980 }
981 981
982 input_mask &= pvr2_hdw_get_input_available(hdw);
983 input_cnt = 0;
984 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
985 if (input_mask & (1 << idx)) input_cnt++;
986 }
987 fhp->input_cnt = input_cnt;
988 fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
989 if (!fhp->input_map) {
990 pvr2_channel_done(&fhp->channel);
991 pvr2_trace(PVR2_TRACE_STRUCT,
992 "Destroying pvr_v4l2_fh id=%p (input map failure)",
993 fhp);
994 kfree(fhp);
995 return -ENOMEM;
996 }
997 input_cnt = 0;
998 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
999 if (!(input_mask & (1 << idx))) continue;
1000 fhp->input_map[input_cnt++] = idx;
1001 }
1002
982 fhp->vnext = NULL; 1003 fhp->vnext = NULL;
983 fhp->vprev = vp->vlast; 1004 fhp->vprev = vp->vlast;
984 if (vp->vlast) { 1005 if (vp->vlast) {
@@ -1217,8 +1238,6 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1217struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) 1238struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1218{ 1239{
1219 struct pvr2_v4l2 *vp; 1240 struct pvr2_v4l2 *vp;
1220 struct pvr2_hdw *hdw;
1221 unsigned int input_mask,input_cnt,idx;
1222 1241
1223 vp = kzalloc(sizeof(*vp),GFP_KERNEL); 1242 vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1224 if (!vp) return vp; 1243 if (!vp) return vp;
@@ -1227,26 +1246,12 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1227 1246
1228 vp->channel.check_func = pvr2_v4l2_internal_check; 1247 vp->channel.check_func = pvr2_v4l2_internal_check;
1229 1248
1230 hdw = vp->channel.mc_head->hdw;
1231 input_mask = pvr2_hdw_get_input_available(hdw);
1232 input_cnt = 0;
1233 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1234 if (input_mask & (1 << idx)) input_cnt++;
1235 }
1236 vp->input_cnt = input_cnt;
1237 vp->input_map = kzalloc(input_cnt,GFP_KERNEL);
1238 if (!vp->input_map) goto fail;
1239 input_cnt = 0;
1240 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1241 if (!(input_mask & (1 << idx))) continue;
1242 vp->input_map[input_cnt++] = idx;
1243 }
1244
1245 /* register streams */ 1249 /* register streams */
1246 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL); 1250 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1247 if (!vp->dev_video) goto fail; 1251 if (!vp->dev_video) goto fail;
1248 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER); 1252 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
1249 if (input_mask & (1 << PVR2_CVAL_INPUT_RADIO)) { 1253 if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1254 (1 << PVR2_CVAL_INPUT_RADIO)) {
1250 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL); 1255 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1251 if (!vp->dev_radio) goto fail; 1256 if (!vp->dev_radio) goto fail;
1252 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO); 1257 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);