.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for the Conexant CX23885 PCIe bridge |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | 6 | */ |
---|
17 | 7 | |
---|
18 | 8 | #include "cx23885.h" |
---|
.. | .. |
---|
77 | 67 | #define FORMAT_FLAGS_PACKED 0x01 |
---|
78 | 68 | static struct cx23885_fmt formats[] = { |
---|
79 | 69 | { |
---|
80 | | - .name = "4:2:2, packed, YUYV", |
---|
81 | 70 | .fourcc = V4L2_PIX_FMT_YUYV, |
---|
82 | 71 | .depth = 16, |
---|
83 | 72 | .flags = FORMAT_FLAGS_PACKED, |
---|
.. | .. |
---|
264 | 253 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || |
---|
265 | 254 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || |
---|
266 | 255 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || |
---|
| 256 | + (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) || |
---|
| 257 | + (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || |
---|
267 | 258 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || |
---|
| 259 | + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR5525) || |
---|
268 | 260 | (dev->board == CX23885_BOARD_MYGICA_X8507) || |
---|
269 | 261 | (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || |
---|
270 | 262 | (dev->board == CX23885_BOARD_VIEWCAST_260E) || |
---|
.. | .. |
---|
420 | 412 | dev->height >> 1); |
---|
421 | 413 | break; |
---|
422 | 414 | default: |
---|
423 | | - BUG(); |
---|
| 415 | + return -EINVAL; /* should not happen */ |
---|
424 | 416 | } |
---|
425 | | - dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", |
---|
| 417 | + dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", |
---|
426 | 418 | buf, buf->vb.vb2_buf.index, |
---|
427 | | - dev->width, dev->height, dev->fmt->depth, dev->fmt->name, |
---|
| 419 | + dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc, |
---|
428 | 420 | (unsigned long)buf->risc.dma); |
---|
429 | 421 | return 0; |
---|
430 | 422 | } |
---|
.. | .. |
---|
638 | 630 | struct v4l2_capability *cap) |
---|
639 | 631 | { |
---|
640 | 632 | struct cx23885_dev *dev = video_drvdata(file); |
---|
641 | | - struct video_device *vdev = video_devdata(file); |
---|
642 | 633 | |
---|
643 | | - strcpy(cap->driver, "cx23885"); |
---|
644 | | - strlcpy(cap->card, cx23885_boards[dev->board].name, |
---|
| 634 | + strscpy(cap->driver, "cx23885", sizeof(cap->driver)); |
---|
| 635 | + strscpy(cap->card, cx23885_boards[dev->board].name, |
---|
645 | 636 | sizeof(cap->card)); |
---|
646 | 637 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); |
---|
647 | | - cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO; |
---|
648 | | - if (dev->tuner_type != TUNER_ABSENT) |
---|
649 | | - cap->device_caps |= V4L2_CAP_TUNER; |
---|
650 | | - if (vdev->vfl_type == VFL_TYPE_VBI) |
---|
651 | | - cap->device_caps |= V4L2_CAP_VBI_CAPTURE; |
---|
652 | | - else |
---|
653 | | - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
---|
654 | | - cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE | |
---|
655 | | - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_DEVICE_CAPS; |
---|
| 638 | + cap->capabilities = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 639 | + V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE | |
---|
| 640 | + V4L2_CAP_VIDEO_CAPTURE | |
---|
| 641 | + V4L2_CAP_DEVICE_CAPS; |
---|
| 642 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 643 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 644 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 645 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 646 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 647 | + cap->capabilities |= V4L2_CAP_TUNER; |
---|
| 648 | + break; |
---|
| 649 | + default: |
---|
| 650 | + if (dev->tuner_type != TUNER_ABSENT) |
---|
| 651 | + cap->capabilities |= V4L2_CAP_TUNER; |
---|
| 652 | + break; |
---|
| 653 | + } |
---|
656 | 654 | return 0; |
---|
657 | 655 | } |
---|
658 | 656 | |
---|
.. | .. |
---|
662 | 660 | if (unlikely(f->index >= ARRAY_SIZE(formats))) |
---|
663 | 661 | return -EINVAL; |
---|
664 | 662 | |
---|
665 | | - strlcpy(f->description, formats[f->index].name, |
---|
666 | | - sizeof(f->description)); |
---|
667 | 663 | f->pixelformat = formats[f->index].fourcc; |
---|
668 | 664 | |
---|
669 | 665 | return 0; |
---|
670 | 666 | } |
---|
671 | 667 | |
---|
672 | | -static int vidioc_cropcap(struct file *file, void *priv, |
---|
673 | | - struct v4l2_cropcap *cc) |
---|
| 668 | +static int vidioc_g_pixelaspect(struct file *file, void *priv, |
---|
| 669 | + int type, struct v4l2_fract *f) |
---|
674 | 670 | { |
---|
675 | 671 | struct cx23885_dev *dev = video_drvdata(file); |
---|
676 | 672 | bool is_50hz = dev->tvnorm & V4L2_STD_625_50; |
---|
677 | 673 | |
---|
678 | | - if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
| 674 | + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
679 | 675 | return -EINVAL; |
---|
680 | 676 | |
---|
681 | | - cc->bounds.left = 0; |
---|
682 | | - cc->bounds.top = 0; |
---|
683 | | - cc->bounds.width = 720; |
---|
684 | | - cc->bounds.height = norm_maxh(dev->tvnorm); |
---|
685 | | - cc->defrect = cc->bounds; |
---|
686 | | - cc->pixelaspect.numerator = is_50hz ? 54 : 11; |
---|
687 | | - cc->pixelaspect.denominator = is_50hz ? 59 : 10; |
---|
| 677 | + f->numerator = is_50hz ? 54 : 11; |
---|
| 678 | + f->denominator = is_50hz ? 59 : 10; |
---|
688 | 679 | |
---|
| 680 | + return 0; |
---|
| 681 | +} |
---|
| 682 | + |
---|
| 683 | +static int vidioc_g_selection(struct file *file, void *fh, |
---|
| 684 | + struct v4l2_selection *sel) |
---|
| 685 | +{ |
---|
| 686 | + struct cx23885_dev *dev = video_drvdata(file); |
---|
| 687 | + |
---|
| 688 | + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
| 689 | + return -EINVAL; |
---|
| 690 | + |
---|
| 691 | + switch (sel->target) { |
---|
| 692 | + case V4L2_SEL_TGT_CROP_BOUNDS: |
---|
| 693 | + case V4L2_SEL_TGT_CROP_DEFAULT: |
---|
| 694 | + sel->r.top = 0; |
---|
| 695 | + sel->r.left = 0; |
---|
| 696 | + sel->r.width = 720; |
---|
| 697 | + sel->r.height = norm_maxh(dev->tvnorm); |
---|
| 698 | + break; |
---|
| 699 | + default: |
---|
| 700 | + return -EINVAL; |
---|
| 701 | + } |
---|
689 | 702 | return 0; |
---|
690 | 703 | } |
---|
691 | 704 | |
---|
.. | .. |
---|
732 | 745 | |
---|
733 | 746 | i->index = n; |
---|
734 | 747 | i->type = V4L2_INPUT_TYPE_CAMERA; |
---|
735 | | - strcpy(i->name, iname[INPUT(n)->type]); |
---|
| 748 | + strscpy(i->name, iname[INPUT(n)->type], sizeof(i->name)); |
---|
736 | 749 | i->std = CX23885_NORMS; |
---|
737 | 750 | if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || |
---|
738 | 751 | (CX23885_VMUX_CABLE == INPUT(n)->type)) { |
---|
.. | .. |
---|
829 | 842 | |
---|
830 | 843 | memset(i, 0, sizeof(*i)); |
---|
831 | 844 | i->index = n; |
---|
832 | | - strcpy(i->name, iname[n]); |
---|
| 845 | + strscpy(i->name, iname[n], sizeof(i->name)); |
---|
833 | 846 | i->capability = V4L2_AUDCAP_STEREO; |
---|
834 | 847 | return 0; |
---|
835 | 848 | |
---|
.. | .. |
---|
883 | 896 | { |
---|
884 | 897 | struct cx23885_dev *dev = video_drvdata(file); |
---|
885 | 898 | |
---|
886 | | - if (dev->tuner_type == TUNER_ABSENT) |
---|
887 | | - return -EINVAL; |
---|
| 899 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 900 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 901 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 902 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 903 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 904 | + break; |
---|
| 905 | + default: |
---|
| 906 | + if (dev->tuner_type == TUNER_ABSENT) |
---|
| 907 | + return -EINVAL; |
---|
| 908 | + break; |
---|
| 909 | + } |
---|
888 | 910 | if (0 != t->index) |
---|
889 | 911 | return -EINVAL; |
---|
890 | 912 | |
---|
891 | | - strcpy(t->name, "Television"); |
---|
| 913 | + strscpy(t->name, "Television", sizeof(t->name)); |
---|
892 | 914 | |
---|
893 | 915 | call_all(dev, tuner, g_tuner, t); |
---|
894 | 916 | return 0; |
---|
.. | .. |
---|
899 | 921 | { |
---|
900 | 922 | struct cx23885_dev *dev = video_drvdata(file); |
---|
901 | 923 | |
---|
902 | | - if (dev->tuner_type == TUNER_ABSENT) |
---|
903 | | - return -EINVAL; |
---|
| 924 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 925 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 926 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 927 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 928 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 929 | + break; |
---|
| 930 | + default: |
---|
| 931 | + if (dev->tuner_type == TUNER_ABSENT) |
---|
| 932 | + return -EINVAL; |
---|
| 933 | + break; |
---|
| 934 | + } |
---|
904 | 935 | if (0 != t->index) |
---|
905 | 936 | return -EINVAL; |
---|
906 | 937 | /* Update the A/V core */ |
---|
.. | .. |
---|
914 | 945 | { |
---|
915 | 946 | struct cx23885_dev *dev = video_drvdata(file); |
---|
916 | 947 | |
---|
917 | | - if (dev->tuner_type == TUNER_ABSENT) |
---|
918 | | - return -EINVAL; |
---|
919 | | - |
---|
| 948 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 949 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 950 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 951 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 952 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 953 | + break; |
---|
| 954 | + default: |
---|
| 955 | + if (dev->tuner_type == TUNER_ABSENT) |
---|
| 956 | + return -EINVAL; |
---|
| 957 | + break; |
---|
| 958 | + } |
---|
920 | 959 | f->type = V4L2_TUNER_ANALOG_TV; |
---|
921 | 960 | f->frequency = dev->freq; |
---|
922 | 961 | |
---|
.. | .. |
---|
930 | 969 | struct v4l2_ctrl *mute; |
---|
931 | 970 | int old_mute_val = 1; |
---|
932 | 971 | |
---|
933 | | - if (dev->tuner_type == TUNER_ABSENT) |
---|
934 | | - return -EINVAL; |
---|
| 972 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 973 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 974 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 975 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 976 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 977 | + break; |
---|
| 978 | + default: |
---|
| 979 | + if (dev->tuner_type == TUNER_ABSENT) |
---|
| 980 | + return -EINVAL; |
---|
| 981 | + break; |
---|
| 982 | + } |
---|
935 | 983 | if (unlikely(f->tuner != 0)) |
---|
936 | 984 | return -EINVAL; |
---|
937 | 985 | |
---|
.. | .. |
---|
996 | 1044 | if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || |
---|
997 | 1045 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || |
---|
998 | 1046 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || |
---|
999 | | - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4)) |
---|
| 1047 | + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || |
---|
| 1048 | + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR5525) || |
---|
| 1049 | + (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || |
---|
| 1050 | + (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC)) |
---|
1000 | 1051 | fe = &dev->ts1.analog_fe; |
---|
1001 | 1052 | |
---|
1002 | 1053 | if (fe && fe->ops.tuner_ops.set_analog_params) { |
---|
.. | .. |
---|
1027 | 1078 | case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: |
---|
1028 | 1079 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
1029 | 1080 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
---|
| 1081 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 1082 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 1083 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
1030 | 1084 | ret = cx23885_set_freq_via_ops(dev, f); |
---|
1031 | 1085 | break; |
---|
1032 | 1086 | default: |
---|
.. | .. |
---|
1123 | 1177 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
---|
1124 | 1178 | .vidioc_streamon = vb2_ioctl_streamon, |
---|
1125 | 1179 | .vidioc_streamoff = vb2_ioctl_streamoff, |
---|
1126 | | - .vidioc_cropcap = vidioc_cropcap, |
---|
| 1180 | + .vidioc_g_pixelaspect = vidioc_g_pixelaspect, |
---|
| 1181 | + .vidioc_g_selection = vidioc_g_selection, |
---|
1127 | 1182 | .vidioc_s_std = vidioc_s_std, |
---|
1128 | 1183 | .vidioc_g_std = vidioc_g_std, |
---|
1129 | 1184 | .vidioc_enum_input = vidioc_enum_input, |
---|
.. | .. |
---|
1187 | 1242 | |
---|
1188 | 1243 | /* Initialize VBI template */ |
---|
1189 | 1244 | cx23885_vbi_template = cx23885_video_template; |
---|
1190 | | - strcpy(cx23885_vbi_template.name, "cx23885-vbi"); |
---|
| 1245 | + strscpy(cx23885_vbi_template.name, "cx23885-vbi", |
---|
| 1246 | + sizeof(cx23885_vbi_template.name)); |
---|
1191 | 1247 | |
---|
1192 | 1248 | dev->tvnorm = V4L2_STD_NTSC_M; |
---|
1193 | 1249 | dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV); |
---|
.. | .. |
---|
1298 | 1354 | dev->video_dev = cx23885_vdev_init(dev, dev->pci, |
---|
1299 | 1355 | &cx23885_video_template, "video"); |
---|
1300 | 1356 | dev->video_dev->queue = &dev->vb2_vidq; |
---|
1301 | | - err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, |
---|
| 1357 | + dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 1358 | + V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE; |
---|
| 1359 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 1360 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 1361 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 1362 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 1363 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 1364 | + dev->video_dev->device_caps |= V4L2_CAP_TUNER; |
---|
| 1365 | + break; |
---|
| 1366 | + default: |
---|
| 1367 | + if (dev->tuner_type != TUNER_ABSENT) |
---|
| 1368 | + dev->video_dev->device_caps |= V4L2_CAP_TUNER; |
---|
| 1369 | + } |
---|
| 1370 | + |
---|
| 1371 | + err = video_register_device(dev->video_dev, VFL_TYPE_VIDEO, |
---|
1302 | 1372 | video_nr[dev->nr]); |
---|
1303 | 1373 | if (err < 0) { |
---|
1304 | 1374 | pr_info("%s: can't register video device\n", |
---|
.. | .. |
---|
1312 | 1382 | dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, |
---|
1313 | 1383 | &cx23885_vbi_template, "vbi"); |
---|
1314 | 1384 | dev->vbi_dev->queue = &dev->vb2_vbiq; |
---|
| 1385 | + dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 1386 | + V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE; |
---|
| 1387 | + switch (dev->board) { /* i2c device tuners */ |
---|
| 1388 | + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: |
---|
| 1389 | + case CX23885_BOARD_HAUPPAUGE_HVR5525: |
---|
| 1390 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
---|
| 1391 | + case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
---|
| 1392 | + dev->vbi_dev->device_caps |= V4L2_CAP_TUNER; |
---|
| 1393 | + break; |
---|
| 1394 | + default: |
---|
| 1395 | + if (dev->tuner_type != TUNER_ABSENT) |
---|
| 1396 | + dev->vbi_dev->device_caps |= V4L2_CAP_TUNER; |
---|
| 1397 | + } |
---|
1315 | 1398 | err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, |
---|
1316 | 1399 | vbi_nr[dev->nr]); |
---|
1317 | 1400 | if (err < 0) { |
---|