aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-v4l2.c')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c335
1 files changed, 234 insertions, 101 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 6cf17080eb49..4fe4136204c7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -40,7 +40,10 @@ struct pvr2_v4l2_dev {
40 struct video_device devbase; /* MUST be first! */ 40 struct video_device devbase; /* MUST be first! */
41 struct pvr2_v4l2 *v4lp; 41 struct pvr2_v4l2 *v4lp;
42 struct pvr2_context_stream *stream; 42 struct pvr2_context_stream *stream;
43 enum pvr2_config config; 43 /* Information about this device: */
44 enum pvr2_config config; /* Expected stream format */
45 int v4l_type; /* V4L defined type for this device node */
46 enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
44}; 47};
45 48
46struct pvr2_v4l2_fh { 49struct pvr2_v4l2_fh {
@@ -54,6 +57,7 @@ struct pvr2_v4l2_fh {
54 struct pvr2_v4l2_fh *vprev; 57 struct pvr2_v4l2_fh *vprev;
55 wait_queue_head_t wait_data; 58 wait_queue_head_t wait_data;
56 int fw_mode_flag; 59 int fw_mode_flag;
60 int prev_input_val;
57}; 61};
58 62
59struct pvr2_v4l2 { 63struct pvr2_v4l2 {
@@ -63,13 +67,22 @@ struct pvr2_v4l2 {
63 67
64 struct v4l2_prio_state prio; 68 struct v4l2_prio_state prio;
65 69
66 /* streams */ 70 /* streams - Note that these must be separately, individually,
67 struct pvr2_v4l2_dev *vdev; 71 * allocated pointers. This is because the v4l core is going to
72 * manage their deletion - separately, individually... */
73 struct pvr2_v4l2_dev *dev_video;
74 struct pvr2_v4l2_dev *dev_radio;
68}; 75};
69 76
70static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; 77static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
71module_param_array(video_nr, int, NULL, 0444); 78module_param_array(video_nr, int, NULL, 0444);
72MODULE_PARM_DESC(video_nr, "Offset for device's minor"); 79MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
80static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
81module_param_array(radio_nr, int, NULL, 0444);
82MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
83static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
84module_param_array(vbi_nr, int, NULL, 0444);
85MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
73 86
74static struct v4l2_capability pvr_capability ={ 87static struct v4l2_capability pvr_capability ={
75 .driver = "pvrusb2", 88 .driver = "pvrusb2",
@@ -77,30 +90,11 @@ static struct v4l2_capability pvr_capability ={
77 .bus_info = "usb", 90 .bus_info = "usb",
78 .version = KERNEL_VERSION(0,8,0), 91 .version = KERNEL_VERSION(0,8,0),
79 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | 92 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
80 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | 93 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
81 V4L2_CAP_READWRITE), 94 V4L2_CAP_READWRITE),
82 .reserved = {0,0,0,0} 95 .reserved = {0,0,0,0}
83}; 96};
84 97
85static struct v4l2_tuner pvr_v4l2_tuners[]= {
86 {
87 .index = 0,
88 .name = "TV Tuner",
89 .type = V4L2_TUNER_ANALOG_TV,
90 .capability = (V4L2_TUNER_CAP_NORM |
91 V4L2_TUNER_CAP_STEREO |
92 V4L2_TUNER_CAP_LANG1 |
93 V4L2_TUNER_CAP_LANG2),
94 .rangelow = 0,
95 .rangehigh = 0,
96 .rxsubchans = V4L2_TUNER_SUB_STEREO,
97 .audmode = V4L2_TUNER_MODE_STEREO,
98 .signal = 0,
99 .afc = 0,
100 .reserved = {0,0,0,0}
101 }
102};
103
104static struct v4l2_fmtdesc pvr_fmtdesc [] = { 98static struct v4l2_fmtdesc pvr_fmtdesc [] = {
105 { 99 {
106 .index = 0, 100 .index = 0,
@@ -154,6 +148,18 @@ static struct v4l2_format pvr_format [] = {
154 } 148 }
155}; 149};
156 150
151
152static const char *get_v4l_name(int v4l_type)
153{
154 switch (v4l_type) {
155 case VFL_TYPE_GRABBER: return "video";
156 case VFL_TYPE_RADIO: return "radio";
157 case VFL_TYPE_VBI: return "vbi";
158 default: return "?";
159 }
160}
161
162
157/* 163/*
158 * pvr_ioctl() 164 * pvr_ioctl()
159 * 165 *
@@ -315,13 +321,39 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
315 321
316 case VIDIOC_ENUMAUDIO: 322 case VIDIOC_ENUMAUDIO:
317 { 323 {
324 /* pkt: FIXME: We are returning one "fake" input here
325 which could very well be called "whatever_we_like".
326 This is for apps that want to see an audio input
327 just to feel comfortable, as well as to test if
328 it can do stereo or sth. There is actually no guarantee
329 that the actual audio input cannot change behind the app's
330 back, but most applications should not mind that either.
331
332 Hopefully, mplayer people will work with us on this (this
333 whole mess is to support mplayer pvr://), or Hans will come
334 up with a more standard way to say "we have inputs but we
335 don 't want you to change them independent of video" which
336 will sort this mess.
337 */
338 struct v4l2_audio *vin = arg;
318 ret = -EINVAL; 339 ret = -EINVAL;
340 if (vin->index > 0) break;
341 strncpy(vin->name, "PVRUSB2 Audio",14);
342 vin->capability = V4L2_AUDCAP_STEREO;
343 ret = 0;
344 break;
319 break; 345 break;
320 } 346 }
321 347
322 case VIDIOC_G_AUDIO: 348 case VIDIOC_G_AUDIO:
323 { 349 {
324 ret = -EINVAL; 350 /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
351 struct v4l2_audio *vin = arg;
352 memset(vin,0,sizeof(*vin));
353 vin->index = 0;
354 strncpy(vin->name, "PVRUSB2 Audio",14);
355 vin->capability = V4L2_AUDCAP_STEREO;
356 ret = 0;
325 break; 357 break;
326 } 358 }
327 359
@@ -333,34 +365,11 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
333 case VIDIOC_G_TUNER: 365 case VIDIOC_G_TUNER:
334 { 366 {
335 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 367 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
336 unsigned int status_mask;
337 int val;
338 if (vt->index !=0) break;
339 368
340 status_mask = pvr2_hdw_get_signal_status(hdw); 369 if (vt->index != 0) break; /* Only answer for the 1st tuner */
341 370
342 memcpy(vt, &pvr_v4l2_tuners[vt->index], 371 pvr2_hdw_execute_tuner_poll(hdw);
343 sizeof(struct v4l2_tuner)); 372 ret = pvr2_hdw_get_tuner_status(hdw,vt);
344
345 vt->signal = 0;
346 if (status_mask & PVR2_SIGNAL_OK) {
347 if (status_mask & PVR2_SIGNAL_STEREO) {
348 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
349 } else {
350 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
351 }
352 if (status_mask & PVR2_SIGNAL_SAP) {
353 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
354 V4L2_TUNER_SUB_LANG2);
355 }
356 vt->signal = 65535;
357 }
358
359 val = 0;
360 ret = pvr2_ctrl_get_value(
361 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
362 &val);
363 vt->audmode = val;
364 break; 373 break;
365 } 374 }
366 375
@@ -374,14 +383,40 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
374 ret = pvr2_ctrl_set_value( 383 ret = pvr2_ctrl_set_value(
375 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), 384 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
376 vt->audmode); 385 vt->audmode);
386 break;
377 } 387 }
378 388
379 case VIDIOC_S_FREQUENCY: 389 case VIDIOC_S_FREQUENCY:
380 { 390 {
381 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 391 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
392 unsigned long fv;
393 struct v4l2_tuner vt;
394 int cur_input;
395 struct pvr2_ctrl *ctrlp;
396 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
397 if (ret != 0) break;
398 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
399 ret = pvr2_ctrl_get_value(ctrlp,&cur_input);
400 if (ret != 0) break;
401 if (vf->type == V4L2_TUNER_RADIO) {
402 if (cur_input != PVR2_CVAL_INPUT_RADIO) {
403 pvr2_ctrl_set_value(ctrlp,
404 PVR2_CVAL_INPUT_RADIO);
405 }
406 } else {
407 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
408 pvr2_ctrl_set_value(ctrlp,
409 PVR2_CVAL_INPUT_TV);
410 }
411 }
412 fv = vf->frequency;
413 if (vt.capability & V4L2_TUNER_CAP_LOW) {
414 fv = (fv * 125) / 2;
415 } else {
416 fv = fv * 62500;
417 }
382 ret = pvr2_ctrl_set_value( 418 ret = pvr2_ctrl_set_value(
383 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), 419 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
384 vf->frequency * 62500);
385 break; 420 break;
386 } 421 }
387 422
@@ -389,10 +424,27 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
389 { 424 {
390 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 425 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
391 int val = 0; 426 int val = 0;
427 int cur_input;
428 struct v4l2_tuner vt;
429 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
430 if (ret != 0) break;
392 ret = pvr2_ctrl_get_value( 431 ret = pvr2_ctrl_get_value(
393 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), 432 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
394 &val); 433 &val);
395 val /= 62500; 434 if (ret != 0) break;
435 pvr2_ctrl_get_value(
436 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
437 &cur_input);
438 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
439 vf->type = V4L2_TUNER_RADIO;
440 } else {
441 vf->type = V4L2_TUNER_ANALOG_TV;
442 }
443 if (vt.capability & V4L2_TUNER_CAP_LOW) {
444 val = (val * 2) / 125;
445 } else {
446 val /= 62500;
447 }
396 vf->frequency = val; 448 vf->frequency = val;
397 break; 449 break;
398 } 450 }
@@ -449,7 +501,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
449 ret = 0; 501 ret = 0;
450 switch(vf->type) { 502 switch(vf->type) {
451 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 503 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
452 int lmin,lmax; 504 int lmin,lmax,ldef;
453 struct pvr2_ctrl *hcp,*vcp; 505 struct pvr2_ctrl *hcp,*vcp;
454 int h = vf->fmt.pix.height; 506 int h = vf->fmt.pix.height;
455 int w = vf->fmt.pix.width; 507 int w = vf->fmt.pix.width;
@@ -458,14 +510,20 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
458 510
459 lmin = pvr2_ctrl_get_min(hcp); 511 lmin = pvr2_ctrl_get_min(hcp);
460 lmax = pvr2_ctrl_get_max(hcp); 512 lmax = pvr2_ctrl_get_max(hcp);
461 if (w < lmin) { 513 ldef = pvr2_ctrl_get_def(hcp);
514 if (w == -1) {
515 w = ldef;
516 } else if (w < lmin) {
462 w = lmin; 517 w = lmin;
463 } else if (w > lmax) { 518 } else if (w > lmax) {
464 w = lmax; 519 w = lmax;
465 } 520 }
466 lmin = pvr2_ctrl_get_min(vcp); 521 lmin = pvr2_ctrl_get_min(vcp);
467 lmax = pvr2_ctrl_get_max(vcp); 522 lmax = pvr2_ctrl_get_max(vcp);
468 if (h < lmin) { 523 ldef = pvr2_ctrl_get_def(vcp);
524 if (h == -1) {
525 h = ldef;
526 } else if (h < lmin) {
469 h = lmin; 527 h = lmin;
470 } else if (h > lmax) { 528 } else if (h > lmax) {
471 h = lmax; 529 h = lmax;
@@ -494,6 +552,13 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
494 552
495 case VIDIOC_STREAMON: 553 case VIDIOC_STREAMON:
496 { 554 {
555 if (!fh->dev_info->stream) {
556 /* No stream defined for this node. This means
557 that we're not currently allowed to stream from
558 this node. */
559 ret = -EPERM;
560 break;
561 }
497 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config); 562 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
498 if (ret < 0) return ret; 563 if (ret < 0) return ret;
499 ret = pvr2_hdw_set_streaming(hdw,!0); 564 ret = pvr2_hdw_set_streaming(hdw,!0);
@@ -502,6 +567,13 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
502 567
503 case VIDIOC_STREAMOFF: 568 case VIDIOC_STREAMOFF:
504 { 569 {
570 if (!fh->dev_info->stream) {
571 /* No stream defined for this node. This means
572 that we're not currently allowed to stream from
573 this node. */
574 ret = -EPERM;
575 break;
576 }
505 ret = pvr2_hdw_set_streaming(hdw,0); 577 ret = pvr2_hdw_set_streaming(hdw,0);
506 break; 578 break;
507 } 579 }
@@ -599,6 +671,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
599 struct v4l2_ext_control *ctrl; 671 struct v4l2_ext_control *ctrl;
600 unsigned int idx; 672 unsigned int idx;
601 int val; 673 int val;
674 ret = 0;
602 for (idx = 0; idx < ctls->count; idx++) { 675 for (idx = 0; idx < ctls->count; idx++) {
603 ctrl = ctls->controls + idx; 676 ctrl = ctls->controls + idx;
604 ret = pvr2_ctrl_get_value( 677 ret = pvr2_ctrl_get_value(
@@ -621,6 +694,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
621 (struct v4l2_ext_controls *)arg; 694 (struct v4l2_ext_controls *)arg;
622 struct v4l2_ext_control *ctrl; 695 struct v4l2_ext_control *ctrl;
623 unsigned int idx; 696 unsigned int idx;
697 ret = 0;
624 for (idx = 0; idx < ctls->count; idx++) { 698 for (idx = 0; idx < ctls->count; idx++) {
625 ctrl = ctls->controls + idx; 699 ctrl = ctls->controls + idx;
626 ret = pvr2_ctrl_set_value( 700 ret = pvr2_ctrl_set_value(
@@ -643,6 +717,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
643 unsigned int idx; 717 unsigned int idx;
644 /* For the moment just validate that the requested control 718 /* For the moment just validate that the requested control
645 actually exists. */ 719 actually exists. */
720 ret = 0;
646 for (idx = 0; idx < ctls->count; idx++) { 721 for (idx = 0; idx < ctls->count; idx++) {
647 ctrl = ctls->controls + idx; 722 ctrl = ctls->controls + idx;
648 pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id); 723 pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
@@ -662,16 +737,16 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
662 break; 737 break;
663 } 738 }
664#ifdef CONFIG_VIDEO_ADV_DEBUG 739#ifdef CONFIG_VIDEO_ADV_DEBUG
665 case VIDIOC_INT_G_REGISTER: 740 case VIDIOC_DBG_S_REGISTER:
666 case VIDIOC_INT_S_REGISTER: 741 case VIDIOC_DBG_G_REGISTER:
667 { 742 {
668 u32 val; 743 u32 val;
669 struct v4l2_register *req = (struct v4l2_register *)arg; 744 struct v4l2_register *req = (struct v4l2_register *)arg;
670 if (cmd == VIDIOC_INT_S_REGISTER) val = req->val; 745 if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
671 ret = pvr2_hdw_register_access( 746 ret = pvr2_hdw_register_access(
672 hdw,req->i2c_id,req->reg, 747 hdw,req->i2c_id,req->reg,
673 cmd == VIDIOC_INT_S_REGISTER,&val); 748 cmd == VIDIOC_DBG_S_REGISTER,&val);
674 if (cmd == VIDIOC_INT_G_REGISTER) req->val = val; 749 if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
675 break; 750 break;
676 } 751 }
677#endif 752#endif
@@ -707,8 +782,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
707 782
708static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) 783static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
709{ 784{
710 printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n", 785 int minor_id = dip->devbase.minor;
711 dip->devbase.minor,pvr2_config_get_name(dip->config)); 786 struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
787 enum pvr2_config cfg = dip->config;
788 int v4l_type = dip->v4l_type;
789
790 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
712 791
713 /* Paranoia */ 792 /* Paranoia */
714 dip->v4lp = NULL; 793 dip->v4lp = NULL;
@@ -717,13 +796,24 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
717 /* Actual deallocation happens later when all internal references 796 /* Actual deallocation happens later when all internal references
718 are gone. */ 797 are gone. */
719 video_unregister_device(&dip->devbase); 798 video_unregister_device(&dip->devbase);
799
800 printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
801 get_v4l_name(v4l_type),minor_id & 0x1f,
802 pvr2_config_get_name(cfg));
803
720} 804}
721 805
722 806
723static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) 807static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
724{ 808{
725 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1); 809 if (vp->dev_video) {
726 pvr2_v4l2_dev_destroy(vp->vdev); 810 pvr2_v4l2_dev_destroy(vp->dev_video);
811 vp->dev_video = 0;
812 }
813 if (vp->dev_radio) {
814 pvr2_v4l2_dev_destroy(vp->dev_radio);
815 vp->dev_radio = 0;
816 }
727 817
728 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); 818 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
729 pvr2_channel_done(&vp->channel); 819 pvr2_channel_done(&vp->channel);
@@ -766,23 +856,37 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
766 struct pvr2_v4l2_fh *fhp = file->private_data; 856 struct pvr2_v4l2_fh *fhp = file->private_data;
767 struct pvr2_v4l2 *vp = fhp->vhead; 857 struct pvr2_v4l2 *vp = fhp->vhead;
768 struct pvr2_context *mp = fhp->vhead->channel.mc_head; 858 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
859 struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
769 860
770 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); 861 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
771 862
772 if (fhp->rhp) { 863 if (fhp->rhp) {
773 struct pvr2_stream *sp; 864 struct pvr2_stream *sp;
774 struct pvr2_hdw *hdw;
775 hdw = fhp->channel.mc_head->hdw;
776 pvr2_hdw_set_streaming(hdw,0); 865 pvr2_hdw_set_streaming(hdw,0);
777 sp = pvr2_ioread_get_stream(fhp->rhp); 866 sp = pvr2_ioread_get_stream(fhp->rhp);
778 if (sp) pvr2_stream_set_callback(sp,NULL,NULL); 867 if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
779 pvr2_ioread_destroy(fhp->rhp); 868 pvr2_ioread_destroy(fhp->rhp);
780 fhp->rhp = NULL; 869 fhp->rhp = NULL;
781 } 870 }
871
782 v4l2_prio_close(&vp->prio, &fhp->prio); 872 v4l2_prio_close(&vp->prio, &fhp->prio);
783 file->private_data = NULL; 873 file->private_data = NULL;
784 874
785 pvr2_context_enter(mp); do { 875 pvr2_context_enter(mp); do {
876 /* Restore the previous input selection, if it makes sense
877 to do so. */
878 if (fhp->dev_info->v4l_type == VFL_TYPE_RADIO) {
879 struct pvr2_ctrl *cp;
880 int pval;
881 cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
882 pvr2_ctrl_get_value(cp,&pval);
883 /* Only restore if we're still selecting the radio */
884 if (pval == PVR2_CVAL_INPUT_RADIO) {
885 pvr2_ctrl_set_value(cp,fhp->prev_input_val);
886 pvr2_hdw_commit_ctl(hdw);
887 }
888 }
889
786 if (fhp->vnext) { 890 if (fhp->vnext) {
787 fhp->vnext->vprev = fhp->vprev; 891 fhp->vnext->vprev = fhp->vprev;
788 } else { 892 } else {
@@ -828,11 +932,10 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
828 return -EIO; 932 return -EIO;
829 } 933 }
830 934
831 fhp = kmalloc(sizeof(*fhp),GFP_KERNEL); 935 fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
832 if (!fhp) { 936 if (!fhp) {
833 return -ENOMEM; 937 return -ENOMEM;
834 } 938 }
835 memset(fhp,0,sizeof(*fhp));
836 939
837 init_waitqueue_head(&fhp->wait_data); 940 init_waitqueue_head(&fhp->wait_data);
838 fhp->dev_info = dip; 941 fhp->dev_info = dip;
@@ -840,6 +943,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
840 pvr2_context_enter(vp->channel.mc_head); do { 943 pvr2_context_enter(vp->channel.mc_head); do {
841 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); 944 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
842 pvr2_channel_init(&fhp->channel,vp->channel.mc_head); 945 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
946
843 fhp->vnext = NULL; 947 fhp->vnext = NULL;
844 fhp->vprev = vp->vlast; 948 fhp->vprev = vp->vlast;
845 if (vp->vlast) { 949 if (vp->vlast) {
@@ -849,6 +953,18 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file)
849 } 953 }
850 vp->vlast = fhp; 954 vp->vlast = fhp;
851 fhp->vhead = vp; 955 fhp->vhead = vp;
956
957 /* Opening the /dev/radioX device implies a mode switch.
958 So execute that here. Note that you can get the
959 IDENTICAL effect merely by opening the normal video
960 device and setting the input appropriately. */
961 if (dip->v4l_type == VFL_TYPE_RADIO) {
962 struct pvr2_ctrl *cp;
963 cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
964 pvr2_ctrl_get_value(cp,&fhp->prev_input_val);
965 pvr2_ctrl_set_value(cp,PVR2_CVAL_INPUT_RADIO);
966 pvr2_hdw_commit_ctl(hdw);
967 }
852 } while (0); pvr2_context_exit(vp->channel.mc_head); 968 } while (0); pvr2_context_exit(vp->channel.mc_head);
853 969
854 fhp->file = file; 970 fhp->file = file;
@@ -873,6 +989,12 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
873 struct pvr2_hdw *hdw; 989 struct pvr2_hdw *hdw;
874 if (fh->rhp) return 0; 990 if (fh->rhp) return 0;
875 991
992 if (!fh->dev_info->stream) {
993 /* No stream defined for this node. This means that we're
994 not currently allowed to stream from this node. */
995 return -EPERM;
996 }
997
876 /* First read() attempt. Try to claim the stream and start 998 /* First read() attempt. Try to claim the stream and start
877 it... */ 999 it... */
878 if ((ret = pvr2_channel_claim_stream(&fh->channel, 1000 if ((ret = pvr2_channel_claim_stream(&fh->channel,
@@ -1012,25 +1134,37 @@ static struct video_device vdev_template = {
1012 1134
1013static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, 1135static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1014 struct pvr2_v4l2 *vp, 1136 struct pvr2_v4l2 *vp,
1015 enum pvr2_config cfg) 1137 int v4l_type)
1016{ 1138{
1017 int mindevnum; 1139 int mindevnum;
1018 int unit_number; 1140 int unit_number;
1019 int v4l_type; 1141 int *nr_ptr = 0;
1020 dip->v4lp = vp; 1142 dip->v4lp = vp;
1021 dip->config = cfg;
1022 1143
1023 1144
1024 switch (cfg) { 1145 dip->v4l_type = v4l_type;
1025 case pvr2_config_mpeg: 1146 switch (v4l_type) {
1026 v4l_type = VFL_TYPE_GRABBER; 1147 case VFL_TYPE_GRABBER:
1027 dip->stream = &vp->channel.mc_head->video_stream; 1148 dip->stream = &vp->channel.mc_head->video_stream;
1149 dip->config = pvr2_config_mpeg;
1150 dip->minor_type = pvr2_v4l_type_video;
1151 nr_ptr = video_nr;
1152 if (!dip->stream) {
1153 err("Failed to set up pvrusb2 v4l video dev"
1154 " due to missing stream instance");
1155 return;
1156 }
1028 break; 1157 break;
1029 case pvr2_config_vbi: 1158 case VFL_TYPE_VBI:
1030 v4l_type = VFL_TYPE_VBI; 1159 dip->config = pvr2_config_vbi;
1160 dip->minor_type = pvr2_v4l_type_vbi;
1161 nr_ptr = vbi_nr;
1031 break; 1162 break;
1032 case pvr2_config_radio: 1163 case VFL_TYPE_RADIO:
1033 v4l_type = VFL_TYPE_RADIO; 1164 dip->stream = &vp->channel.mc_head->video_stream;
1165 dip->config = pvr2_config_mpeg;
1166 dip->minor_type = pvr2_v4l_type_radio;
1167 nr_ptr = radio_nr;
1034 break; 1168 break;
1035 default: 1169 default:
1036 /* Bail out (this should be impossible) */ 1170 /* Bail out (this should be impossible) */
@@ -1039,30 +1173,27 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1039 return; 1173 return;
1040 } 1174 }
1041 1175
1042 if (!dip->stream) {
1043 err("Failed to set up pvrusb2 v4l dev"
1044 " due to missing stream instance");
1045 return;
1046 }
1047
1048 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template)); 1176 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1049 dip->devbase.release = pvr2_video_device_release; 1177 dip->devbase.release = pvr2_video_device_release;
1050 1178
1051 mindevnum = -1; 1179 mindevnum = -1;
1052 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); 1180 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
1053 if ((unit_number >= 0) && (unit_number < PVR_NUM)) { 1181 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1054 mindevnum = video_nr[unit_number]; 1182 mindevnum = nr_ptr[unit_number];
1055 } 1183 }
1056 if ((video_register_device(&dip->devbase, v4l_type, mindevnum) < 0) && 1184 if ((video_register_device(&dip->devbase,
1057 (video_register_device(&dip->devbase, v4l_type, -1) < 0)) { 1185 dip->v4l_type, mindevnum) < 0) &&
1058 err("Failed to register pvrusb2 v4l video device"); 1186 (video_register_device(&dip->devbase,
1059 } else { 1187 dip->v4l_type, -1) < 0)) {
1060 printk(KERN_INFO "pvrusb2: registered device video%d [%s]\n", 1188 err("Failed to register pvrusb2 v4l device");
1061 dip->devbase.minor,pvr2_config_get_name(dip->config));
1062 } 1189 }
1063 1190
1191 printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
1192 get_v4l_name(dip->v4l_type),dip->devbase.minor & 0x1f,
1193 pvr2_config_get_name(dip->config));
1194
1064 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, 1195 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1065 dip->devbase.minor); 1196 dip->minor_type,dip->devbase.minor);
1066} 1197}
1067 1198
1068 1199
@@ -1070,22 +1201,24 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1070{ 1201{
1071 struct pvr2_v4l2 *vp; 1202 struct pvr2_v4l2 *vp;
1072 1203
1073 vp = kmalloc(sizeof(*vp),GFP_KERNEL); 1204 vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1074 if (!vp) return vp; 1205 if (!vp) return vp;
1075 memset(vp,0,sizeof(*vp)); 1206 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1076 vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL); 1207 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1077 if (!vp->vdev) { 1208 if (!(vp->dev_video && vp->dev_radio)) {
1209 kfree(vp->dev_video);
1210 kfree(vp->dev_radio);
1078 kfree(vp); 1211 kfree(vp);
1079 return NULL; 1212 return NULL;
1080 } 1213 }
1081 memset(vp->vdev,0,sizeof(*vp->vdev));
1082 pvr2_channel_init(&vp->channel,mnp); 1214 pvr2_channel_init(&vp->channel,mnp);
1083 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); 1215 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1084 1216
1085 vp->channel.check_func = pvr2_v4l2_internal_check; 1217 vp->channel.check_func = pvr2_v4l2_internal_check;
1086 1218
1087 /* register streams */ 1219 /* register streams */
1088 pvr2_v4l2_dev_init(vp->vdev,vp,pvr2_config_mpeg); 1220 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
1221 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1089 1222
1090 return vp; 1223 return vp;
1091} 1224}