hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/platform/qcom/camss/camss-video.c
....@@ -18,6 +18,12 @@
1818 #include "camss-video.h"
1919 #include "camss.h"
2020
21
+#define CAMSS_FRAME_MIN_WIDTH 1
22
+#define CAMSS_FRAME_MAX_WIDTH 8191
23
+#define CAMSS_FRAME_MIN_HEIGHT 1
24
+#define CAMSS_FRAME_MAX_HEIGHT_RDI 8191
25
+#define CAMSS_FRAME_MAX_HEIGHT_PIX 4096
26
+
2127 struct fract {
2228 u8 numerator;
2329 u8 denominator;
....@@ -521,24 +527,23 @@
521527 {
522528 struct camss_video *video = video_drvdata(file);
523529
524
- strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver));
525
- strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
530
+ strscpy(cap->driver, "qcom-camss", sizeof(cap->driver));
531
+ strscpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
526532 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
527533 dev_name(video->camss->dev));
528534
529535 return 0;
530536 }
531537
532
-static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
538
+/*
539
+ * Returns the index in the video->formats[] array of the element which
540
+ * has the "ndx"th unique value of pixelformat field.
541
+ * If not found (no more unique pixelformat's) returns -EINVAL.
542
+ */
543
+static int video_get_unique_pixelformat_by_index(struct camss_video *video,
544
+ int ndx)
533545 {
534
- struct camss_video *video = video_drvdata(file);
535546 int i, j, k;
536
-
537
- if (f->type != video->type)
538
- return -EINVAL;
539
-
540
- if (f->index >= video->nformats)
541
- return -EINVAL;
542547
543548 /* find index "i" of "k"th unique pixelformat in formats array */
544549 k = -1;
....@@ -552,14 +557,86 @@
552557 if (j == i)
553558 k++;
554559
555
- if (k == f->index)
556
- break;
560
+ if (k == ndx)
561
+ return i;
557562 }
558563
559
- if (k < f->index)
564
+ return -EINVAL;
565
+}
566
+
567
+/*
568
+ * Returns the index in the video->formats[] array of the element which
569
+ * has code equal to mcode.
570
+ * If not found returns -EINVAL.
571
+ */
572
+static int video_get_pixelformat_by_mbus_code(struct camss_video *video,
573
+ u32 mcode)
574
+{
575
+ int i;
576
+
577
+ for (i = 0; i < video->nformats; i++) {
578
+ if (video->formats[i].code == mcode)
579
+ return i;
580
+ }
581
+
582
+ return -EINVAL;
583
+}
584
+
585
+static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
586
+{
587
+ struct camss_video *video = video_drvdata(file);
588
+ int i;
589
+
590
+ if (f->type != video->type)
591
+ return -EINVAL;
592
+
593
+ if (f->index >= video->nformats)
594
+ return -EINVAL;
595
+
596
+ if (f->mbus_code) {
597
+ /* Each entry in formats[] table has unique mbus_code */
598
+ if (f->index > 0)
599
+ return -EINVAL;
600
+
601
+ i = video_get_pixelformat_by_mbus_code(video, f->mbus_code);
602
+ } else {
603
+ i = video_get_unique_pixelformat_by_index(video, f->index);
604
+ }
605
+
606
+ if (i < 0)
560607 return -EINVAL;
561608
562609 f->pixelformat = video->formats[i].pixelformat;
610
+
611
+ return 0;
612
+}
613
+
614
+static int video_enum_framesizes(struct file *file, void *fh,
615
+ struct v4l2_frmsizeenum *fsize)
616
+{
617
+ struct camss_video *video = video_drvdata(file);
618
+ int i;
619
+
620
+ if (fsize->index)
621
+ return -EINVAL;
622
+
623
+ /* Only accept pixel format present in the formats[] table */
624
+ for (i = 0; i < video->nformats; i++) {
625
+ if (video->formats[i].pixelformat == fsize->pixel_format)
626
+ break;
627
+ }
628
+
629
+ if (i == video->nformats)
630
+ return -EINVAL;
631
+
632
+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
633
+ fsize->stepwise.min_width = CAMSS_FRAME_MIN_WIDTH;
634
+ fsize->stepwise.max_width = CAMSS_FRAME_MAX_WIDTH;
635
+ fsize->stepwise.min_height = CAMSS_FRAME_MIN_HEIGHT;
636
+ fsize->stepwise.max_height = (video->line_based) ?
637
+ CAMSS_FRAME_MAX_HEIGHT_PIX : CAMSS_FRAME_MAX_HEIGHT_RDI;
638
+ fsize->stepwise.step_width = 1;
639
+ fsize->stepwise.step_height = 1;
563640
564641 return 0;
565642 }
....@@ -593,7 +670,7 @@
593670 1, 65528);
594671 sizeimage[i] = clamp_t(u32, p->sizeimage,
595672 bytesperline[i],
596
- bytesperline[i] * 4096);
673
+ bytesperline[i] * CAMSS_FRAME_MAX_HEIGHT_PIX);
597674 }
598675
599676 for (j = 0; j < video->nformats; j++)
....@@ -610,8 +687,8 @@
610687 memset(pix_mp, 0, sizeof(*pix_mp));
611688
612689 pix_mp->pixelformat = fi->pixelformat;
613
- pix_mp->width = clamp_t(u32, width, 1, 8191);
614
- pix_mp->height = clamp_t(u32, height, 1, 8191);
690
+ pix_mp->width = clamp_t(u32, width, 1, CAMSS_FRAME_MAX_WIDTH);
691
+ pix_mp->height = clamp_t(u32, height, 1, CAMSS_FRAME_MAX_HEIGHT_RDI);
615692 pix_mp->num_planes = fi->planes;
616693 for (i = 0; i < pix_mp->num_planes; i++) {
617694 bpl = pix_mp->width / fi->hsub[i].numerator *
....@@ -637,7 +714,7 @@
637714 1, 65528);
638715 p->sizeimage = clamp_t(u32, p->sizeimage,
639716 p->bytesperline,
640
- p->bytesperline * 4096);
717
+ p->bytesperline * CAMSS_FRAME_MAX_HEIGHT_PIX);
641718 lines = p->sizeimage / p->bytesperline;
642719
643720 if (p->bytesperline < bytesperline[i])
....@@ -683,7 +760,7 @@
683760 if (input->index > 0)
684761 return -EINVAL;
685762
686
- strlcpy(input->name, "camera", sizeof(input->name));
763
+ strscpy(input->name, "camera", sizeof(input->name));
687764 input->type = V4L2_INPUT_TYPE_CAMERA;
688765
689766 return 0;
....@@ -703,7 +780,8 @@
703780
704781 static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = {
705782 .vidioc_querycap = video_querycap,
706
- .vidioc_enum_fmt_vid_cap_mplane = video_enum_fmt,
783
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
784
+ .vidioc_enum_framesizes = video_enum_framesizes,
707785 .vidioc_g_fmt_vid_cap_mplane = video_g_fmt,
708786 .vidioc_s_fmt_vid_cap_mplane = video_s_fmt,
709787 .vidioc_try_fmt_vid_cap_mplane = video_try_fmt,
....@@ -745,7 +823,7 @@
745823
746824 file->private_data = vfh;
747825
748
- ret = v4l2_pipeline_pm_use(&vdev->entity, 1);
826
+ ret = v4l2_pipeline_pm_get(&vdev->entity);
749827 if (ret < 0) {
750828 dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
751829 ret);
....@@ -771,7 +849,7 @@
771849
772850 vb2_fop_release(file);
773851
774
- v4l2_pipeline_pm_use(&vdev->entity, 0);
852
+ v4l2_pipeline_pm_put(&vdev->entity);
775853
776854 file->private_data = NULL;
777855
....@@ -879,7 +957,7 @@
879957 if (ret < 0) {
880958 dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n",
881959 ret);
882
- goto error_media_init;
960
+ goto error_vb2_init;
883961 }
884962
885963 mutex_init(&video->lock);
....@@ -912,17 +990,17 @@
912990 }
913991
914992 vdev->fops = &msm_vid_fops;
915
- vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
916
- V4L2_CAP_READWRITE;
993
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING
994
+ | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC;
917995 vdev->ioctl_ops = &msm_vid_ioctl_ops;
918996 vdev->release = msm_video_release;
919997 vdev->v4l2_dev = v4l2_dev;
920998 vdev->vfl_dir = VFL_DIR_RX;
921999 vdev->queue = &video->vb2_q;
9221000 vdev->lock = &video->lock;
923
- strlcpy(vdev->name, name, sizeof(vdev->name));
1001
+ strscpy(vdev->name, name, sizeof(vdev->name));
9241002
925
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1003
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
9261004 if (ret < 0) {
9271005 dev_err(v4l2_dev->dev, "Failed to register video device: %d\n",
9281006 ret);
....@@ -937,23 +1015,15 @@
9371015 error_video_register:
9381016 media_entity_cleanup(&vdev->entity);
9391017 mutex_destroy(&video->lock);
940
-error_media_init:
941
- vb2_queue_release(&video->vb2_q);
9421018 error_vb2_init:
9431019 mutex_destroy(&video->q_lock);
9441020
9451021 return ret;
9461022 }
9471023
948
-void msm_video_stop_streaming(struct camss_video *video)
949
-{
950
- if (vb2_is_streaming(&video->vb2_q))
951
- vb2_queue_release(&video->vb2_q);
952
-}
953
-
9541024 void msm_video_unregister(struct camss_video *video)
9551025 {
9561026 atomic_inc(&video->camss->ref_count);
957
- video_unregister_device(&video->vdev);
1027
+ vb2_video_unregister_device(&video->vdev);
9581028 atomic_dec(&video->camss->ref_count);
9591029 }