[4/8] media: rkisp1: Add support for ext format

Message ID 20240605165434.432230-5-jacopo.mondi@ideasonboard.com (mailing list archive)
State Superseded
Headers
Series media: rkisp1: Implement support for extensible parameters |

Commit Message

Jacopo Mondi June 5, 2024, 4:54 p.m. UTC
  Add support to the rkisp1 driver for the extensible parameters format.

Allow the driver to enumerate the existing and the new format and
implement support for the try_fmt and s_fmt operations.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 .../platform/rockchip/rkisp1/rkisp1-common.h  |  1 +
 .../platform/rockchip/rkisp1/rkisp1-params.c  | 87 +++++++++++++++++--
 2 files changed, 79 insertions(+), 9 deletions(-)
  

Comments

Daniel Scally June 12, 2024, 10:46 a.m. UTC | #1
Hi Jacopo, thanks for the patch

On 05/06/2024 17:54, Jacopo Mondi wrote:
> Add support to the rkisp1 driver for the extensible parameters format.
>
> Allow the driver to enumerate the existing and the new format and
> implement support for the try_fmt and s_fmt operations.
>
> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>


Isn't this too early in the set? I'd expect this to come after the actual support for handling the 
extensible buffers was done.

> ---
>   .../platform/rockchip/rkisp1/rkisp1-common.h  |  1 +
>   .../platform/rockchip/rkisp1/rkisp1-params.c  | 87 +++++++++++++++++--
>   2 files changed, 79 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index 2a715f964f6e..0bddae8dbdb1 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -383,6 +383,7 @@ struct rkisp1_params {
>   	spinlock_t config_lock; /* locks the buffers list 'params' */
>   	struct list_head params;
>   
> +	struct v4l2_meta_format metafmt;
>   	enum v4l2_quantization quantization;
>   	enum v4l2_ycbcr_encoding ycbcr_encoding;
>   	enum rkisp1_fmt_raw_pat_type raw_type;
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> index 1f449f29b241..6f99c7dad758 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> @@ -33,6 +33,34 @@
>   #define RKISP1_ISP_CC_COEFF(n) \
>   			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
>   
> +enum rkisp1_params_formats {
> +	RKISP1_PARAMS_FIXED,
> +	RKISP1_PARAMS_EXTENSIBLE,
> +	RKISP1_PARAMS_NUM_FMT,
> +};
> +
> +static const struct v4l2_meta_format rkisp1_params_formats[] = {
> +	[RKISP1_PARAMS_FIXED] = {
> +		.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS,
> +		.buffersize = sizeof(struct rkisp1_params_cfg),
> +	},
> +	[RKISP1_PARAMS_EXTENSIBLE] = {
> +		.dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS,
> +		.buffersize = sizeof(struct rkisp1_ext_params_cfg),
> +	},
> +};
> +
> +static const struct v4l2_meta_format *
> +rkisp1_params_get_format_info(u32 dataformat)
> +{
> +	for (unsigned int i = 0; i < RKISP1_PARAMS_NUM_FMT; i++) {
> +		if (rkisp1_params_formats[i].dataformat == dataformat)
> +			return &rkisp1_params_formats[i];
> +	}
> +
> +	return &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
> +}
> +
>   static inline void
>   rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
>   {
> @@ -1742,11 +1770,13 @@ static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
>   					   struct v4l2_fmtdesc *f)
>   {
>   	struct video_device *video = video_devdata(file);
> +	const struct v4l2_meta_format *metafmt;
>   
> -	if (f->index > 0 || f->type != video->queue->type)
> +	if (f->index >= RKISP1_PARAMS_NUM_FMT || f->type != video->queue->type)
>   		return -EINVAL;
>   
> -	f->pixelformat = V4L2_META_FMT_RK_ISP1_PARAMS;
> +	metafmt = &rkisp1_params_formats[f->index];
> +	f->pixelformat = metafmt->dataformat;
>   
>   	return 0;
>   }
> @@ -1755,14 +1785,44 @@ static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
>   					struct v4l2_format *f)
>   {
>   	struct video_device *video = video_devdata(file);
> +	struct rkisp1_params *params = video_get_drvdata(video);
>   	struct v4l2_meta_format *meta = &f->fmt.meta;
>   
>   	if (f->type != video->queue->type)
>   		return -EINVAL;
>   
>   	memset(meta, 0, sizeof(*meta));
> -	meta->dataformat = V4L2_META_FMT_RK_ISP1_PARAMS;
> -	meta->buffersize = sizeof(struct rkisp1_params_cfg);
> +	*meta = params->metafmt;
> +
> +	return 0;
> +}
> +
> +static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh,
> +					  struct v4l2_format *f)
> +{
> +	struct video_device *video = video_devdata(file);
> +	struct v4l2_meta_format *meta = &f->fmt.meta;
> +
> +	if (f->type != video->queue->type)
> +		return -EINVAL;
> +
> +	*meta = *rkisp1_params_get_format_info(meta->dataformat);
> +
> +	return 0;
> +}
> +
> +static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh,
> +					struct v4l2_format *f)
> +{
> +	struct video_device *video = video_devdata(file);
> +	struct rkisp1_params *params = video_get_drvdata(video);
> +	struct v4l2_meta_format *meta = &f->fmt.meta;
> +
> +	if (f->type != video->queue->type)
> +		return -EINVAL;
> +
> +	*meta = *rkisp1_params_get_format_info(meta->dataformat);
> +	params->metafmt = *meta;
>   
>   	return 0;
>   }
> @@ -1792,8 +1852,8 @@ static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
>   	.vidioc_streamoff = vb2_ioctl_streamoff,
>   	.vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
>   	.vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> -	.vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> -	.vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> +	.vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out,
> +	.vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out,
>   	.vidioc_querycap = rkisp1_params_querycap,
>   	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
>   	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> @@ -1805,13 +1865,16 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
>   					 unsigned int sizes[],
>   					 struct device *alloc_devs[])
>   {
> +	struct rkisp1_params *params = vq->drv_priv;
> +	size_t buf_size = params->metafmt.buffersize;
> +
>   	*num_buffers = clamp_t(u32, *num_buffers,
>   			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
>   			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
>   
>   	*num_planes = 1;
>   
> -	sizes[0] = sizeof(struct rkisp1_params_cfg);
> +	sizes[0] = buf_size;
sizes[0] = params->metafmt.buffersize; would save a variable - up to you.
>   
>   	return 0;
>   }
> @@ -1831,10 +1894,14 @@ static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
>   
>   static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
>   {
> -	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
> +	struct vb2_queue *vq = vb->vb2_queue;
> +	struct rkisp1_params *params = vq->drv_priv;
> +	size_t buf_size = params->metafmt.buffersize;
> +
> +	if (vb2_plane_size(vb, 0) < buf_size)
>   		return -EINVAL;
>   
> -	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
> +	vb2_set_plane_payload(vb, 0, buf_size);
>   
>   	return 0;
>   }
> @@ -1929,6 +1996,8 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1)
>   	else
>   		params->ops = &rkisp1_v10_params_ops;
>   
> +	params->metafmt = rkisp1_params_formats[RKISP1_PARAMS_FIXED];
> +
>   	video_set_drvdata(vdev, params);
>   
>   	node->pad.flags = MEDIA_PAD_FL_SOURCE;
  
