From 9894906ad424f266853b61a6996b2da8b119c6e6 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
Date: Fri, 13 Sep 2019 17:19:33 +0100
Subject: [PATCH] staging:bcm2835-codec: Add support for
 ENUM_FRAMESIZES

Required for compliance testing for the encoder.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
---
 .../bcm2835-codec/bcm2835-v4l2-codec.c        | 48 +++++++++++++++++--
 1 file changed, 44 insertions(+), 4 deletions(-)

--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
@@ -496,9 +496,10 @@ struct bcm2835_codec_fmt *get_default_fo
 	return &dev->supported_fmts[capture ? 1 : 0].list[0];
 }
 
-static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f,
-					     struct bcm2835_codec_dev *dev,
-					     bool capture)
+static
+struct bcm2835_codec_fmt *find_format_pix_fmt(u32 pix_fmt,
+					      struct bcm2835_codec_dev *dev,
+					      bool capture)
 {
 	struct bcm2835_codec_fmt *fmt;
 	unsigned int k;
@@ -507,7 +508,7 @@ static struct bcm2835_codec_fmt *find_fo
 
 	for (k = 0; k < fmts->num_entries; k++) {
 		fmt = &fmts->list[k];
-		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
+		if (fmt->fourcc == pix_fmt)
 			break;
 	}
 	if (k == fmts->num_entries)
@@ -516,6 +517,14 @@ static struct bcm2835_codec_fmt *find_fo
 	return &fmts->list[k];
 }
 
+static inline
+struct bcm2835_codec_fmt *find_format(struct v4l2_format *f,
+				      struct bcm2835_codec_dev *dev,
+				      bool capture)
+{
+	return find_format_pix_fmt(f->fmt.pix_mp.pixelformat, dev, capture);
+}
+
 static inline struct bcm2835_codec_ctx *file2ctx(struct file *file)
 {
 	return container_of(file->private_data, struct bcm2835_codec_ctx, fh);
@@ -1792,6 +1801,36 @@ static int vidioc_encoder_cmd(struct fil
 	return 0;
 }
 
+static int vidioc_enum_framesizes(struct file *file, void *fh,
+				  struct v4l2_frmsizeenum *fsize)
+{
+	struct bcm2835_codec_fmt *fmt;
+
+	fmt = find_format_pix_fmt(fsize->pixel_format, file2ctx(file)->dev,
+				  true);
+	if (!fmt)
+		fmt = find_format_pix_fmt(fsize->pixel_format,
+					  file2ctx(file)->dev,
+					  false);
+
+	if (!fmt)
+		return -EINVAL;
+
+	if (fsize->index)
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+
+	fsize->stepwise.min_width = MIN_W;
+	fsize->stepwise.max_width = MAX_W;
+	fsize->stepwise.step_width = 1;
+	fsize->stepwise.min_height = MIN_H;
+	fsize->stepwise.max_height = MAX_H;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
 static const struct v4l2_ioctl_ops bcm2835_codec_ioctl_ops = {
 	.vidioc_querycap	= vidioc_querycap,
 
@@ -1829,6 +1868,7 @@ static const struct v4l2_ioctl_ops bcm28
 	.vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
 	.vidioc_encoder_cmd = vidioc_encoder_cmd,
 	.vidioc_try_encoder_cmd = vidioc_try_encoder_cmd,
+	.vidioc_enum_framesizes = vidioc_enum_framesizes,
 };
 
 static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx)
