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 ||