Laurent Pinchart June 12, 2024, 2:51 p.m. UTC | #2
On Wed, Jun 12, 2024 at 11:46:17AM +0100, Daniel Scally wrote:
> Hi Jacopo, thanks for the patch
> 
> On 05/06/2024 17:54, Jacopo Mondi wrote:
> > Add support to the rkisp1 driver for the extensible parameters format.
> >
> > Allow the driver to enumerate the existing and the new format and
> > implement support for the try_fmt and s_fmt operations.
> >
> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> 
> Isn't this too early in the set? I'd expect this to come after the
> actual support for handling the extensible buffers was done.

Agreed.

> > ---
> >   .../platform/rockchip/rkisp1/rkisp1-common.h  |  1 +
> >   .../platform/rockchip/rkisp1/rkisp1-params.c  | 87 +++++++++++++++++--
> >   2 files changed, 79 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > index 2a715f964f6e..0bddae8dbdb1 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > @@ -383,6 +383,7 @@ struct rkisp1_params {
> >   	spinlock_t config_lock; /* locks the buffers list 'params' */
> >   	struct list_head params;
> >   
> > +	struct v4l2_meta_format metafmt;

This could be turned to a static const pointer, pointing to an entry
from rkisp1_params_formats, as none of the fields can be further
modified by userspace once a format is selected. Up to you.

> >   	enum v4l2_quantization quantization;
> >   	enum v4l2_ycbcr_encoding ycbcr_encoding;
> >   	enum rkisp1_fmt_raw_pat_type raw_type;
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > index 1f449f29b241..6f99c7dad758 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > @@ -33,6 +33,34 @@
> >   #define RKISP1_ISP_CC_COEFF(n) \
> >   			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
> >   
> > +enum rkisp1_params_formats {
> > +	RKISP1_PARAMS_FIXED,
> > +	RKISP1_PARAMS_EXTENSIBLE,
> > +	RKISP1_PARAMS_NUM_FMT,
> > +};
> > +
> > +static const struct v4l2_meta_format rkisp1_params_formats[] = {
> > +	[RKISP1_PARAMS_FIXED] = {
> > +		.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS,
> > +		.buffersize = sizeof(struct rkisp1_params_cfg),
> > +	},
> > +	[RKISP1_PARAMS_EXTENSIBLE] = {
> > +		.dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS,
> > +		.buffersize = sizeof(struct rkisp1_ext_params_cfg),
> > +	},
> > +};
> > +
> > +static const struct v4l2_meta_format *
> > +rkisp1_params_get_format_info(u32 dataformat)
> > +{
> > +	for (unsigned int i = 0; i < RKISP1_PARAMS_NUM_FMT; i++) {

Use ARRAY_SIZE(rkisp1_params_formats) instead of RKISP1_PARAMS_NUM_FMT,
that's safer. Same below, and drop RKISP1_PARAMS_NUM_FMT

> > +		if (rkisp1_params_formats[i].dataformat == dataformat)
> > +			return &rkisp1_params_formats[i];
> > +	}
> > +
> > +	return &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
> > +}
> > +
> >   static inline void
> >   rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
> >   {
> > @@ -1742,11 +1770,13 @@ static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
> >   					   struct v4l2_fmtdesc *f)
> >   {
> >   	struct video_device *video = video_devdata(file);
> > +	const struct v4l2_meta_format *metafmt;
> >   
> > -	if (f->index > 0 || f->type != video->queue->type)
> > +	if (f->index >= RKISP1_PARAMS_NUM_FMT || f->type != video->queue->type)
> >   		return -EINVAL;
> >   
> > -	f->pixelformat = V4L2_META_FMT_RK_ISP1_PARAMS;
> > +	metafmt = &rkisp1_params_formats[f->index];
> > +	f->pixelformat = metafmt->dataformat;

You could drop the metafmt variable:

	f->pixelformat = rkisp1_params_formats[f->index].dataformat;

> >   
> >   	return 0;
> >   }
> > @@ -1755,14 +1785,44 @@ static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
> >   					struct v4l2_format *f)
> >   {
> >   	struct video_device *video = video_devdata(file);
> > +	struct rkisp1_params *params = video_get_drvdata(video);
> >   	struct v4l2_meta_format *meta = &f->fmt.meta;
> >   
> >   	if (f->type != video->queue->type)
> >   		return -EINVAL;
> >   
> >   	memset(meta, 0, sizeof(*meta));
> > -	meta->dataformat = V4L2_META_FMT_RK_ISP1_PARAMS;
> > -	meta->buffersize = sizeof(struct rkisp1_params_cfg);
> > +	*meta = params->metafmt;

You can drop the memset now that you assign the whole structure.

> > +
> > +	return 0;
> > +}
> > +
> > +static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh,
> > +					  struct v4l2_format *f)
> > +{
> > +	struct video_device *video = video_devdata(file);
> > +	struct v4l2_meta_format *meta = &f->fmt.meta;
> > +
> > +	if (f->type != video->queue->type)
> > +		return -EINVAL;
> > +
> > +	*meta = *rkisp1_params_get_format_info(meta->dataformat);
> > +
> > +	return 0;
> > +}
> > +
> > +static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh,
> > +					struct v4l2_format *f)
> > +{
> > +	struct video_device *video = video_devdata(file);
> > +	struct rkisp1_params *params = video_get_drvdata(video);
> > +	struct v4l2_meta_format *meta = &f->fmt.meta;
> > +
> > +	if (f->type != video->queue->type)
> > +		return -EINVAL;
> > +
> > +	*meta = *rkisp1_params_get_format_info(meta->dataformat);
> > +	params->metafmt = *meta;
> >   
> >   	return 0;
> >   }
> > @@ -1792,8 +1852,8 @@ static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
> >   	.vidioc_streamoff = vb2_ioctl_streamoff,
> >   	.vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
> >   	.vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> > -	.vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> > -	.vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
> > +	.vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out,
> > +	.vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out,
> >   	.vidioc_querycap = rkisp1_params_querycap,
> >   	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> >   	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> > @@ -1805,13 +1865,16 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
> >   					 unsigned int sizes[],
> >   					 struct device *alloc_devs[])
> >   {
> > +	struct rkisp1_params *params = vq->drv_priv;
> > +	size_t buf_size = params->metafmt.buffersize;
> > +
> >   	*num_buffers = clamp_t(u32, *num_buffers,
> >   			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
> >   			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
> >   
> >   	*num_planes = 1;
> >   
> > -	sizes[0] = sizeof(struct rkisp1_params_cfg);
> > +	sizes[0] = buf_size;
>
> sizes[0] = params->metafmt.buffersize; would save a variable - up to you.
>
> >   
> >   	return 0;
> >   }
> > @@ -1831,10 +1894,14 @@ static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
> >   
> >   static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
> >   {
> > -	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
> > +	struct vb2_queue *vq = vb->vb2_queue;
> > +	struct rkisp1_params *params = vq->drv_priv;
> > +	size_t buf_size = params->metafmt.buffersize;
> > +
> > +	if (vb2_plane_size(vb, 0) < buf_size)
> >   		return -EINVAL;
> >   
> > -	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
> > +	vb2_set_plane_payload(vb, 0, buf_size);
> >   
> >   	return 0;
> >   }
> > @@ -1929,6 +1996,8 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1)
> >   	else
> >   		params->ops = &rkisp1_v10_params_ops;
> >   
> > +	params->metafmt = rkisp1_params_formats[RKISP1_PARAMS_FIXED];
> > +
> >   	video_set_drvdata(vdev, params);
> >   
> >   	node->pad.flags = MEDIA_PAD_FL_SOURCE;
  

Patch

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 2a715f964f6e..0bddae8dbdb1 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -383,6 +383,7 @@  struct rkisp1_params {
 	spinlock_t config_lock; /* locks the buffers list 'params' */
 	struct list_head params;
 
+	struct v4l2_meta_format metafmt;
 	enum v4l2_quantization quantization;
 	enum v4l2_ycbcr_encoding ycbcr_encoding;
 	enum rkisp1_fmt_raw_pat_type raw_type;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
index 1f449f29b241..6f99c7dad758 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
@@ -33,6 +33,34 @@ 
 #define RKISP1_ISP_CC_COEFF(n) \
 			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
 
+enum rkisp1_params_formats {
+	RKISP1_PARAMS_FIXED,
+	RKISP1_PARAMS_EXTENSIBLE,
+	RKISP1_PARAMS_NUM_FMT,
+};
+
+static const struct v4l2_meta_format rkisp1_params_formats[] = {
+	[RKISP1_PARAMS_FIXED] = {
+		.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS,
+		.buffersize = sizeof(struct rkisp1_params_cfg),
+	},
+	[RKISP1_PARAMS_EXTENSIBLE] = {
+		.dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS,
+		.buffersize = sizeof(struct rkisp1_ext_params_cfg),
+	},
+};
+
+static const struct v4l2_meta_format *
+rkisp1_params_get_format_info(u32 dataformat)
+{
+	for (unsigned int i = 0; i < RKISP1_PARAMS_NUM_FMT; i++) {
+		if (rkisp1_params_formats[i].dataformat == dataformat)
+			return &rkisp1_params_formats[i];
+	}
+
+	return &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
+}
+
 static inline void
 rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
 {
@@ -1742,11 +1770,13 @@  static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
 					   struct v4l2_fmtdesc *f)
 {
 	struct video_device *video = video_devdata(file);
+	const struct v4l2_meta_format *metafmt;
 
-	if (f->index > 0 || f->type != video->queue->type)
+	if (f->index >= RKISP1_PARAMS_NUM_FMT || f->type != video->queue->type)
 		return -EINVAL;
 
-	f->pixelformat = V4L2_META_FMT_RK_ISP1_PARAMS;
+	metafmt = &rkisp1_params_formats[f->index];
+	f->pixelformat = metafmt->dataformat;
 
 	return 0;
 }
@@ -1755,14 +1785,44 @@  static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
 					struct v4l2_format *f)
 {
 	struct video_device *video = video_devdata(file);
+	struct rkisp1_params *params = video_get_drvdata(video);
 	struct v4l2_meta_format *meta = &f->fmt.meta;
 
 	if (f->type != video->queue->type)
 		return -EINVAL;
 
 	memset(meta, 0, sizeof(*meta));
-	meta->dataformat = V4L2_META_FMT_RK_ISP1_PARAMS;
-	meta->buffersize = sizeof(struct rkisp1_params_cfg);
+	*meta = params->metafmt;
+
+	return 0;
+}
+
+static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh,
+					  struct v4l2_format *f)
+{
+	struct video_device *video = video_devdata(file);
+	struct v4l2_meta_format *meta = &f->fmt.meta;
+
+	if (f->type != video->queue->type)
+		return -EINVAL;
+
+	*meta = *rkisp1_params_get_format_info(meta->dataformat);
+
+	return 0;
+}
+
+static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct video_device *video = video_devdata(file);
+	struct rkisp1_params *params = video_get_drvdata(video);
+	struct v4l2_meta_format *meta = &f->fmt.meta;
+
+	if (f->type != video->queue->type)
+		return -EINVAL;
+
+	*meta = *rkisp1_params_get_format_info(meta->dataformat);
+	params->metafmt = *meta;
 
 	return 0;
 }
