diff options
Diffstat (limited to 'drivers/media/usb/hdpvr/hdpvr-video.c')
-rw-r--r-- | drivers/media/usb/hdpvr/hdpvr-video.c | 945 |
1 files changed, 452 insertions, 493 deletions
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index da6b77912222..774ba0e820be 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/kconfig.h> | ||
13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -20,9 +21,11 @@ | |||
20 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
21 | 22 | ||
22 | #include <linux/videodev2.h> | 23 | #include <linux/videodev2.h> |
24 | #include <linux/v4l2-dv-timings.h> | ||
23 | #include <media/v4l2-dev.h> | 25 | #include <media/v4l2-dev.h> |
24 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
25 | #include <media/v4l2-ioctl.h> | 27 | #include <media/v4l2-ioctl.h> |
28 | #include <media/v4l2-event.h> | ||
26 | #include "hdpvr.h" | 29 | #include "hdpvr.h" |
27 | 30 | ||
28 | #define BULK_URB_TIMEOUT 90 /* 0.09 seconds */ | 31 | #define BULK_URB_TIMEOUT 90 /* 0.09 seconds */ |
@@ -34,8 +37,23 @@ | |||
34 | list_size(&dev->free_buff_list), \ | 37 | list_size(&dev->free_buff_list), \ |
35 | list_size(&dev->rec_buff_list)); } | 38 | list_size(&dev->rec_buff_list)); } |
36 | 39 | ||
40 | static const struct v4l2_dv_timings hdpvr_dv_timings[] = { | ||
41 | V4L2_DV_BT_CEA_720X480I59_94, | ||
42 | V4L2_DV_BT_CEA_720X576I50, | ||
43 | V4L2_DV_BT_CEA_720X480P59_94, | ||
44 | V4L2_DV_BT_CEA_720X576P50, | ||
45 | V4L2_DV_BT_CEA_1280X720P50, | ||
46 | V4L2_DV_BT_CEA_1280X720P60, | ||
47 | V4L2_DV_BT_CEA_1920X1080I50, | ||
48 | V4L2_DV_BT_CEA_1920X1080I60, | ||
49 | }; | ||
50 | |||
51 | /* Use 480i59 as the default timings */ | ||
52 | #define HDPVR_DEF_DV_TIMINGS_IDX (0) | ||
53 | |||
37 | struct hdpvr_fh { | 54 | struct hdpvr_fh { |
38 | struct hdpvr_device *dev; | 55 | struct v4l2_fh fh; |
56 | bool legacy_mode; | ||
39 | }; | 57 | }; |
40 | 58 | ||
41 | static uint list_size(struct list_head *list) | 59 | static uint list_size(struct list_head *list) |
@@ -359,53 +377,29 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) | |||
359 | 377 | ||
360 | static int hdpvr_open(struct file *file) | 378 | static int hdpvr_open(struct file *file) |
361 | { | 379 | { |
362 | struct hdpvr_device *dev; | 380 | struct hdpvr_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
363 | struct hdpvr_fh *fh; | ||
364 | int retval = -ENOMEM; | ||
365 | |||
366 | dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); | ||
367 | if (!dev) { | ||
368 | pr_err("open failing with with ENODEV\n"); | ||
369 | retval = -ENODEV; | ||
370 | goto err; | ||
371 | } | ||
372 | |||
373 | fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL); | ||
374 | if (!fh) { | ||
375 | v4l2_err(&dev->v4l2_dev, "Out of memory\n"); | ||
376 | goto err; | ||
377 | } | ||
378 | /* lock the device to allow correctly handling errors | ||
379 | * in resumption */ | ||
380 | mutex_lock(&dev->io_mutex); | ||
381 | dev->open_count++; | ||
382 | mutex_unlock(&dev->io_mutex); | ||
383 | 381 | ||
384 | fh->dev = dev; | 382 | if (fh == NULL) |
385 | 383 | return -ENOMEM; | |
386 | /* save our object in the file's private structure */ | 384 | fh->legacy_mode = true; |
385 | v4l2_fh_init(&fh->fh, video_devdata(file)); | ||
386 | v4l2_fh_add(&fh->fh); | ||
387 | file->private_data = fh; | 387 | file->private_data = fh; |
388 | 388 | return 0; | |
389 | retval = 0; | ||
390 | err: | ||
391 | return retval; | ||
392 | } | 389 | } |
393 | 390 | ||
394 | static int hdpvr_release(struct file *file) | 391 | static int hdpvr_release(struct file *file) |
395 | { | 392 | { |
396 | struct hdpvr_fh *fh = file->private_data; | 393 | struct hdpvr_device *dev = video_drvdata(file); |
397 | struct hdpvr_device *dev = fh->dev; | ||
398 | |||
399 | if (!dev) | ||
400 | return -ENODEV; | ||
401 | 394 | ||
402 | mutex_lock(&dev->io_mutex); | 395 | mutex_lock(&dev->io_mutex); |
403 | if (!(--dev->open_count) && dev->status == STATUS_STREAMING) | 396 | if (file->private_data == dev->owner) { |
404 | hdpvr_stop_streaming(dev); | 397 | hdpvr_stop_streaming(dev); |
405 | 398 | dev->owner = NULL; | |
399 | } | ||
406 | mutex_unlock(&dev->io_mutex); | 400 | mutex_unlock(&dev->io_mutex); |
407 | 401 | ||
408 | return 0; | 402 | return v4l2_fh_release(file); |
409 | } | 403 | } |
410 | 404 | ||
411 | /* | 405 | /* |
@@ -415,8 +409,7 @@ static int hdpvr_release(struct file *file) | |||
415 | static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, | 409 | static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, |
416 | loff_t *pos) | 410 | loff_t *pos) |
417 | { | 411 | { |
418 | struct hdpvr_fh *fh = file->private_data; | 412 | struct hdpvr_device *dev = video_drvdata(file); |
419 | struct hdpvr_device *dev = fh->dev; | ||
420 | struct hdpvr_buffer *buf = NULL; | 413 | struct hdpvr_buffer *buf = NULL; |
421 | struct urb *urb; | 414 | struct urb *urb; |
422 | unsigned int ret = 0; | 415 | unsigned int ret = 0; |
@@ -425,9 +418,6 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, | |||
425 | if (*pos) | 418 | if (*pos) |
426 | return -ESPIPE; | 419 | return -ESPIPE; |
427 | 420 | ||
428 | if (!dev) | ||
429 | return -ENODEV; | ||
430 | |||
431 | mutex_lock(&dev->io_mutex); | 421 | mutex_lock(&dev->io_mutex); |
432 | if (dev->status == STATUS_IDLE) { | 422 | if (dev->status == STATUS_IDLE) { |
433 | if (hdpvr_start_streaming(dev)) { | 423 | if (hdpvr_start_streaming(dev)) { |
@@ -439,6 +429,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, | |||
439 | mutex_unlock(&dev->io_mutex); | 429 | mutex_unlock(&dev->io_mutex); |
440 | goto err; | 430 | goto err; |
441 | } | 431 | } |
432 | dev->owner = file->private_data; | ||
442 | print_buffer_status(); | 433 | print_buffer_status(); |
443 | } | 434 | } |
444 | mutex_unlock(&dev->io_mutex); | 435 | mutex_unlock(&dev->io_mutex); |
@@ -516,23 +507,23 @@ err: | |||
516 | 507 | ||
517 | static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) | 508 | static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) |
518 | { | 509 | { |
510 | unsigned long req_events = poll_requested_events(wait); | ||
519 | struct hdpvr_buffer *buf = NULL; | 511 | struct hdpvr_buffer *buf = NULL; |
520 | struct hdpvr_fh *fh = filp->private_data; | 512 | struct hdpvr_device *dev = video_drvdata(filp); |
521 | struct hdpvr_device *dev = fh->dev; | 513 | unsigned int mask = v4l2_ctrl_poll(filp, wait); |
522 | unsigned int mask = 0; | ||
523 | 514 | ||
524 | mutex_lock(&dev->io_mutex); | 515 | if (!(req_events & (POLLIN | POLLRDNORM))) |
516 | return mask; | ||
525 | 517 | ||
526 | if (!video_is_registered(dev->video_dev)) { | 518 | mutex_lock(&dev->io_mutex); |
527 | mutex_unlock(&dev->io_mutex); | ||
528 | return -EIO; | ||
529 | } | ||
530 | 519 | ||
531 | if (dev->status == STATUS_IDLE) { | 520 | if (dev->status == STATUS_IDLE) { |
532 | if (hdpvr_start_streaming(dev)) { | 521 | if (hdpvr_start_streaming(dev)) { |
533 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, | 522 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, |
534 | "start_streaming failed\n"); | 523 | "start_streaming failed\n"); |
535 | dev->status = STATUS_IDLE; | 524 | dev->status = STATUS_IDLE; |
525 | } else { | ||
526 | dev->owner = filp->private_data; | ||
536 | } | 527 | } |
537 | 528 | ||
538 | print_buffer_status(); | 529 | print_buffer_status(); |
@@ -574,36 +565,188 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
574 | strcpy(cap->driver, "hdpvr"); | 565 | strcpy(cap->driver, "hdpvr"); |
575 | strcpy(cap->card, "Hauppauge HD PVR"); | 566 | strcpy(cap->card, "Hauppauge HD PVR"); |
576 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | 567 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); |
577 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 568 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO | |
578 | V4L2_CAP_AUDIO | | 569 | V4L2_CAP_READWRITE; |
579 | V4L2_CAP_READWRITE; | 570 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
580 | return 0; | 571 | return 0; |
581 | } | 572 | } |
582 | 573 | ||
583 | static int vidioc_s_std(struct file *file, void *private_data, | 574 | static int vidioc_s_std(struct file *file, void *_fh, |
584 | v4l2_std_id *std) | 575 | v4l2_std_id std) |
585 | { | 576 | { |
586 | struct hdpvr_fh *fh = file->private_data; | 577 | struct hdpvr_device *dev = video_drvdata(file); |
587 | struct hdpvr_device *dev = fh->dev; | 578 | struct hdpvr_fh *fh = _fh; |
588 | u8 std_type = 1; | 579 | u8 std_type = 1; |
589 | 580 | ||
590 | if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60)) | 581 | if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT) |
582 | return -ENODATA; | ||
583 | if (dev->status != STATUS_IDLE) | ||
584 | return -EBUSY; | ||
585 | if (std & V4L2_STD_525_60) | ||
591 | std_type = 0; | 586 | std_type = 0; |
587 | dev->cur_std = std; | ||
588 | dev->width = 720; | ||
589 | dev->height = std_type ? 576 : 480; | ||
592 | 590 | ||
593 | return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type); | 591 | return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type); |
594 | } | 592 | } |
595 | 593 | ||
594 | static int vidioc_g_std(struct file *file, void *_fh, | ||
595 | v4l2_std_id *std) | ||
596 | { | ||
597 | struct hdpvr_device *dev = video_drvdata(file); | ||
598 | struct hdpvr_fh *fh = _fh; | ||
599 | |||
600 | if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT) | ||
601 | return -ENODATA; | ||
602 | *std = dev->cur_std; | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a) | ||
607 | { | ||
608 | struct hdpvr_device *dev = video_drvdata(file); | ||
609 | struct hdpvr_video_info *vid_info; | ||
610 | struct hdpvr_fh *fh = _fh; | ||
611 | |||
612 | *a = V4L2_STD_ALL; | ||
613 | if (dev->options.video_input == HDPVR_COMPONENT) | ||
614 | return fh->legacy_mode ? 0 : -ENODATA; | ||
615 | vid_info = get_video_info(dev); | ||
616 | if (vid_info == NULL) | ||
617 | return 0; | ||
618 | if (vid_info->width == 720 && | ||
619 | (vid_info->height == 480 || vid_info->height == 576)) { | ||
620 | *a = (vid_info->height == 480) ? | ||
621 | V4L2_STD_525_60 : V4L2_STD_625_50; | ||
622 | } | ||
623 | kfree(vid_info); | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int vidioc_s_dv_timings(struct file *file, void *_fh, | ||
628 | struct v4l2_dv_timings *timings) | ||
629 | { | ||
630 | struct hdpvr_device *dev = video_drvdata(file); | ||
631 | struct hdpvr_fh *fh = _fh; | ||
632 | int i; | ||
633 | |||
634 | fh->legacy_mode = false; | ||
635 | if (dev->options.video_input) | ||
636 | return -ENODATA; | ||
637 | if (dev->status != STATUS_IDLE) | ||
638 | return -EBUSY; | ||
639 | for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) | ||
640 | if (v4l_match_dv_timings(timings, hdpvr_dv_timings + i, 0)) | ||
641 | break; | ||
642 | if (i == ARRAY_SIZE(hdpvr_dv_timings)) | ||
643 | return -EINVAL; | ||
644 | dev->cur_dv_timings = hdpvr_dv_timings[i]; | ||
645 | dev->width = hdpvr_dv_timings[i].bt.width; | ||
646 | dev->height = hdpvr_dv_timings[i].bt.height; | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static int vidioc_g_dv_timings(struct file *file, void *_fh, | ||
651 | struct v4l2_dv_timings *timings) | ||
652 | { | ||
653 | struct hdpvr_device *dev = video_drvdata(file); | ||
654 | struct hdpvr_fh *fh = _fh; | ||
655 | |||
656 | fh->legacy_mode = false; | ||
657 | if (dev->options.video_input) | ||
658 | return -ENODATA; | ||
659 | *timings = dev->cur_dv_timings; | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static int vidioc_query_dv_timings(struct file *file, void *_fh, | ||
664 | struct v4l2_dv_timings *timings) | ||
665 | { | ||
666 | struct hdpvr_device *dev = video_drvdata(file); | ||
667 | struct hdpvr_fh *fh = _fh; | ||
668 | struct hdpvr_video_info *vid_info; | ||
669 | bool interlaced; | ||
670 | int ret = 0; | ||
671 | int i; | ||
672 | |||
673 | fh->legacy_mode = false; | ||
674 | if (dev->options.video_input) | ||
675 | return -ENODATA; | ||
676 | vid_info = get_video_info(dev); | ||
677 | if (vid_info == NULL) | ||
678 | return -ENOLCK; | ||
679 | interlaced = vid_info->fps <= 30; | ||
680 | for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) { | ||
681 | const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt; | ||
682 | unsigned hsize; | ||
683 | unsigned vsize; | ||
684 | unsigned fps; | ||
685 | |||
686 | hsize = bt->hfrontporch + bt->hsync + bt->hbackporch + bt->width; | ||
687 | vsize = bt->vfrontporch + bt->vsync + bt->vbackporch + | ||
688 | bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch + | ||
689 | bt->height; | ||
690 | fps = (unsigned)bt->pixelclock / (hsize * vsize); | ||
691 | if (bt->width != vid_info->width || | ||
692 | bt->height != vid_info->height || | ||
693 | bt->interlaced != interlaced || | ||
694 | (fps != vid_info->fps && fps + 1 != vid_info->fps)) | ||
695 | continue; | ||
696 | *timings = hdpvr_dv_timings[i]; | ||
697 | break; | ||
698 | } | ||
699 | if (i == ARRAY_SIZE(hdpvr_dv_timings)) | ||
700 | ret = -ERANGE; | ||
701 | kfree(vid_info); | ||
702 | return ret; | ||
703 | } | ||
704 | |||
705 | static int vidioc_enum_dv_timings(struct file *file, void *_fh, | ||
706 | struct v4l2_enum_dv_timings *timings) | ||
707 | { | ||
708 | struct hdpvr_device *dev = video_drvdata(file); | ||
709 | struct hdpvr_fh *fh = _fh; | ||
710 | |||
711 | fh->legacy_mode = false; | ||
712 | memset(timings->reserved, 0, sizeof(timings->reserved)); | ||
713 | if (dev->options.video_input) | ||
714 | return -ENODATA; | ||
715 | if (timings->index >= ARRAY_SIZE(hdpvr_dv_timings)) | ||
716 | return -EINVAL; | ||
717 | timings->timings = hdpvr_dv_timings[timings->index]; | ||
718 | return 0; | ||
719 | } | ||
720 | |||
721 | static int vidioc_dv_timings_cap(struct file *file, void *_fh, | ||
722 | struct v4l2_dv_timings_cap *cap) | ||
723 | { | ||
724 | struct hdpvr_device *dev = video_drvdata(file); | ||
725 | struct hdpvr_fh *fh = _fh; | ||
726 | |||
727 | fh->legacy_mode = false; | ||
728 | if (dev->options.video_input) | ||
729 | return -ENODATA; | ||
730 | cap->type = V4L2_DV_BT_656_1120; | ||
731 | cap->bt.min_width = 720; | ||
732 | cap->bt.max_width = 1920; | ||
733 | cap->bt.min_height = 480; | ||
734 | cap->bt.max_height = 1080; | ||
735 | cap->bt.min_pixelclock = 27000000; | ||
736 | cap->bt.max_pixelclock = 74250000; | ||
737 | cap->bt.standards = V4L2_DV_BT_STD_CEA861; | ||
738 | cap->bt.capabilities = V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE; | ||
739 | return 0; | ||
740 | } | ||
741 | |||
596 | static const char *iname[] = { | 742 | static const char *iname[] = { |
597 | [HDPVR_COMPONENT] = "Component", | 743 | [HDPVR_COMPONENT] = "Component", |
598 | [HDPVR_SVIDEO] = "S-Video", | 744 | [HDPVR_SVIDEO] = "S-Video", |
599 | [HDPVR_COMPOSITE] = "Composite", | 745 | [HDPVR_COMPOSITE] = "Composite", |
600 | }; | 746 | }; |
601 | 747 | ||
602 | static int vidioc_enum_input(struct file *file, void *priv, | 748 | static int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i) |
603 | struct v4l2_input *i) | ||
604 | { | 749 | { |
605 | struct hdpvr_fh *fh = file->private_data; | ||
606 | struct hdpvr_device *dev = fh->dev; | ||
607 | unsigned int n; | 750 | unsigned int n; |
608 | 751 | ||
609 | n = i->index; | 752 | n = i->index; |
@@ -617,27 +760,42 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
617 | 760 | ||
618 | i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF; | 761 | i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF; |
619 | 762 | ||
620 | i->std = dev->video_dev->tvnorms; | 763 | i->capabilities = n ? V4L2_IN_CAP_STD : V4L2_IN_CAP_DV_TIMINGS; |
764 | i->std = n ? V4L2_STD_ALL : 0; | ||
621 | 765 | ||
622 | return 0; | 766 | return 0; |
623 | } | 767 | } |
624 | 768 | ||
625 | static int vidioc_s_input(struct file *file, void *private_data, | 769 | static int vidioc_s_input(struct file *file, void *_fh, |
626 | unsigned int index) | 770 | unsigned int index) |
627 | { | 771 | { |
628 | struct hdpvr_fh *fh = file->private_data; | 772 | struct hdpvr_device *dev = video_drvdata(file); |
629 | struct hdpvr_device *dev = fh->dev; | ||
630 | int retval; | 773 | int retval; |
631 | 774 | ||
632 | if (index >= HDPVR_VIDEO_INPUTS) | 775 | if (index >= HDPVR_VIDEO_INPUTS) |
633 | return -EINVAL; | 776 | return -EINVAL; |
634 | 777 | ||
635 | if (dev->status != STATUS_IDLE) | 778 | if (dev->status != STATUS_IDLE) |
636 | return -EAGAIN; | 779 | return -EBUSY; |
637 | 780 | ||
638 | retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1); | 781 | retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1); |
639 | if (!retval) | 782 | if (!retval) { |
640 | dev->options.video_input = index; | 783 | dev->options.video_input = index; |
784 | /* | ||
785 | * Unfortunately gstreamer calls ENUMSTD and bails out if it | ||
786 | * won't find any formats, even though component input is | ||
787 | * selected. This means that we have to leave tvnorms at | ||
788 | * V4L2_STD_ALL. We cannot use the 'legacy' trick since | ||
789 | * tvnorms is set at the device node level and not at the | ||
790 | * filehandle level. | ||
791 | * | ||
792 | * Comment this out for now, but if the legacy mode can be | ||
793 | * removed in the future, then this code should be enabled | ||
794 | * again. | ||
795 | dev->video_dev->tvnorms = | ||
796 | (index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0; | ||
797 | */ | ||
798 | } | ||
641 | 799 | ||
642 | return retval; | 800 | return retval; |
643 | } | 801 | } |
@@ -645,8 +803,7 @@ static int vidioc_s_input(struct file *file, void *private_data, | |||
645 | static int vidioc_g_input(struct file *file, void *private_data, | 803 | static int vidioc_g_input(struct file *file, void *private_data, |
646 | unsigned int *index) | 804 | unsigned int *index) |
647 | { | 805 | { |
648 | struct hdpvr_fh *fh = file->private_data; | 806 | struct hdpvr_device *dev = video_drvdata(file); |
649 | struct hdpvr_device *dev = fh->dev; | ||
650 | 807 | ||
651 | *index = dev->options.video_input; | 808 | *index = dev->options.video_input; |
652 | return 0; | 809 | return 0; |
@@ -679,15 +836,14 @@ static int vidioc_enumaudio(struct file *file, void *priv, | |||
679 | static int vidioc_s_audio(struct file *file, void *private_data, | 836 | static int vidioc_s_audio(struct file *file, void *private_data, |
680 | const struct v4l2_audio *audio) | 837 | const struct v4l2_audio *audio) |
681 | { | 838 | { |
682 | struct hdpvr_fh *fh = file->private_data; | 839 | struct hdpvr_device *dev = video_drvdata(file); |
683 | struct hdpvr_device *dev = fh->dev; | ||
684 | int retval; | 840 | int retval; |
685 | 841 | ||
686 | if (audio->index >= HDPVR_AUDIO_INPUTS) | 842 | if (audio->index >= HDPVR_AUDIO_INPUTS) |
687 | return -EINVAL; | 843 | return -EINVAL; |
688 | 844 | ||
689 | if (dev->status != STATUS_IDLE) | 845 | if (dev->status != STATUS_IDLE) |
690 | return -EAGAIN; | 846 | return -EBUSY; |
691 | 847 | ||
692 | retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec); | 848 | retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec); |
693 | if (!retval) | 849 | if (!retval) |
@@ -699,8 +855,7 @@ static int vidioc_s_audio(struct file *file, void *private_data, | |||
699 | static int vidioc_g_audio(struct file *file, void *private_data, | 855 | static int vidioc_g_audio(struct file *file, void *private_data, |
700 | struct v4l2_audio *audio) | 856 | struct v4l2_audio *audio) |
701 | { | 857 | { |
702 | struct hdpvr_fh *fh = file->private_data; | 858 | struct hdpvr_device *dev = video_drvdata(file); |
703 | struct hdpvr_device *dev = fh->dev; | ||
704 | 859 | ||
705 | audio->index = dev->options.audio_input; | 860 | audio->index = dev->options.audio_input; |
706 | audio->capability = V4L2_AUDCAP_STEREO; | 861 | audio->capability = V4L2_AUDCAP_STEREO; |
@@ -709,335 +864,69 @@ static int vidioc_g_audio(struct file *file, void *private_data, | |||
709 | return 0; | 864 | return 0; |
710 | } | 865 | } |
711 | 866 | ||
712 | static const s32 supported_v4l2_ctrls[] = { | 867 | static int hdpvr_try_ctrl(struct v4l2_ctrl *ctrl) |
713 | V4L2_CID_BRIGHTNESS, | ||
714 | V4L2_CID_CONTRAST, | ||
715 | V4L2_CID_SATURATION, | ||
716 | V4L2_CID_HUE, | ||
717 | V4L2_CID_SHARPNESS, | ||
718 | V4L2_CID_MPEG_AUDIO_ENCODING, | ||
719 | V4L2_CID_MPEG_VIDEO_ENCODING, | ||
720 | V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
721 | V4L2_CID_MPEG_VIDEO_BITRATE, | ||
722 | V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
723 | }; | ||
724 | |||
725 | static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc, | ||
726 | int ac3, int fw_ver) | ||
727 | { | ||
728 | int err; | ||
729 | |||
730 | if (fw_ver > 0x15) { | ||
731 | switch (qc->id) { | ||
732 | case V4L2_CID_BRIGHTNESS: | ||
733 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
734 | case V4L2_CID_CONTRAST: | ||
735 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40); | ||
736 | case V4L2_CID_SATURATION: | ||
737 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40); | ||
738 | case V4L2_CID_HUE: | ||
739 | return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf); | ||
740 | case V4L2_CID_SHARPNESS: | ||
741 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
742 | } | ||
743 | } else { | ||
744 | switch (qc->id) { | ||
745 | case V4L2_CID_BRIGHTNESS: | ||
746 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86); | ||
747 | case V4L2_CID_CONTRAST: | ||
748 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
749 | case V4L2_CID_SATURATION: | ||
750 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
751 | case V4L2_CID_HUE: | ||
752 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
753 | case V4L2_CID_SHARPNESS: | ||
754 | return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | switch (qc->id) { | ||
759 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
760 | return v4l2_ctrl_query_fill( | ||
761 | qc, V4L2_MPEG_AUDIO_ENCODING_AAC, | ||
762 | ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 | ||
763 | : V4L2_MPEG_AUDIO_ENCODING_AAC, | ||
764 | 1, V4L2_MPEG_AUDIO_ENCODING_AAC); | ||
765 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
766 | return v4l2_ctrl_query_fill( | ||
767 | qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, | ||
768 | V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, | ||
769 | V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); | ||
770 | |||
771 | /* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */ | ||
772 | /* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */ | ||
773 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
774 | return v4l2_ctrl_query_fill( | ||
775 | qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
776 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, | ||
777 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); | ||
778 | |||
779 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
780 | return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000, | ||
781 | 6500000); | ||
782 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
783 | err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000, | ||
784 | 9000000); | ||
785 | if (!err && opt->bitrate_mode == HDPVR_CONSTANT) | ||
786 | qc->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
787 | return err; | ||
788 | default: | ||
789 | return -EINVAL; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | static int vidioc_queryctrl(struct file *file, void *private_data, | ||
794 | struct v4l2_queryctrl *qc) | ||
795 | { | ||
796 | struct hdpvr_fh *fh = file->private_data; | ||
797 | struct hdpvr_device *dev = fh->dev; | ||
798 | int i, next; | ||
799 | u32 id = qc->id; | ||
800 | |||
801 | memset(qc, 0, sizeof(*qc)); | ||
802 | |||
803 | next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); | ||
804 | qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; | ||
805 | |||
806 | for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) { | ||
807 | if (next) { | ||
808 | if (qc->id < supported_v4l2_ctrls[i]) | ||
809 | qc->id = supported_v4l2_ctrls[i]; | ||
810 | else | ||
811 | continue; | ||
812 | } | ||
813 | |||
814 | if (qc->id == supported_v4l2_ctrls[i]) | ||
815 | return fill_queryctrl(&dev->options, qc, | ||
816 | dev->flags & HDPVR_FLAG_AC3_CAP, | ||
817 | dev->fw_ver); | ||
818 | |||
819 | if (qc->id < supported_v4l2_ctrls[i]) | ||
820 | break; | ||
821 | } | ||
822 | |||
823 | return -EINVAL; | ||
824 | } | ||
825 | |||
826 | static int vidioc_g_ctrl(struct file *file, void *private_data, | ||
827 | struct v4l2_control *ctrl) | ||
828 | { | 868 | { |
829 | struct hdpvr_fh *fh = file->private_data; | 869 | struct hdpvr_device *dev = |
830 | struct hdpvr_device *dev = fh->dev; | 870 | container_of(ctrl->handler, struct hdpvr_device, hdl); |
831 | 871 | ||
832 | switch (ctrl->id) { | 872 | switch (ctrl->id) { |
833 | case V4L2_CID_BRIGHTNESS: | 873 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: |
834 | ctrl->value = dev->options.brightness; | 874 | if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && |
835 | break; | 875 | dev->video_bitrate->val >= dev->video_bitrate_peak->val) |
836 | case V4L2_CID_CONTRAST: | 876 | dev->video_bitrate_peak->val = |
837 | ctrl->value = dev->options.contrast; | 877 | dev->video_bitrate->val + 100000; |
838 | break; | ||
839 | case V4L2_CID_SATURATION: | ||
840 | ctrl->value = dev->options.saturation; | ||
841 | break; | ||
842 | case V4L2_CID_HUE: | ||
843 | ctrl->value = dev->options.hue; | ||
844 | break; | ||
845 | case V4L2_CID_SHARPNESS: | ||
846 | ctrl->value = dev->options.sharpness; | ||
847 | break; | 878 | break; |
848 | default: | ||
849 | return -EINVAL; | ||
850 | } | 879 | } |
851 | return 0; | 880 | return 0; |
852 | } | 881 | } |
853 | 882 | ||
854 | static int vidioc_s_ctrl(struct file *file, void *private_data, | 883 | static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl) |
855 | struct v4l2_control *ctrl) | ||
856 | { | 884 | { |
857 | struct hdpvr_fh *fh = file->private_data; | 885 | struct hdpvr_device *dev = |
858 | struct hdpvr_device *dev = fh->dev; | 886 | container_of(ctrl->handler, struct hdpvr_device, hdl); |
859 | int retval; | 887 | struct hdpvr_options *opt = &dev->options; |
888 | int ret = -EINVAL; | ||
860 | 889 | ||
861 | switch (ctrl->id) { | 890 | switch (ctrl->id) { |
862 | case V4L2_CID_BRIGHTNESS: | 891 | case V4L2_CID_BRIGHTNESS: |
863 | retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value); | 892 | ret = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->val); |
864 | if (!retval) | 893 | if (ret) |
865 | dev->options.brightness = ctrl->value; | 894 | break; |
866 | break; | 895 | dev->options.brightness = ctrl->val; |
896 | return 0; | ||
867 | case V4L2_CID_CONTRAST: | 897 | case V4L2_CID_CONTRAST: |
868 | retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value); | 898 | ret = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->val); |
869 | if (!retval) | 899 | if (ret) |
870 | dev->options.contrast = ctrl->value; | 900 | break; |
871 | break; | 901 | dev->options.contrast = ctrl->val; |
902 | return 0; | ||
872 | case V4L2_CID_SATURATION: | 903 | case V4L2_CID_SATURATION: |
873 | retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value); | 904 | ret = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->val); |
874 | if (!retval) | 905 | if (ret) |
875 | dev->options.saturation = ctrl->value; | 906 | break; |
876 | break; | 907 | dev->options.saturation = ctrl->val; |
908 | return 0; | ||
877 | case V4L2_CID_HUE: | 909 | case V4L2_CID_HUE: |
878 | retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value); | 910 | ret = hdpvr_config_call(dev, CTRL_HUE, ctrl->val); |
879 | if (!retval) | 911 | if (ret) |
880 | dev->options.hue = ctrl->value; | 912 | break; |
881 | break; | 913 | dev->options.hue = ctrl->val; |
914 | return 0; | ||
882 | case V4L2_CID_SHARPNESS: | 915 | case V4L2_CID_SHARPNESS: |
883 | retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value); | 916 | ret = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->val); |
884 | if (!retval) | 917 | if (ret) |
885 | dev->options.sharpness = ctrl->value; | 918 | break; |
886 | break; | 919 | dev->options.sharpness = ctrl->val; |
887 | default: | 920 | return 0; |
888 | return -EINVAL; | ||
889 | } | ||
890 | |||
891 | return retval; | ||
892 | } | ||
893 | |||
894 | |||
895 | static int hdpvr_get_ctrl(struct hdpvr_options *opt, | ||
896 | struct v4l2_ext_control *ctrl) | ||
897 | { | ||
898 | switch (ctrl->id) { | ||
899 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
900 | ctrl->value = opt->audio_codec; | ||
901 | break; | ||
902 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
903 | ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC; | ||
904 | break; | ||
905 | /* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ | ||
906 | /* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */ | ||
907 | /* break; */ | ||
908 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
909 | ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT | ||
910 | ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR | ||
911 | : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; | ||
912 | break; | ||
913 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
914 | ctrl->value = opt->bitrate * 100000; | ||
915 | break; | ||
916 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
917 | ctrl->value = opt->peak_bitrate * 100000; | ||
918 | break; | ||
919 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
920 | ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; | ||
921 | break; | ||
922 | default: | ||
923 | return -EINVAL; | ||
924 | } | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int vidioc_g_ext_ctrls(struct file *file, void *priv, | ||
929 | struct v4l2_ext_controls *ctrls) | ||
930 | { | ||
931 | struct hdpvr_fh *fh = file->private_data; | ||
932 | struct hdpvr_device *dev = fh->dev; | ||
933 | int i, err = 0; | ||
934 | |||
935 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
936 | for (i = 0; i < ctrls->count; i++) { | ||
937 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
938 | |||
939 | err = hdpvr_get_ctrl(&dev->options, ctrl); | ||
940 | if (err) { | ||
941 | ctrls->error_idx = i; | ||
942 | break; | ||
943 | } | ||
944 | } | ||
945 | return err; | ||
946 | |||
947 | } | ||
948 | |||
949 | return -EINVAL; | ||
950 | } | ||
951 | |||
952 | |||
953 | static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) | ||
954 | { | ||
955 | int ret = -EINVAL; | ||
956 | |||
957 | switch (ctrl->id) { | ||
958 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
959 | if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC || | ||
960 | (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3)) | ||
961 | ret = 0; | ||
962 | break; | ||
963 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
964 | if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC) | ||
965 | ret = 0; | ||
966 | break; | ||
967 | /* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ | ||
968 | /* if (ctrl->value == 0 || ctrl->value == 128) */ | ||
969 | /* ret = 0; */ | ||
970 | /* break; */ | ||
971 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
972 | if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || | ||
973 | ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | ||
974 | ret = 0; | ||
975 | break; | ||
976 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
977 | { | ||
978 | uint bitrate = ctrl->value / 100000; | ||
979 | if (bitrate >= 10 && bitrate <= 135) | ||
980 | ret = 0; | ||
981 | break; | ||
982 | } | ||
983 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
984 | { | ||
985 | uint peak_bitrate = ctrl->value / 100000; | ||
986 | if (peak_bitrate >= 10 && peak_bitrate <= 202) | ||
987 | ret = 0; | ||
988 | break; | ||
989 | } | ||
990 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
991 | if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) | ||
992 | ret = 0; | ||
993 | break; | ||
994 | default: | ||
995 | return -EINVAL; | ||
996 | } | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | static int vidioc_try_ext_ctrls(struct file *file, void *priv, | ||
1001 | struct v4l2_ext_controls *ctrls) | ||
1002 | { | ||
1003 | struct hdpvr_fh *fh = file->private_data; | ||
1004 | struct hdpvr_device *dev = fh->dev; | ||
1005 | int i, err = 0; | ||
1006 | |||
1007 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
1008 | for (i = 0; i < ctrls->count; i++) { | ||
1009 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
1010 | |||
1011 | err = hdpvr_try_ctrl(ctrl, | ||
1012 | dev->flags & HDPVR_FLAG_AC3_CAP); | ||
1013 | if (err) { | ||
1014 | ctrls->error_idx = i; | ||
1015 | break; | ||
1016 | } | ||
1017 | } | ||
1018 | return err; | ||
1019 | } | ||
1020 | |||
1021 | return -EINVAL; | ||
1022 | } | ||
1023 | |||
1024 | |||
1025 | static int hdpvr_set_ctrl(struct hdpvr_device *dev, | ||
1026 | struct v4l2_ext_control *ctrl) | ||
1027 | { | ||
1028 | struct hdpvr_options *opt = &dev->options; | ||
1029 | int ret = 0; | ||
1030 | |||
1031 | switch (ctrl->id) { | ||
1032 | case V4L2_CID_MPEG_AUDIO_ENCODING: | 921 | case V4L2_CID_MPEG_AUDIO_ENCODING: |
1033 | if (dev->flags & HDPVR_FLAG_AC3_CAP) { | 922 | if (dev->flags & HDPVR_FLAG_AC3_CAP) { |
1034 | opt->audio_codec = ctrl->value; | 923 | opt->audio_codec = ctrl->val; |
1035 | ret = hdpvr_set_audio(dev, opt->audio_input, | 924 | return hdpvr_set_audio(dev, opt->audio_input, |
1036 | opt->audio_codec); | 925 | opt->audio_codec); |
1037 | } | 926 | } |
1038 | break; | 927 | return 0; |
1039 | case V4L2_CID_MPEG_VIDEO_ENCODING: | 928 | case V4L2_CID_MPEG_VIDEO_ENCODING: |
1040 | break; | 929 | return 0; |
1041 | /* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ | 930 | /* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ |
1042 | /* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ | 931 | /* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ |
1043 | /* opt->gop_mode |= 0x2; */ | 932 | /* opt->gop_mode |= 0x2; */ |
@@ -1050,86 +939,41 @@ static int hdpvr_set_ctrl(struct hdpvr_device *dev, | |||
1050 | /* opt->gop_mode); */ | 939 | /* opt->gop_mode); */ |
1051 | /* } */ | 940 | /* } */ |
1052 | /* break; */ | 941 | /* break; */ |
1053 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | 942 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: { |
1054 | if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && | 943 | uint peak_bitrate = dev->video_bitrate_peak->val / 100000; |
1055 | opt->bitrate_mode != HDPVR_CONSTANT) { | 944 | uint bitrate = dev->video_bitrate->val / 100000; |
1056 | opt->bitrate_mode = HDPVR_CONSTANT; | 945 | |
1057 | hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, | 946 | if (ctrl->is_new) { |
1058 | opt->bitrate_mode); | 947 | if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) |
1059 | } | 948 | opt->bitrate_mode = HDPVR_CONSTANT; |
1060 | if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && | 949 | else |
1061 | opt->bitrate_mode == HDPVR_CONSTANT) { | 950 | opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE; |
1062 | opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE; | ||
1063 | hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, | 951 | hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, |
1064 | opt->bitrate_mode); | 952 | opt->bitrate_mode); |
953 | v4l2_ctrl_activate(dev->video_bitrate_peak, | ||
954 | ctrl->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); | ||
1065 | } | 955 | } |
1066 | break; | ||
1067 | case V4L2_CID_MPEG_VIDEO_BITRATE: { | ||
1068 | uint bitrate = ctrl->value / 100000; | ||
1069 | |||
1070 | opt->bitrate = bitrate; | ||
1071 | if (bitrate >= opt->peak_bitrate) | ||
1072 | opt->peak_bitrate = bitrate+1; | ||
1073 | |||
1074 | hdpvr_set_bitrate(dev); | ||
1075 | break; | ||
1076 | } | ||
1077 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: { | ||
1078 | uint peak_bitrate = ctrl->value / 100000; | ||
1079 | |||
1080 | if (opt->bitrate_mode == HDPVR_CONSTANT) | ||
1081 | break; | ||
1082 | 956 | ||
1083 | if (opt->bitrate < peak_bitrate) { | 957 | if (dev->video_bitrate_peak->is_new || |
958 | dev->video_bitrate->is_new) { | ||
959 | opt->bitrate = bitrate; | ||
1084 | opt->peak_bitrate = peak_bitrate; | 960 | opt->peak_bitrate = peak_bitrate; |
1085 | hdpvr_set_bitrate(dev); | 961 | hdpvr_set_bitrate(dev); |
1086 | } else | 962 | } |
1087 | ret = -EINVAL; | 963 | return 0; |
1088 | break; | ||
1089 | } | 964 | } |
1090 | case V4L2_CID_MPEG_STREAM_TYPE: | 965 | case V4L2_CID_MPEG_STREAM_TYPE: |
1091 | break; | 966 | return 0; |
1092 | default: | 967 | default: |
1093 | return -EINVAL; | 968 | break; |
1094 | } | 969 | } |
1095 | return ret; | 970 | return ret; |
1096 | } | 971 | } |
1097 | 972 | ||
1098 | static int vidioc_s_ext_ctrls(struct file *file, void *priv, | ||
1099 | struct v4l2_ext_controls *ctrls) | ||
1100 | { | ||
1101 | struct hdpvr_fh *fh = file->private_data; | ||
1102 | struct hdpvr_device *dev = fh->dev; | ||
1103 | int i, err = 0; | ||
1104 | |||
1105 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
1106 | for (i = 0; i < ctrls->count; i++) { | ||
1107 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
1108 | |||
1109 | err = hdpvr_try_ctrl(ctrl, | ||
1110 | dev->flags & HDPVR_FLAG_AC3_CAP); | ||
1111 | if (err) { | ||
1112 | ctrls->error_idx = i; | ||
1113 | break; | ||
1114 | } | ||
1115 | err = hdpvr_set_ctrl(dev, ctrl); | ||
1116 | if (err) { | ||
1117 | ctrls->error_idx = i; | ||
1118 | break; | ||
1119 | } | ||
1120 | } | ||
1121 | return err; | ||
1122 | |||
1123 | } | ||
1124 | |||
1125 | return -EINVAL; | ||
1126 | } | ||
1127 | |||
1128 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, | 973 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, |
1129 | struct v4l2_fmtdesc *f) | 974 | struct v4l2_fmtdesc *f) |
1130 | { | 975 | { |
1131 | 976 | if (f->index != 0) | |
1132 | if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1133 | return -EINVAL; | 977 | return -EINVAL; |
1134 | 978 | ||
1135 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | 979 | f->flags = V4L2_FMT_FLAG_COMPRESSED; |
@@ -1139,56 +983,92 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, | |||
1139 | return 0; | 983 | return 0; |
1140 | } | 984 | } |
1141 | 985 | ||
1142 | static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data, | 986 | static int vidioc_g_fmt_vid_cap(struct file *file, void *_fh, |
1143 | struct v4l2_format *f) | 987 | struct v4l2_format *f) |
1144 | { | 988 | { |
1145 | struct hdpvr_fh *fh = file->private_data; | 989 | struct hdpvr_device *dev = video_drvdata(file); |
1146 | struct hdpvr_device *dev = fh->dev; | 990 | struct hdpvr_fh *fh = _fh; |
1147 | struct hdpvr_video_info *vid_info; | 991 | |
1148 | 992 | /* | |
1149 | if (!dev) | 993 | * The original driver would always returns the current detected |
1150 | return -ENODEV; | 994 | * resolution as the format (and EFAULT if it couldn't be detected). |
1151 | 995 | * With the introduction of VIDIOC_QUERY_DV_TIMINGS there is now a | |
1152 | vid_info = get_video_info(dev); | 996 | * better way of doing this, but to stay compatible with existing |
1153 | if (!vid_info) | 997 | * applications we assume legacy mode every time an application opens |
1154 | return -EFAULT; | 998 | * the device. Only if one of the new DV_TIMINGS ioctls is called |
1155 | 999 | * will the filehandle go into 'normal' mode where g_fmt returns the | |
1156 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1000 | * last set format. |
1001 | */ | ||
1002 | if (fh->legacy_mode) { | ||
1003 | struct hdpvr_video_info *vid_info; | ||
1004 | |||
1005 | vid_info = get_video_info(dev); | ||
1006 | if (!vid_info) | ||
1007 | return -EFAULT; | ||
1008 | f->fmt.pix.width = vid_info->width; | ||
1009 | f->fmt.pix.height = vid_info->height; | ||
1010 | kfree(vid_info); | ||
1011 | } else { | ||
1012 | f->fmt.pix.width = dev->width; | ||
1013 | f->fmt.pix.height = dev->height; | ||
1014 | } | ||
1157 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 1015 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
1158 | f->fmt.pix.width = vid_info->width; | ||
1159 | f->fmt.pix.height = vid_info->height; | ||
1160 | f->fmt.pix.sizeimage = dev->bulk_in_size; | 1016 | f->fmt.pix.sizeimage = dev->bulk_in_size; |
1161 | f->fmt.pix.colorspace = 0; | ||
1162 | f->fmt.pix.bytesperline = 0; | 1017 | f->fmt.pix.bytesperline = 0; |
1163 | f->fmt.pix.field = V4L2_FIELD_ANY; | 1018 | f->fmt.pix.priv = 0; |
1164 | 1019 | if (f->fmt.pix.width == 720) { | |
1165 | kfree(vid_info); | 1020 | /* SDTV formats */ |
1021 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1022 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
1023 | } else { | ||
1024 | /* HDTV formats */ | ||
1025 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE240M; | ||
1026 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1027 | } | ||
1166 | return 0; | 1028 | return 0; |
1167 | } | 1029 | } |
1168 | 1030 | ||
1169 | static int vidioc_encoder_cmd(struct file *filp, void *priv, | 1031 | static int vidioc_encoder_cmd(struct file *filp, void *priv, |
1170 | struct v4l2_encoder_cmd *a) | 1032 | struct v4l2_encoder_cmd *a) |
1171 | { | 1033 | { |
1172 | struct hdpvr_fh *fh = filp->private_data; | 1034 | struct hdpvr_device *dev = video_drvdata(filp); |
1173 | struct hdpvr_device *dev = fh->dev; | 1035 | int res = 0; |
1174 | int res; | ||
1175 | 1036 | ||
1176 | mutex_lock(&dev->io_mutex); | 1037 | mutex_lock(&dev->io_mutex); |
1038 | a->flags = 0; | ||
1177 | 1039 | ||
1178 | memset(&a->raw, 0, sizeof(a->raw)); | ||
1179 | switch (a->cmd) { | 1040 | switch (a->cmd) { |
1180 | case V4L2_ENC_CMD_START: | 1041 | case V4L2_ENC_CMD_START: |
1181 | a->flags = 0; | 1042 | if (dev->owner && filp->private_data != dev->owner) { |
1043 | res = -EBUSY; | ||
1044 | break; | ||
1045 | } | ||
1046 | if (dev->status == STATUS_STREAMING) | ||
1047 | break; | ||
1182 | res = hdpvr_start_streaming(dev); | 1048 | res = hdpvr_start_streaming(dev); |
1049 | if (!res) | ||
1050 | dev->owner = filp->private_data; | ||
1051 | else | ||
1052 | dev->status = STATUS_IDLE; | ||
1183 | break; | 1053 | break; |
1184 | case V4L2_ENC_CMD_STOP: | 1054 | case V4L2_ENC_CMD_STOP: |
1055 | if (dev->owner && filp->private_data != dev->owner) { | ||
1056 | res = -EBUSY; | ||
1057 | break; | ||
1058 | } | ||
1059 | if (dev->status == STATUS_IDLE) | ||
1060 | break; | ||
1185 | res = hdpvr_stop_streaming(dev); | 1061 | res = hdpvr_stop_streaming(dev); |
1062 | if (!res) | ||
1063 | dev->owner = NULL; | ||
1186 | break; | 1064 | break; |
1187 | default: | 1065 | default: |
1188 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, | 1066 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, |
1189 | "Unsupported encoder cmd %d\n", a->cmd); | 1067 | "Unsupported encoder cmd %d\n", a->cmd); |
1190 | res = -EINVAL; | 1068 | res = -EINVAL; |
1069 | break; | ||
1191 | } | 1070 | } |
1071 | |||
1192 | mutex_unlock(&dev->io_mutex); | 1072 | mutex_unlock(&dev->io_mutex); |
1193 | return res; | 1073 | return res; |
1194 | } | 1074 | } |
@@ -1196,6 +1076,7 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv, | |||
1196 | static int vidioc_try_encoder_cmd(struct file *filp, void *priv, | 1076 | static int vidioc_try_encoder_cmd(struct file *filp, void *priv, |
1197 | struct v4l2_encoder_cmd *a) | 1077 | struct v4l2_encoder_cmd *a) |
1198 | { | 1078 | { |
1079 | a->flags = 0; | ||
1199 | switch (a->cmd) { | 1080 | switch (a->cmd) { |
1200 | case V4L2_ENC_CMD_START: | 1081 | case V4L2_ENC_CMD_START: |
1201 | case V4L2_ENC_CMD_STOP: | 1082 | case V4L2_ENC_CMD_STOP: |
@@ -1208,22 +1089,28 @@ static int vidioc_try_encoder_cmd(struct file *filp, void *priv, | |||
1208 | static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = { | 1089 | static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = { |
1209 | .vidioc_querycap = vidioc_querycap, | 1090 | .vidioc_querycap = vidioc_querycap, |
1210 | .vidioc_s_std = vidioc_s_std, | 1091 | .vidioc_s_std = vidioc_s_std, |
1092 | .vidioc_g_std = vidioc_g_std, | ||
1093 | .vidioc_querystd = vidioc_querystd, | ||
1094 | .vidioc_s_dv_timings = vidioc_s_dv_timings, | ||
1095 | .vidioc_g_dv_timings = vidioc_g_dv_timings, | ||
1096 | .vidioc_query_dv_timings= vidioc_query_dv_timings, | ||
1097 | .vidioc_enum_dv_timings = vidioc_enum_dv_timings, | ||
1098 | .vidioc_dv_timings_cap = vidioc_dv_timings_cap, | ||
1211 | .vidioc_enum_input = vidioc_enum_input, | 1099 | .vidioc_enum_input = vidioc_enum_input, |
1212 | .vidioc_g_input = vidioc_g_input, | 1100 | .vidioc_g_input = vidioc_g_input, |
1213 | .vidioc_s_input = vidioc_s_input, | 1101 | .vidioc_s_input = vidioc_s_input, |
1214 | .vidioc_enumaudio = vidioc_enumaudio, | 1102 | .vidioc_enumaudio = vidioc_enumaudio, |
1215 | .vidioc_g_audio = vidioc_g_audio, | 1103 | .vidioc_g_audio = vidioc_g_audio, |
1216 | .vidioc_s_audio = vidioc_s_audio, | 1104 | .vidioc_s_audio = vidioc_s_audio, |
1217 | .vidioc_queryctrl = vidioc_queryctrl, | 1105 | .vidioc_enum_fmt_vid_cap= vidioc_enum_fmt_vid_cap, |
1218 | .vidioc_g_ctrl = vidioc_g_ctrl, | 1106 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1219 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1107 | .vidioc_s_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1220 | .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, | 1108 | .vidioc_try_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1221 | .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, | ||
1222 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, | ||
1223 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1224 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1225 | .vidioc_encoder_cmd = vidioc_encoder_cmd, | 1109 | .vidioc_encoder_cmd = vidioc_encoder_cmd, |
1226 | .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, | 1110 | .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, |
1111 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
1112 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1113 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1227 | }; | 1114 | }; |
1228 | 1115 | ||
1229 | static void hdpvr_device_release(struct video_device *vdev) | 1116 | static void hdpvr_device_release(struct video_device *vdev) |
@@ -1236,9 +1123,10 @@ static void hdpvr_device_release(struct video_device *vdev) | |||
1236 | mutex_unlock(&dev->io_mutex); | 1123 | mutex_unlock(&dev->io_mutex); |
1237 | 1124 | ||
1238 | v4l2_device_unregister(&dev->v4l2_dev); | 1125 | v4l2_device_unregister(&dev->v4l2_dev); |
1126 | v4l2_ctrl_handler_free(&dev->hdl); | ||
1239 | 1127 | ||
1240 | /* deregister I2C adapter */ | 1128 | /* deregister I2C adapter */ |
1241 | #if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE) | 1129 | #if IS_ENABLED(CONFIG_I2C) |
1242 | mutex_lock(&dev->i2c_mutex); | 1130 | mutex_lock(&dev->i2c_mutex); |
1243 | i2c_del_adapter(&dev->i2c_adapter); | 1131 | i2c_del_adapter(&dev->i2c_adapter); |
1244 | mutex_unlock(&dev->i2c_mutex); | 1132 | mutex_unlock(&dev->i2c_mutex); |
@@ -1249,41 +1137,112 @@ static void hdpvr_device_release(struct video_device *vdev) | |||
1249 | } | 1137 | } |
1250 | 1138 | ||
1251 | static const struct video_device hdpvr_video_template = { | 1139 | static const struct video_device hdpvr_video_template = { |
1252 | /* .type = VFL_TYPE_GRABBER, */ | ||
1253 | /* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */ | ||
1254 | .fops = &hdpvr_fops, | 1140 | .fops = &hdpvr_fops, |
1255 | .release = hdpvr_device_release, | 1141 | .release = hdpvr_device_release, |
1256 | .ioctl_ops = &hdpvr_ioctl_ops, | 1142 | .ioctl_ops = &hdpvr_ioctl_ops, |
1257 | .tvnorms = | 1143 | .tvnorms = V4L2_STD_ALL, |
1258 | V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B | | 1144 | }; |
1259 | V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I | | 1145 | |
1260 | V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N | | 1146 | static const struct v4l2_ctrl_ops hdpvr_ctrl_ops = { |
1261 | V4L2_STD_PAL_60, | 1147 | .try_ctrl = hdpvr_try_ctrl, |
1262 | .current_norm = V4L2_STD_NTSC | V4L2_STD_PAL_M | | 1148 | .s_ctrl = hdpvr_s_ctrl, |
1263 | V4L2_STD_PAL_60, | ||
1264 | }; | 1149 | }; |
1265 | 1150 | ||
1266 | int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, | 1151 | int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, |
1267 | int devnum) | 1152 | int devnum) |
1268 | { | 1153 | { |
1154 | struct v4l2_ctrl_handler *hdl = &dev->hdl; | ||
1155 | bool ac3 = dev->flags & HDPVR_FLAG_AC3_CAP; | ||
1156 | int res; | ||
1157 | |||
1158 | dev->cur_std = V4L2_STD_525_60; | ||
1159 | dev->width = 720; | ||
1160 | dev->height = 480; | ||
1161 | dev->cur_dv_timings = hdpvr_dv_timings[HDPVR_DEF_DV_TIMINGS_IDX]; | ||
1162 | v4l2_ctrl_handler_init(hdl, 11); | ||
1163 | if (dev->fw_ver > 0x15) { | ||
1164 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1165 | V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x80); | ||
1166 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1167 | V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x40); | ||
1168 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1169 | V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x40); | ||
1170 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1171 | V4L2_CID_HUE, 0x0, 0x1e, 1, 0xf); | ||
1172 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1173 | V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80); | ||
1174 | } else { | ||
1175 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1176 | V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x86); | ||
1177 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1178 | V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x80); | ||
1179 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1180 | V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x80); | ||
1181 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1182 | V4L2_CID_HUE, 0x0, 0xff, 1, 0x80); | ||
1183 | v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1184 | V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80); | ||
1185 | } | ||
1186 | |||
1187 | v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, | ||
1188 | V4L2_CID_MPEG_STREAM_TYPE, | ||
1189 | V4L2_MPEG_STREAM_TYPE_MPEG2_TS, | ||
1190 | 0x1, V4L2_MPEG_STREAM_TYPE_MPEG2_TS); | ||
1191 | v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, | ||
1192 | V4L2_CID_MPEG_AUDIO_ENCODING, | ||
1193 | ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC, | ||
1194 | 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC); | ||
1195 | v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, | ||
1196 | V4L2_CID_MPEG_VIDEO_ENCODING, | ||
1197 | V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3, | ||
1198 | V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); | ||
1199 | |||
1200 | dev->video_mode = v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, | ||
1201 | V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
1202 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, | ||
1203 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); | ||
1204 | |||
1205 | dev->video_bitrate = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1206 | V4L2_CID_MPEG_VIDEO_BITRATE, | ||
1207 | 1000000, 13500000, 100000, 6500000); | ||
1208 | dev->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops, | ||
1209 | V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
1210 | 1100000, 20200000, 100000, 9000000); | ||
1211 | dev->v4l2_dev.ctrl_handler = hdl; | ||
1212 | if (hdl->error) { | ||
1213 | res = hdl->error; | ||
1214 | v4l2_err(&dev->v4l2_dev, "Could not register controls\n"); | ||
1215 | goto error; | ||
1216 | } | ||
1217 | v4l2_ctrl_cluster(3, &dev->video_mode); | ||
1218 | res = v4l2_ctrl_handler_setup(hdl); | ||
1219 | if (res < 0) { | ||
1220 | v4l2_err(&dev->v4l2_dev, "Could not setup controls\n"); | ||
1221 | goto error; | ||
1222 | } | ||
1223 | |||
1269 | /* setup and register video device */ | 1224 | /* setup and register video device */ |
1270 | dev->video_dev = video_device_alloc(); | 1225 | dev->video_dev = video_device_alloc(); |
1271 | if (!dev->video_dev) { | 1226 | if (!dev->video_dev) { |
1272 | v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n"); | 1227 | v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n"); |
1228 | res = -ENOMEM; | ||
1273 | goto error; | 1229 | goto error; |
1274 | } | 1230 | } |
1275 | 1231 | ||
1276 | *(dev->video_dev) = hdpvr_video_template; | 1232 | *dev->video_dev = hdpvr_video_template; |
1277 | strcpy(dev->video_dev->name, "Hauppauge HD PVR"); | 1233 | strcpy(dev->video_dev->name, "Hauppauge HD PVR"); |
1278 | dev->video_dev->parent = parent; | 1234 | dev->video_dev->v4l2_dev = &dev->v4l2_dev; |
1279 | video_set_drvdata(dev->video_dev, dev); | 1235 | video_set_drvdata(dev->video_dev, dev); |
1236 | set_bit(V4L2_FL_USE_FH_PRIO, &dev->video_dev->flags); | ||
1280 | 1237 | ||
1281 | if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) { | 1238 | res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum); |
1239 | if (res < 0) { | ||
1282 | v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); | 1240 | v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); |
1283 | goto error; | 1241 | goto error; |
1284 | } | 1242 | } |
1285 | 1243 | ||
1286 | return 0; | 1244 | return 0; |
1287 | error: | 1245 | error: |
1288 | return -ENOMEM; | 1246 | v4l2_ctrl_handler_free(hdl); |
1247 | return res; | ||
1289 | } | 1248 | } |