[PATCH v2 1/2] media: imx274: improve v4l2-compliance

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



1) Fix incorrect return of get_fmt when fmt->which is set
to V4L2_SUBDEV_FORMAT_TRY. get_fmt always returns the active format,
but should return the pad configuration when V4L2_SUBDEV_FORMAT_TRY
is requested.

2) Fix set_fmt not functioning correctly when fmt->which is set to
V4L2_SUBDEV_FORMAT_TRY, by implementing 'init_cfg'.

3) Add support for enumerating media bus formats
via VIDIOC_SUBDEV_ENUM_MBUS_CODE.

4) Add  support for enumerating frame sizes
via VIDIOC_SUBDEV_ENUM_FRAME_SIZE.

5) Fix v4l2-compliance error 'VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL'
by implementing v4l2_subdev_core_ops struct with default functions.

Signed-off-by: Bob Veringa <bob.veringa@xxxxxxxx>
Acked-by: Mike Looijmans <mike.looijmans@xxxxxxxx>
---
Integrated feedback on the previous patch. The init_cfg method 
has been implemented to configure the subdev pad config.

 drivers/media/i2c/imx274.c | 77 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index d9849d34f39f..52ca9bdf0066 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -28,6 +28,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
+#include <media/v4l2-event.h>
 
 /*
  * See "SHR, SVR Setting" in datasheet
@@ -72,6 +73,7 @@
 #define IMX274_MAX_FRAME_RATE			(120)
 #define IMX274_MIN_FRAME_RATE			(5)
 #define IMX274_DEF_FRAME_RATE			(60)
+#define IMX274_DEFAULT_MEDIA_FORMAT		MEDIA_BUS_FMT_SRGGB10_1X10
 
 /*
  * register SHR is limited to (SVR value + 1) x VMAX value - 4
@@ -1072,11 +1074,23 @@ static int imx274_get_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_format *fmt)
 {
 	struct stimx274 *imx274 = to_imx274(sd);
+	int ret = 0;
 
 	mutex_lock(&imx274->lock);
-	fmt->format = imx274->format;
+
+	switch (fmt->which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+		break;
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		fmt->format = imx274->format;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
 	mutex_unlock(&imx274->lock);
-	return 0;
+	return ret;
 }
 
 /**
@@ -1274,6 +1288,53 @@ static int imx274_set_selection(struct v4l2_subdev *sd,
 	return -EINVAL;
 }
 
+static int imx274_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	u32 width, height;
+
+	if (fse->index >= ARRAY_SIZE(imx274_modes))
+		return -EINVAL;
+
+	width = IMX274_MAX_WIDTH / imx274_modes[fse->index].wbin_ratio;
+	height = IMX274_MAX_HEIGHT / imx274_modes[fse->index].hbin_ratio;
+
+	fse->code = IMX274_DEFAULT_MEDIA_FORMAT;
+	fse->min_width = width;
+	fse->max_width = width;
+	fse->min_height = height;
+	fse->max_height = height;
+	return 0;
+}
+
+static int imx274_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = IMX274_DEFAULT_MEDIA_FORMAT;
+
+	return 0;
+}
+
+static int imx274_init_cfg(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg)
+{
+	struct imx274_mode *mode = &imx274_modes[0];
+
+	cfg->try_crop.width = IMX274_MAX_WIDTH;
+	cfg->try_crop.height = IMX274_MAX_HEIGHT;
+
+	cfg->try_fmt.width = cfg->try_crop.width / mode->wbin_ratio;
+	cfg->try_fmt.height = cfg->try_crop.height / mode->hbin_ratio;
+	cfg->try_fmt.field = V4L2_FIELD_NONE;
+	cfg->try_fmt.code = IMX274_DEFAULT_MEDIA_FORMAT;
+	cfg->try_fmt.colorspace = V4L2_COLORSPACE_SRGB;
+}
+
 static int imx274_apply_trimming(struct stimx274 *imx274)
 {
 	u32 h_start;
@@ -1903,11 +1964,20 @@ static int imx274_set_frame_interval(struct stimx274 *priv,
 	return err;
 }
 
+static const struct v4l2_subdev_core_ops imx274_core_ops = {
+	.log_status = v4l2_ctrl_subdev_log_status,
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
 static const struct v4l2_subdev_pad_ops imx274_pad_ops = {
 	.get_fmt = imx274_get_fmt,
 	.set_fmt = imx274_set_fmt,
 	.get_selection = imx274_get_selection,
 	.set_selection = imx274_set_selection,
+	.enum_mbus_code = imx274_enum_mbus_code,
+	.enum_frame_size = imx274_enum_frame_size,
+	.init_cfg = imx274_init_cfg,
 };
 
 static const struct v4l2_subdev_video_ops imx274_video_ops = {
@@ -1917,6 +1987,7 @@ static const struct v4l2_subdev_video_ops imx274_video_ops = {
 };
 
 static const struct v4l2_subdev_ops imx274_subdev_ops = {
+	.core = &imx274_core_ops,
 	.pad = &imx274_pad_ops,
 	.video = &imx274_video_ops,
 };
@@ -1968,7 +2039,7 @@ static int imx274_probe(struct i2c_client *client)
 	imx274->format.width = imx274->crop.width / imx274->mode->wbin_ratio;
 	imx274->format.height = imx274->crop.height / imx274->mode->hbin_ratio;
 	imx274->format.field = V4L2_FIELD_NONE;
-	imx274->format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
+	imx274->format.code = IMX274_DEFAULT_MEDIA_FORMAT;
 	imx274->format.colorspace = V4L2_COLORSPACE_SRGB;
 	imx274->frame_interval.numerator = 1;
 	imx274->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
-- 
2.17.1


Met vriendelijke groet / kind regards,

Bob Veringa


TOPIC Embedded Systems B.V.
Materiaalweg 4, 5681 RJ Best
The Netherlands

T: +31 (0) 499 33 69 79
E: bob.Veringa@xxxxxxxx
W: www.topic.nl

Please consider the environment before printing this e-mail




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux