hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/pci/cx23885/cx23885-video.c
....@@ -1,18 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Driver for the Conexant CX23885 PCIe bridge
34 *
45 * 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.
166 */
177
188 #include "cx23885.h"
....@@ -77,7 +67,6 @@
7767 #define FORMAT_FLAGS_PACKED 0x01
7868 static struct cx23885_fmt formats[] = {
7969 {
80
- .name = "4:2:2, packed, YUYV",
8170 .fourcc = V4L2_PIX_FMT_YUYV,
8271 .depth = 16,
8372 .flags = FORMAT_FLAGS_PACKED,
....@@ -264,7 +253,10 @@
264253 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
265254 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
266255 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) ||
256
+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) ||
257
+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) ||
267258 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
259
+ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR5525) ||
268260 (dev->board == CX23885_BOARD_MYGICA_X8507) ||
269261 (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
270262 (dev->board == CX23885_BOARD_VIEWCAST_260E) ||
....@@ -420,11 +412,11 @@
420412 dev->height >> 1);
421413 break;
422414 default:
423
- BUG();
415
+ return -EINVAL; /* should not happen */
424416 }
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",
426418 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,
428420 (unsigned long)buf->risc.dma);
429421 return 0;
430422 }
....@@ -638,21 +630,27 @@
638630 struct v4l2_capability *cap)
639631 {
640632 struct cx23885_dev *dev = video_drvdata(file);
641
- struct video_device *vdev = video_devdata(file);
642633
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,
645636 sizeof(cap->card));
646637 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
+ }
656654 return 0;
657655 }
658656
....@@ -662,30 +660,45 @@
662660 if (unlikely(f->index >= ARRAY_SIZE(formats)))
663661 return -EINVAL;
664662
665
- strlcpy(f->description, formats[f->index].name,
666
- sizeof(f->description));
667663 f->pixelformat = formats[f->index].fourcc;
668664
669665 return 0;
670666 }
671667
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)
674670 {
675671 struct cx23885_dev *dev = video_drvdata(file);
676672 bool is_50hz = dev->tvnorm & V4L2_STD_625_50;
677673
678
- if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
674
+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
679675 return -EINVAL;
680676
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;
688679
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
+ }
689702 return 0;
690703 }
691704
....@@ -732,7 +745,7 @@
732745
733746 i->index = n;
734747 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));
736749 i->std = CX23885_NORMS;
737750 if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
738751 (CX23885_VMUX_CABLE == INPUT(n)->type)) {
....@@ -829,7 +842,7 @@
829842
830843 memset(i, 0, sizeof(*i));
831844 i->index = n;
832
- strcpy(i->name, iname[n]);
845
+ strscpy(i->name, iname[n], sizeof(i->name));
833846 i->capability = V4L2_AUDCAP_STEREO;
834847 return 0;
835848
....@@ -883,12 +896,21 @@
883896 {
884897 struct cx23885_dev *dev = video_drvdata(file);
885898
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
+ }
888910 if (0 != t->index)
889911 return -EINVAL;
890912
891
- strcpy(t->name, "Television");
913
+ strscpy(t->name, "Television", sizeof(t->name));
892914
893915 call_all(dev, tuner, g_tuner, t);
894916 return 0;
....@@ -899,8 +921,17 @@
899921 {
900922 struct cx23885_dev *dev = video_drvdata(file);
901923
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
+ }
904935 if (0 != t->index)
905936 return -EINVAL;
906937 /* Update the A/V core */
....@@ -914,9 +945,17 @@
914945 {
915946 struct cx23885_dev *dev = video_drvdata(file);
916947
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
+ }
920959 f->type = V4L2_TUNER_ANALOG_TV;
921960 f->frequency = dev->freq;
922961
....@@ -930,8 +969,17 @@
930969 struct v4l2_ctrl *mute;
931970 int old_mute_val = 1;
932971
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
+ }
935983 if (unlikely(f->tuner != 0))
936984 return -EINVAL;
937985
....@@ -996,7 +1044,10 @@
9961044 if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
9971045 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
9981046 (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))
10001051 fe = &dev->ts1.analog_fe;
10011052
10021053 if (fe && fe->ops.tuner_ops.set_analog_params) {
....@@ -1027,6 +1078,9 @@
10271078 case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
10281079 case CX23885_BOARD_HAUPPAUGE_HVR1265_K4:
10291080 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:
10301084 ret = cx23885_set_freq_via_ops(dev, f);
10311085 break;
10321086 default:
....@@ -1123,7 +1177,8 @@
11231177 .vidioc_dqbuf = vb2_ioctl_dqbuf,
11241178 .vidioc_streamon = vb2_ioctl_streamon,
11251179 .vidioc_streamoff = vb2_ioctl_streamoff,
1126
- .vidioc_cropcap = vidioc_cropcap,
1180
+ .vidioc_g_pixelaspect = vidioc_g_pixelaspect,
1181
+ .vidioc_g_selection = vidioc_g_selection,
11271182 .vidioc_s_std = vidioc_s_std,
11281183 .vidioc_g_std = vidioc_g_std,
11291184 .vidioc_enum_input = vidioc_enum_input,
....@@ -1187,7 +1242,8 @@
11871242
11881243 /* Initialize VBI template */
11891244 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));
11911247
11921248 dev->tvnorm = V4L2_STD_NTSC_M;
11931249 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
....@@ -1298,7 +1354,21 @@
12981354 dev->video_dev = cx23885_vdev_init(dev, dev->pci,
12991355 &cx23885_video_template, "video");
13001356 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,
13021372 video_nr[dev->nr]);
13031373 if (err < 0) {
13041374 pr_info("%s: can't register video device\n",
....@@ -1312,6 +1382,19 @@
13121382 dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
13131383 &cx23885_vbi_template, "vbi");
13141384 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
+ }
13151398 err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
13161399 vbi_nr[dev->nr]);
13171400 if (err < 0) {