hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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;
....@@ -438,7 +444,7 @@
438444
439445 ret = media_pipeline_start(&vdev->entity, &video->pipe);
440446 if (ret < 0)
441
- return ret;
447
+ goto flush_buffers;
442448
443449 ret = video_check_format(video);
444450 if (ret < 0)
....@@ -467,6 +473,7 @@
467473 error:
468474 media_pipeline_stop(&vdev->entity);
469475
476
+flush_buffers:
470477 video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
471478
472479 return ret;
....@@ -521,24 +528,23 @@
521528 {
522529 struct camss_video *video = video_drvdata(file);
523530
524
- strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver));
525
- strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
531
+ strscpy(cap->driver, "qcom-camss", sizeof(cap->driver));
532
+ strscpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
526533 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
527534 dev_name(video->camss->dev));
528535
529536 return 0;
530537 }
531538
532
-static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
539
+/*
540
+ * Returns the index in the video->formats[] array of the element which
541
+ * has the "ndx"th unique value of pixelformat field.
542
+ * If not found (no more unique pixelformat's) returns -EINVAL.
543
+ */
544
+static int video_get_unique_pixelformat_by_index(struct camss_video *video,
545
+ int ndx)
533546 {
534
- struct camss_video *video = video_drvdata(file);
535547 int i, j, k;
536
-
537
- if (f->type != video->type)
538
- return -EINVAL;
539
-
540
- if (f->index >= video->nformats)
541
- return -EINVAL;
542548
543549 /* find index "i" of "k"th unique pixelformat in formats array */
544550 k = -1;
....@@ -552,14 +558,86 @@
552558 if (j == i)
553559 k++;
554560
555
- if (k == f->index)
556
- break;
561
+ if (k == ndx)
562
+ return i;
557563 }
558564
559
- if (k < f->index)
565
+ return -EINVAL;
566
+}
567
+
568
+/*
569
+ * Returns the index in the video->formats[] array of the element which
570
+ * has code equal to mcode.
571
+ * If not found returns -EINVAL.
572
+ */
573
+static int video_get_pixelformat_by_mbus_code(struct camss_video *video,
574
+ u32 mcode)
575
+{
576
+ int i;
577
+
578
+ for (i = 0; i < video->nformats; i++) {
579
+ if (video->formats[i].code == mcode)
580
+ return i;
581
+ }
582
+
583
+ return -EINVAL;
584
+}
585
+
586
+static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
587
+{
588
+ struct camss_video *video = video_drvdata(file);
589
+ int i;
590
+
591
+ if (f->type != video->type)
592
+ return -EINVAL;
593
+
594
+ if (f->index >= video->nformats)
595
+ return -EINVAL;
596
+
597
+ if (f->mbus_code) {
598
+ /* Each entry in formats[] table has unique mbus_code */
599
+ if (f->index > 0)
600
+ return -EINVAL;
601
+
602
+ i = video_get_pixelformat_by_mbus_code(video, f->mbus_code);
603
+ } else {
604
+ i = video_get_unique_pixelformat_by_index(video, f->index);
605
+ }
606
+
607
+ if (i < 0)
560608 return -EINVAL;
561609
562610 f->pixelformat = video->formats[i].pixelformat;
611
+
612
+ return 0;
613
+}
614
+
615
+static int video_enum_framesizes(struct file *file, void *fh,
616
+ struct v4l2_frmsizeenum *fsize)
617
+{
618
+ struct camss_video *video = video_drvdata(file);
619
+ int i;
620
+
621
+ if (fsize->index)
622
+ return -EINVAL;
623
+
624
+ /* Only accept pixel format present in the formats[] table */
625
+ for (i = 0; i < video->nformats; i++) {
626
+ if (video->formats[i].pixelformat == fsize->pixel_format)
627
+ break;
628
+ }
629
+
630
+ if (i == video->nformats)
631
+ return -EINVAL;
632
+
633
+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
634
+ fsize->stepwise.min_width = CAMSS_FRAME_MIN_WIDTH;
635
+ fsize->stepwise.max_width = CAMSS_FRAME_MAX_WIDTH;
636
+ fsize->stepwise.min_height = CAMSS_FRAME_MIN_HEIGHT;
637
+ fsize->stepwise.max_height = (video->line_based) ?
638
+ CAMSS_FRAME_MAX_HEIGHT_PIX : CAMSS_FRAME_MAX_HEIGHT_RDI;
639
+ fsize->stepwise.step_width = 1;
640
+ fsize->stepwise.step_height = 1;
563641
564642 return 0;
565643 }
....@@ -593,7 +671,7 @@
593671 1, 65528);
594672 sizeimage[i] = clamp_t(u32, p->sizeimage,
595673 bytesperline[i],
596
- bytesperline[i] * 4096);
674
+ bytesperline[i] * CAMSS_FRAME_MAX_HEIGHT_PIX);
597675 }
598676
599677 for (j = 0; j < video->nformats; j++)
....@@ -610,8 +688,8 @@
610688 memset(pix_mp, 0, sizeof(*pix_mp));
611689
612690 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);
691
+ pix_mp->width = clamp_t(u32, width, 1, CAMSS_FRAME_MAX_WIDTH);
692
+ pix_mp->height = clamp_t(u32, height, 1, CAMSS_FRAME_MAX_HEIGHT_RDI);
615693 pix_mp->num_planes = fi->planes;
616694 for (i = 0; i < pix_mp->num_planes; i++) {
617695 bpl = pix_mp->width / fi->hsub[i].numerator *
....@@ -637,7 +715,7 @@
637715 1, 65528);
638716 p->sizeimage = clamp_t(u32, p->sizeimage,
639717 p->bytesperline,
640
- p->bytesperline * 4096);
718
+ p->bytesperline * CAMSS_FRAME_MAX_HEIGHT_PIX);
641719 lines = p->sizeimage / p->bytesperline;
642720
643721 if (p->bytesperline < bytesperline[i])
....@@ -683,7 +761,7 @@
683761 if (input->index > 0)
684762 return -EINVAL;
685763
686
- strlcpy(input->name, "camera", sizeof(input->name));
764
+ strscpy(input->name, "camera", sizeof(input->name));
687765 input->type = V4L2_INPUT_TYPE_CAMERA;
688766
689767 return 0;
....@@ -703,7 +781,8 @@
703781
704782 static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = {
705783 .vidioc_querycap = video_querycap,
706
- .vidioc_enum_fmt_vid_cap_mplane = video_enum_fmt,
784
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
785
+ .vidioc_enum_framesizes = video_enum_framesizes,
707786 .vidioc_g_fmt_vid_cap_mplane = video_g_fmt,
708787 .vidioc_s_fmt_vid_cap_mplane = video_s_fmt,
709788 .vidioc_try_fmt_vid_cap_mplane = video_try_fmt,
....@@ -745,7 +824,7 @@
745824
746825 file->private_data = vfh;
747826
748
- ret = v4l2_pipeline_pm_use(&vdev->entity, 1);
827
+ ret = v4l2_pipeline_pm_get(&vdev->entity);
749828 if (ret < 0) {
750829 dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
751830 ret);
....@@ -771,7 +850,7 @@
771850
772851 vb2_fop_release(file);
773852
774
- v4l2_pipeline_pm_use(&vdev->entity, 0);
853
+ v4l2_pipeline_pm_put(&vdev->entity);
775854
776855 file->private_data = NULL;
777856
....@@ -879,7 +958,7 @@
879958 if (ret < 0) {
880959 dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n",
881960 ret);
882
- goto error_media_init;
961
+ goto error_vb2_init;
883962 }
884963
885964 mutex_init(&video->lock);
....@@ -912,17 +991,17 @@
912991 }
913992
914993 vdev->fops = &msm_vid_fops;
915
- vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
916
- V4L2_CAP_READWRITE;
994
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING
995
+ | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC;
917996 vdev->ioctl_ops = &msm_vid_ioctl_ops;
918997 vdev->release = msm_video_release;
919998 vdev->v4l2_dev = v4l2_dev;
920999 vdev->vfl_dir = VFL_DIR_RX;
9211000 vdev->queue = &video->vb2_q;
9221001 vdev->lock = &video->lock;
923
- strlcpy(vdev->name, name, sizeof(vdev->name));
1002
+ strscpy(vdev->name, name, sizeof(vdev->name));
9241003
925
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1004
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
9261005 if (ret < 0) {
9271006 dev_err(v4l2_dev->dev, "Failed to register video device: %d\n",
9281007 ret);
....@@ -937,23 +1016,15 @@
9371016 error_video_register:
9381017 media_entity_cleanup(&vdev->entity);
9391018 mutex_destroy(&video->lock);
940
-error_media_init:
941
- vb2_queue_release(&video->vb2_q);
9421019 error_vb2_init:
9431020 mutex_destroy(&video->q_lock);
9441021
9451022 return ret;
9461023 }
9471024
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
-
9541025 void msm_video_unregister(struct camss_video *video)
9551026 {
9561027 atomic_inc(&video->camss->ref_count);
957
- video_unregister_device(&video->vdev);
1028
+ vb2_video_unregister_device(&video->vdev);
9581029 atomic_dec(&video->camss->ref_count);
9591030 }