| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Video capture interface for Linux version 2 |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * A generic video device interface for the LINUX operating system |
|---|
| 5 | 6 | * using a set of device structures/vectors for low level operations. |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or |
|---|
| 8 | | - * modify it under the terms of the GNU General Public License |
|---|
| 9 | | - * as published by the Free Software Foundation; either version |
|---|
| 10 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 11 | 7 | * |
|---|
| 12 | 8 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
|---|
| 13 | 9 | * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) |
|---|
| .. | .. |
|---|
| 444 | 440 | struct video_device *vdev = video_devdata(filp); |
|---|
| 445 | 441 | int ret = 0; |
|---|
| 446 | 442 | |
|---|
| 447 | | - if (vdev->fops->release) |
|---|
| 448 | | - ret = vdev->fops->release(filp); |
|---|
| 443 | + /* |
|---|
| 444 | + * We need to serialize the release() with queueing new requests. |
|---|
| 445 | + * The release() may trigger the cancellation of a streaming |
|---|
| 446 | + * operation, and that should not be mixed with queueing a new |
|---|
| 447 | + * request at the same time. |
|---|
| 448 | + */ |
|---|
| 449 | + if (vdev->fops->release) { |
|---|
| 450 | + if (v4l2_device_supports_requests(vdev->v4l2_dev)) { |
|---|
| 451 | + mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex); |
|---|
| 452 | + ret = vdev->fops->release(filp); |
|---|
| 453 | + mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex); |
|---|
| 454 | + } else { |
|---|
| 455 | + ret = vdev->fops->release(filp); |
|---|
| 456 | + } |
|---|
| 457 | + } |
|---|
| 458 | + |
|---|
| 449 | 459 | if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP) |
|---|
| 450 | 460 | dprintk("%s: release\n", |
|---|
| 451 | 461 | video_device_node_name(vdev)); |
|---|
| .. | .. |
|---|
| 523 | 533 | */ |
|---|
| 524 | 534 | static void determine_valid_ioctls(struct video_device *vdev) |
|---|
| 525 | 535 | { |
|---|
| 536 | + const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | |
|---|
| 537 | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
|---|
| 538 | + V4L2_CAP_VIDEO_OUTPUT | |
|---|
| 539 | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | |
|---|
| 540 | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; |
|---|
| 541 | + const u32 meta_caps = V4L2_CAP_META_CAPTURE | |
|---|
| 542 | + V4L2_CAP_META_OUTPUT; |
|---|
| 526 | 543 | DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); |
|---|
| 527 | 544 | const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; |
|---|
| 528 | | - bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER; |
|---|
| 545 | + bool is_vid = vdev->vfl_type == VFL_TYPE_VIDEO && |
|---|
| 546 | + (vdev->device_caps & vid_caps); |
|---|
| 529 | 547 | bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI; |
|---|
| 530 | 548 | bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO; |
|---|
| 531 | 549 | bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR; |
|---|
| 532 | 550 | bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH; |
|---|
| 551 | + bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO && |
|---|
| 552 | + (vdev->device_caps & meta_caps); |
|---|
| 533 | 553 | bool is_rx = vdev->vfl_dir != VFL_DIR_TX; |
|---|
| 534 | 554 | bool is_tx = vdev->vfl_dir != VFL_DIR_RX; |
|---|
| 555 | + bool is_io_mc = vdev->device_caps & V4L2_CAP_IO_MC; |
|---|
| 535 | 556 | |
|---|
| 536 | 557 | bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE); |
|---|
| 537 | 558 | |
|---|
| .. | .. |
|---|
| 561 | 582 | set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls); |
|---|
| 562 | 583 | if (vdev->ctrl_handler || ops->vidioc_querymenu) |
|---|
| 563 | 584 | set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); |
|---|
| 564 | | - SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); |
|---|
| 565 | | - SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); |
|---|
| 585 | + if (!is_tch) { |
|---|
| 586 | + SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); |
|---|
| 587 | + SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); |
|---|
| 588 | + } |
|---|
| 566 | 589 | SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status); |
|---|
| 567 | 590 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
|---|
| 568 | 591 | set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_INFO), valid_ioctls); |
|---|
| .. | .. |
|---|
| 576 | 599 | if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator) |
|---|
| 577 | 600 | set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); |
|---|
| 578 | 601 | |
|---|
| 579 | | - if (is_vid || is_tch) { |
|---|
| 580 | | - /* video and metadata specific ioctls */ |
|---|
| 602 | + if (is_vid) { |
|---|
| 603 | + /* video specific ioctls */ |
|---|
| 581 | 604 | if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || |
|---|
| 582 | | - ops->vidioc_enum_fmt_vid_cap_mplane || |
|---|
| 583 | | - ops->vidioc_enum_fmt_vid_overlay || |
|---|
| 584 | | - ops->vidioc_enum_fmt_meta_cap)) || |
|---|
| 585 | | - (is_tx && (ops->vidioc_enum_fmt_vid_out || |
|---|
| 586 | | - ops->vidioc_enum_fmt_vid_out_mplane || |
|---|
| 587 | | - ops->vidioc_enum_fmt_meta_out))) |
|---|
| 605 | + ops->vidioc_enum_fmt_vid_overlay)) || |
|---|
| 606 | + (is_tx && ops->vidioc_enum_fmt_vid_out)) |
|---|
| 588 | 607 | set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); |
|---|
| 589 | 608 | if ((is_rx && (ops->vidioc_g_fmt_vid_cap || |
|---|
| 590 | 609 | ops->vidioc_g_fmt_vid_cap_mplane || |
|---|
| 591 | | - ops->vidioc_g_fmt_vid_overlay || |
|---|
| 592 | | - ops->vidioc_g_fmt_meta_cap)) || |
|---|
| 610 | + ops->vidioc_g_fmt_vid_overlay)) || |
|---|
| 593 | 611 | (is_tx && (ops->vidioc_g_fmt_vid_out || |
|---|
| 594 | 612 | ops->vidioc_g_fmt_vid_out_mplane || |
|---|
| 595 | | - ops->vidioc_g_fmt_vid_out_overlay || |
|---|
| 596 | | - ops->vidioc_g_fmt_meta_out))) |
|---|
| 613 | + ops->vidioc_g_fmt_vid_out_overlay))) |
|---|
| 597 | 614 | set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); |
|---|
| 598 | 615 | if ((is_rx && (ops->vidioc_s_fmt_vid_cap || |
|---|
| 599 | 616 | ops->vidioc_s_fmt_vid_cap_mplane || |
|---|
| 600 | | - ops->vidioc_s_fmt_vid_overlay || |
|---|
| 601 | | - ops->vidioc_s_fmt_meta_cap)) || |
|---|
| 617 | + ops->vidioc_s_fmt_vid_overlay)) || |
|---|
| 602 | 618 | (is_tx && (ops->vidioc_s_fmt_vid_out || |
|---|
| 603 | 619 | ops->vidioc_s_fmt_vid_out_mplane || |
|---|
| 604 | | - ops->vidioc_s_fmt_vid_out_overlay || |
|---|
| 605 | | - ops->vidioc_s_fmt_meta_out))) |
|---|
| 620 | + ops->vidioc_s_fmt_vid_out_overlay))) |
|---|
| 606 | 621 | set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); |
|---|
| 607 | 622 | if ((is_rx && (ops->vidioc_try_fmt_vid_cap || |
|---|
| 608 | 623 | ops->vidioc_try_fmt_vid_cap_mplane || |
|---|
| 609 | | - ops->vidioc_try_fmt_vid_overlay || |
|---|
| 610 | | - ops->vidioc_try_fmt_meta_cap)) || |
|---|
| 624 | + ops->vidioc_try_fmt_vid_overlay)) || |
|---|
| 611 | 625 | (is_tx && (ops->vidioc_try_fmt_vid_out || |
|---|
| 612 | 626 | ops->vidioc_try_fmt_vid_out_mplane || |
|---|
| 613 | | - ops->vidioc_try_fmt_vid_out_overlay || |
|---|
| 614 | | - ops->vidioc_try_fmt_meta_out))) |
|---|
| 627 | + ops->vidioc_try_fmt_vid_out_overlay))) |
|---|
| 615 | 628 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); |
|---|
| 616 | 629 | SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); |
|---|
| 617 | 630 | SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); |
|---|
| .. | .. |
|---|
| 625 | 638 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); |
|---|
| 626 | 639 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); |
|---|
| 627 | 640 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); |
|---|
| 628 | | - if (ops->vidioc_g_crop || ops->vidioc_g_selection) |
|---|
| 641 | + if (ops->vidioc_g_selection) { |
|---|
| 629 | 642 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); |
|---|
| 630 | | - if (ops->vidioc_s_crop || ops->vidioc_s_selection) |
|---|
| 643 | + set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); |
|---|
| 644 | + } |
|---|
| 645 | + if (ops->vidioc_s_selection) |
|---|
| 631 | 646 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); |
|---|
| 632 | 647 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); |
|---|
| 633 | 648 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); |
|---|
| 634 | | - if (ops->vidioc_cropcap || ops->vidioc_g_selection) |
|---|
| 635 | | - set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); |
|---|
| 636 | | - } else if (is_vbi) { |
|---|
| 649 | + } |
|---|
| 650 | + if (is_meta && is_rx) { |
|---|
| 651 | + /* metadata capture specific ioctls */ |
|---|
| 652 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_cap); |
|---|
| 653 | + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_cap); |
|---|
| 654 | + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_cap); |
|---|
| 655 | + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_cap); |
|---|
| 656 | + } else if (is_meta && is_tx) { |
|---|
| 657 | + /* metadata output specific ioctls */ |
|---|
| 658 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_out); |
|---|
| 659 | + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_out); |
|---|
| 660 | + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out); |
|---|
| 661 | + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out); |
|---|
| 662 | + } |
|---|
| 663 | + if (is_vbi) { |
|---|
| 637 | 664 | /* vbi specific ioctls */ |
|---|
| 638 | 665 | if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || |
|---|
| 639 | 666 | ops->vidioc_g_fmt_sliced_vbi_cap)) || |
|---|
| .. | .. |
|---|
| 651 | 678 | ops->vidioc_try_fmt_sliced_vbi_out))) |
|---|
| 652 | 679 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); |
|---|
| 653 | 680 | SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap); |
|---|
| 681 | + } else if (is_tch) { |
|---|
| 682 | + /* touch specific ioctls */ |
|---|
| 683 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_vid_cap); |
|---|
| 684 | + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_vid_cap); |
|---|
| 685 | + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_vid_cap); |
|---|
| 686 | + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_vid_cap); |
|---|
| 687 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); |
|---|
| 688 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); |
|---|
| 689 | + SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); |
|---|
| 690 | + SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); |
|---|
| 691 | + SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); |
|---|
| 692 | + SET_VALID_IOCTL(ops, VIDIOC_G_PARM, vidioc_g_parm); |
|---|
| 693 | + SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); |
|---|
| 654 | 694 | } else if (is_sdr && is_rx) { |
|---|
| 655 | 695 | /* SDR receiver specific ioctls */ |
|---|
| 656 | | - if (ops->vidioc_enum_fmt_sdr_cap) |
|---|
| 657 | | - set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); |
|---|
| 658 | | - if (ops->vidioc_g_fmt_sdr_cap) |
|---|
| 659 | | - set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); |
|---|
| 660 | | - if (ops->vidioc_s_fmt_sdr_cap) |
|---|
| 661 | | - set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); |
|---|
| 662 | | - if (ops->vidioc_try_fmt_sdr_cap) |
|---|
| 663 | | - set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); |
|---|
| 696 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_cap); |
|---|
| 697 | + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_cap); |
|---|
| 698 | + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_cap); |
|---|
| 699 | + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_cap); |
|---|
| 664 | 700 | } else if (is_sdr && is_tx) { |
|---|
| 665 | 701 | /* SDR transmitter specific ioctls */ |
|---|
| 666 | | - if (ops->vidioc_enum_fmt_sdr_out) |
|---|
| 667 | | - set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); |
|---|
| 668 | | - if (ops->vidioc_g_fmt_sdr_out) |
|---|
| 669 | | - set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); |
|---|
| 670 | | - if (ops->vidioc_s_fmt_sdr_out) |
|---|
| 671 | | - set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); |
|---|
| 672 | | - if (ops->vidioc_try_fmt_sdr_out) |
|---|
| 673 | | - set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); |
|---|
| 702 | + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_out); |
|---|
| 703 | + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_out); |
|---|
| 704 | + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_out); |
|---|
| 705 | + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_out); |
|---|
| 674 | 706 | } |
|---|
| 675 | 707 | |
|---|
| 676 | | - if (is_vid || is_vbi || is_sdr || is_tch) { |
|---|
| 677 | | - /* ioctls valid for video, metadata, vbi or sdr */ |
|---|
| 708 | + if (is_vid || is_vbi || is_sdr || is_tch || is_meta) { |
|---|
| 709 | + /* ioctls valid for video, vbi, sdr, touch and metadata */ |
|---|
| 678 | 710 | SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); |
|---|
| 679 | 711 | SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); |
|---|
| 680 | 712 | SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); |
|---|
| .. | .. |
|---|
| 686 | 718 | SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); |
|---|
| 687 | 719 | } |
|---|
| 688 | 720 | |
|---|
| 689 | | - if (is_vid || is_vbi || is_tch) { |
|---|
| 690 | | - /* ioctls valid for video or vbi */ |
|---|
| 721 | + if (is_vid || is_vbi || is_meta) { |
|---|
| 722 | + /* ioctls valid for video, vbi and metadata */ |
|---|
| 691 | 723 | if (ops->vidioc_s_std) |
|---|
| 692 | 724 | set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls); |
|---|
| 693 | 725 | SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); |
|---|
| 694 | 726 | SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std); |
|---|
| 695 | 727 | if (is_rx) { |
|---|
| 696 | 728 | SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd); |
|---|
| 697 | | - SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); |
|---|
| 698 | | - SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); |
|---|
| 699 | | - SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); |
|---|
| 729 | + if (is_io_mc) { |
|---|
| 730 | + set_bit(_IOC_NR(VIDIOC_ENUMINPUT), valid_ioctls); |
|---|
| 731 | + set_bit(_IOC_NR(VIDIOC_G_INPUT), valid_ioctls); |
|---|
| 732 | + set_bit(_IOC_NR(VIDIOC_S_INPUT), valid_ioctls); |
|---|
| 733 | + } else { |
|---|
| 734 | + SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); |
|---|
| 735 | + SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); |
|---|
| 736 | + SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); |
|---|
| 737 | + } |
|---|
| 700 | 738 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio); |
|---|
| 701 | 739 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio); |
|---|
| 702 | 740 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio); |
|---|
| .. | .. |
|---|
| 704 | 742 | SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid); |
|---|
| 705 | 743 | } |
|---|
| 706 | 744 | if (is_tx) { |
|---|
| 707 | | - SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); |
|---|
| 708 | | - SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); |
|---|
| 709 | | - SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); |
|---|
| 745 | + if (is_io_mc) { |
|---|
| 746 | + set_bit(_IOC_NR(VIDIOC_ENUMOUTPUT), valid_ioctls); |
|---|
| 747 | + set_bit(_IOC_NR(VIDIOC_G_OUTPUT), valid_ioctls); |
|---|
| 748 | + set_bit(_IOC_NR(VIDIOC_S_OUTPUT), valid_ioctls); |
|---|
| 749 | + } else { |
|---|
| 750 | + SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); |
|---|
| 751 | + SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); |
|---|
| 752 | + SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); |
|---|
| 753 | + } |
|---|
| 710 | 754 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout); |
|---|
| 711 | 755 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); |
|---|
| 712 | 756 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); |
|---|
| 713 | 757 | } |
|---|
| 714 | | - if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && |
|---|
| 715 | | - ops->vidioc_g_std)) |
|---|
| 758 | + if (ops->vidioc_g_parm || ops->vidioc_g_std) |
|---|
| 716 | 759 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); |
|---|
| 717 | 760 | SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); |
|---|
| 718 | 761 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); |
|---|
| .. | .. |
|---|
| 726 | 769 | SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator); |
|---|
| 727 | 770 | SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator); |
|---|
| 728 | 771 | } |
|---|
| 729 | | - if (is_rx) { |
|---|
| 772 | + if (is_rx && !is_tch) { |
|---|
| 730 | 773 | /* receiver only ioctls */ |
|---|
| 731 | 774 | SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); |
|---|
| 732 | 775 | SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); |
|---|
| .. | .. |
|---|
| 753 | 796 | vdev->entity.function = MEDIA_ENT_F_UNKNOWN; |
|---|
| 754 | 797 | |
|---|
| 755 | 798 | switch (vdev->vfl_type) { |
|---|
| 756 | | - case VFL_TYPE_GRABBER: |
|---|
| 799 | + case VFL_TYPE_VIDEO: |
|---|
| 757 | 800 | intf_type = MEDIA_INTF_T_V4L_VIDEO; |
|---|
| 758 | 801 | vdev->entity.function = MEDIA_ENT_F_IO_V4L; |
|---|
| 759 | 802 | break; |
|---|
| .. | .. |
|---|
| 851 | 894 | /* the v4l2_dev pointer MUST be present */ |
|---|
| 852 | 895 | if (WARN_ON(!vdev->v4l2_dev)) |
|---|
| 853 | 896 | return -EINVAL; |
|---|
| 897 | + /* the device_caps field MUST be set for all but subdevs */ |
|---|
| 898 | + if (WARN_ON(type != VFL_TYPE_SUBDEV && !vdev->device_caps)) |
|---|
| 899 | + return -EINVAL; |
|---|
| 854 | 900 | |
|---|
| 855 | 901 | /* v4l2_fh support */ |
|---|
| 856 | 902 | spin_lock_init(&vdev->fh_lock); |
|---|
| .. | .. |
|---|
| 858 | 904 | |
|---|
| 859 | 905 | /* Part 1: check device type */ |
|---|
| 860 | 906 | switch (type) { |
|---|
| 861 | | - case VFL_TYPE_GRABBER: |
|---|
| 907 | + case VFL_TYPE_VIDEO: |
|---|
| 862 | 908 | name_base = "video"; |
|---|
| 863 | 909 | break; |
|---|
| 864 | 910 | case VFL_TYPE_VBI: |
|---|
| .. | .. |
|---|
| 902 | 948 | * of 128-191 and just pick the first free minor there |
|---|
| 903 | 949 | * (new style). */ |
|---|
| 904 | 950 | switch (type) { |
|---|
| 905 | | - case VFL_TYPE_GRABBER: |
|---|
| 951 | + case VFL_TYPE_VIDEO: |
|---|
| 906 | 952 | minor_offset = 0; |
|---|
| 907 | 953 | minor_cnt = 64; |
|---|
| 908 | 954 | break; |
|---|
| .. | .. |
|---|
| 1078 | 1124 | unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); |
|---|
| 1079 | 1125 | } |
|---|
| 1080 | 1126 | |
|---|
| 1127 | +#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP |
|---|
| 1128 | +arch_initcall_sync(videodev_init); |
|---|
| 1129 | +#else |
|---|
| 1081 | 1130 | subsys_initcall(videodev_init); |
|---|
| 1131 | +#endif |
|---|
| 1082 | 1132 | module_exit(videodev_exit) |
|---|
| 1083 | 1133 | |
|---|
| 1084 | | -MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>"); |
|---|
| 1085 | | -MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); |
|---|
| 1134 | +MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>, Bill Dirks, Justin Schoeman, Gerd Knorr"); |
|---|
| 1135 | +MODULE_DESCRIPTION("Video4Linux2 core driver"); |
|---|
| 1086 | 1136 | MODULE_LICENSE("GPL"); |
|---|
| 1087 | 1137 | MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); |
|---|