@@ -1792,8 +1852,8 @@  static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
 	.vidioc_streamoff = vb2_ioctl_streamoff,
 	.vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
 	.vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
-	.vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
-	.vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+	.vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out,
+	.vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out,
 	.vidioc_querycap = rkisp1_params_querycap,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -1805,13 +1865,16 @@  static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
 					 unsigned int sizes[],
 					 struct device *alloc_devs[])
 {
+	struct rkisp1_params *params = vq->drv_priv;
+	size_t buf_size = params->metafmt.buffersize;
+
 	*num_buffers = clamp_t(u32, *num_buffers,
 			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
 			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
 
 	*num_planes = 1;
 
-	sizes[0] = sizeof(struct rkisp1_params_cfg);
+	sizes[0] = buf_size;
 
 	return 0;
 }
@@ -1831,10 +1894,14 @@  static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
 
 static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
 {
-	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
+	struct vb2_queue *vq = vb->vb2_queue;
+	struct rkisp1_params *params = vq->drv_priv;
+	size_t buf_size = params->metafmt.buffersize;
+
+	if (vb2_plane_size(vb, 0) < buf_size)
 		return -EINVAL;
 
-	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
+	vb2_set_plane_payload(vb, 0, buf_size);
 
 	return 0;
 }
@@ -1929,6 +1996,8 @@  int rkisp1_params_register(struct rkisp1_device *rkisp1)
 	else
 		params->ops = &rkisp1_v10_params_ops;
 
+	params->metafmt = rkisp1_params_formats[RKISP1_PARAMS_FIXED];
+
 	video_set_drvdata(vdev, params);
 
 	node->pad.flags = MEDIA_PAD_FL_SOURCE;