11// SPDX-License-Identifier: GPL-2.0-only
22/* Copyright 2023 Eileen Yoon <eyn@gmx.com> */
33
4+ #include <linux/module.h>
5+
46#include <media/media-device.h>
57#include <media/v4l2-common.h>
68#include <media/v4l2-ioctl.h>
1921#define ISP_BUFFER_TIMEOUT msecs_to_jiffies(1500)
2022#define ISP_STRIDE_ALIGNMENT 64
2123
24+ static bool multiplanar = false;
25+ module_param (multiplanar , bool , 0644 );
26+ MODULE_PARM_DESC (multiplanar , "Enable multiplanar API" );
27+
2228struct isp_h2t_buffer {
2329 u64 iovas [ISP_MAX_PLANES ];
2430 u32 flags [ISP_MAX_PLANES ];
@@ -360,13 +366,23 @@ static int isp_vidioc_querycap(struct file *file, void *priv,
360366static int isp_vidioc_enum_format (struct file * file , void * fh ,
361367 struct v4l2_fmtdesc * f )
362368{
369+ struct apple_isp * isp = video_drvdata (file );
370+
363371 if (f -> index >= ISP_MAX_PIX_FORMATS )
364372 return - EINVAL ;
365373
366- if (!f -> index )
374+ switch (f -> index ) {
375+ case 0 :
367376 f -> pixelformat = V4L2_PIX_FMT_NV12 ;
368- else
377+ break ;
378+ case 1 :
379+ if (!isp -> multiplanar )
380+ return - EINVAL ;
369381 f -> pixelformat = V4L2_PIX_FMT_NV12M ;
382+ break ;
383+ default :
384+ return - EINVAL ;
385+ }
370386
371387 return 0 ;
372388}
@@ -379,7 +395,7 @@ static int isp_vidioc_enum_framesizes(struct file *file, void *fh,
379395 if (f -> index >= isp -> num_presets )
380396 return - EINVAL ;
381397
382- if ((f -> pixel_format != V4L2_PIX_FMT_NV12 ) ||
398+ if ((f -> pixel_format != V4L2_PIX_FMT_NV12 ) &&
383399 (f -> pixel_format != V4L2_PIX_FMT_NV12M ))
384400 return - EINVAL ;
385401
@@ -431,9 +447,6 @@ static int isp_vidioc_get_format(struct file *file, void *fh,
431447 struct apple_isp * isp = video_drvdata (file );
432448 struct isp_format * fmt = isp_get_current_format (isp );
433449
434- if (isp -> multiplanar )
435- return - ENOTTY ;
436-
437450 isp_get_sp_pix_format (isp , f , fmt );
438451
439452 return 0 ;
@@ -447,16 +460,15 @@ static int isp_vidioc_set_format(struct file *file, void *fh,
447460 struct isp_preset * preset ;
448461 int err ;
449462
450- if (isp -> multiplanar )
451- return - ENOTTY ;
452-
453463 preset = isp_select_preset (isp , f -> fmt .pix .width , f -> fmt .pix .height );
454464 err = isp_set_preset (isp , fmt , preset );
455465 if (err )
456466 return err ;
457467
458468 isp_get_sp_pix_format (isp , f , fmt );
459469
470+ isp -> vbq .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
471+
460472 return 0 ;
461473}
462474
@@ -468,9 +480,6 @@ static int isp_vidioc_try_format(struct file *file, void *fh,
468480 struct isp_preset * preset ;
469481 int err ;
470482
471- if (isp -> multiplanar )
472- return - ENOTTY ;
473-
474483 preset = isp_select_preset (isp , f -> fmt .pix .width , f -> fmt .pix .height );
475484 err = isp_set_preset (isp , & fmt , preset );
476485 if (err )
@@ -514,6 +523,8 @@ static int isp_vidioc_set_format_mplane(struct file *file, void *fh,
514523
515524 isp_get_mp_pix_format (isp , f , fmt );
516525
526+ isp -> vbq .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ;
527+
517528 return 0 ;
518529}
519530
@@ -571,8 +582,9 @@ static int isp_vidioc_get_param(struct file *file, void *fh,
571582{
572583 struct apple_isp * isp = video_drvdata (file );
573584
574- if (a -> type != (isp -> multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
575- V4L2_BUF_TYPE_VIDEO_CAPTURE ))
585+ if (a -> type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
586+ (!isp -> multiplanar ||
587+ a -> type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ))
576588 return - EINVAL ;
577589
578590 a -> parm .capture .capability = V4L2_CAP_TIMEPERFRAME ;
@@ -588,8 +600,9 @@ static int isp_vidioc_set_param(struct file *file, void *fh,
588600{
589601 struct apple_isp * isp = video_drvdata (file );
590602
591- if (a -> type != (isp -> multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
592- V4L2_BUF_TYPE_VIDEO_CAPTURE ))
603+ if (a -> type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
604+ (!isp -> multiplanar ||
605+ a -> type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ))
593606 return - EINVAL ;
594607
595608 /* Not supporting frame rate sets. No use. Plus floats. */
@@ -670,7 +683,7 @@ int apple_isp_setup_video(struct apple_isp *isp)
670683 goto media_cleanup ;
671684 }
672685
673- isp -> multiplanar = 0 ;
686+ isp -> multiplanar = multiplanar ;
674687
675688 err = v4l2_device_register (isp -> dev , & isp -> v4l2_dev );
676689 if (err ) {
@@ -699,6 +712,8 @@ int apple_isp_setup_video(struct apple_isp *isp)
699712 vdev -> fops = & isp_v4l2_fops ;
700713 vdev -> ioctl_ops = & isp_v4l2_ioctl_ops ;
701714 vdev -> device_caps = V4L2_BUF_TYPE_VIDEO_CAPTURE | V4L2_CAP_STREAMING ;
715+ if (isp -> multiplanar )
716+ vdev -> device_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE ;
702717 vdev -> v4l2_dev = & isp -> v4l2_dev ;
703718 vdev -> vfl_type = VFL_TYPE_VIDEO ;
704719 vdev -> vfl_dir = VFL_DIR_RX ;
0 commit comments