mtk_mipicsi: add v4l2 enumeration support

Support returning camera resolution and frame rate with
v4l2-ctl --device /dev/video1 --list-formats-ext

Fix the out-of-boundary enumration in the ov5645_mipi_v2 driver

Change-Id: Ia5fc79ceb78cf2a5ce436e2c9fe2c3a056d0d0af
diff --git a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
index d64fa0f..42f062c 100644
--- a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
+++ b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
@@ -864,6 +864,29 @@ static int mtk_enum_fmt_vid_cap(struct file *file, void  *priv,
 	return 0;
 }
 
+/* V4L2 platform handler for VIDIOC_ENUM_FRAMESIZES ioctl */
+static int mtk_enum_framesizes(struct file *file, void *priv,
+			     struct v4l2_frmsizeenum *fsize) {
+	struct mtk_mipicsi_dev *mipicsi = video_drvdata(file);
+	struct v4l2_subdev *sd = mipicsi->mipicsi_sd.subdev;
+	struct v4l2_subdev_frame_size_enum fse;
+	int ret = 0;
+
+	fse.index = fsize->index;
+	fse.pad = 0;
+
+	ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
+	if (ret < 0) {
+		return ret;
+	}
+
+	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+	fsize->discrete.width = fse.max_width;
+	fsize->discrete.height = fse.max_height;
+
+	return ret;
+}
+
 static const struct mtk_format *find_format_by_fourcc(
 					struct mtk_mipicsi_dev *mipicsi,
 					unsigned int fourcc)
@@ -881,6 +904,38 @@ static const struct mtk_format *find_format_by_fourcc(
 	return NULL;
 }
 
+/* V4L2 platform handler for VIDIOC_ENUM_FRAMEINTERVALS ioctl */
+static int mtk_enum_frameintervals(struct file *file, void *priv,
+			     struct v4l2_frmivalenum *fival) {
+	struct mtk_mipicsi_dev *mipicsi = video_drvdata(file);
+	struct v4l2_subdev *sd = mipicsi->mipicsi_sd.subdev;
+	struct v4l2_subdev_frame_interval_enum fie = {
+		.index = fival->index,
+		.width = fival->width,
+		.height = fival->height,
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	const struct mtk_format *mtk_fmt;
+	int ret = 0;
+
+	mtk_fmt = find_format_by_fourcc(mipicsi, fival->pixel_format);
+	if(!mtk_fmt) {
+		mtk_fmt = mipicsi->user_formats[0];
+	}
+
+	fie.code = mtk_fmt->mbus_code;
+
+	ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie);
+	if (ret < 0) {
+		return ret;
+	}
+
+	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+	fival->discrete = fie.interval;
+
+	return ret;
+}
+
 static int mtk_mipicsi_try_fmt(struct mtk_mipicsi_dev *mipicsi,
 			      struct v4l2_format *f,
 			      const struct mtk_format **current_fmt)
@@ -1031,6 +1086,8 @@ static const struct v4l2_ioctl_ops mtk_mipicsi_ioctl_ops = {
 	.vidioc_s_input                 = mtk_s_input,
 	.vidioc_g_parm                  = mtk_g_parm,
 	.vidioc_s_parm                  = mtk_s_parm,
+	.vidioc_enum_framesizes         = mtk_enum_framesizes,
+	.vidioc_enum_frameintervals     = mtk_enum_frameintervals,
 
 	.vidioc_reqbufs                 = vb2_ioctl_reqbufs,
 	.vidioc_create_bufs             = vb2_ioctl_create_bufs,
diff --git a/drivers/media/platform/mxc/capture/ov5645_mipi_v2.c b/drivers/media/platform/mxc/capture/ov5645_mipi_v2.c
index aaceb43..497fd28 100644
--- a/drivers/media/platform/mxc/capture/ov5645_mipi_v2.c
+++ b/drivers/media/platform/mxc/capture/ov5645_mipi_v2.c
@@ -3268,7 +3268,7 @@ static int ov5645_enum_framesizes(struct v4l2_subdev *sd,
 			       struct v4l2_subdev_pad_config *cfg,
 			       struct v4l2_subdev_frame_size_enum *fse)
 {
-	if (fse->index > ov5645_mode_MAX)
+	if (fse->index >= ov5645_mode_MAX)
 		return -EINVAL;
 
 	fse->max_width =
@@ -3301,7 +3301,7 @@ static int ov5645_enum_frameintervals(struct v4l2_subdev *sd,
 {
 	int i, j, count = 0;
 
-	if (fie->index < 0 || fie->index > ov5645_mode_MAX)
+	if (fie->index < 0 || fie->index >= ov5645_mode_MAX)
 		return -EINVAL;
 
 	if (fie->width == 0 || fie->height == 0 ||