diff mbox series

[v2,12/13] media: rcar-csi2: Implement .get_frame_desc()

Message ID 20211017182449.64192-13-jacopo+renesas@jmondi.org (mailing list archive)
State New
Delegated to: Kieran Bingham
Headers show
Series media: Add multiplexed support to R-Car CSI-2 and GMSL | expand

Commit Message

Jacopo Mondi Oct. 17, 2021, 6:24 p.m. UTC
Implement the get_frame_desc subdev pad operation.

The operation informs the VIN entity to which the CSI-2 output channel
is routed to about the CSI-2 Virtual Channel and the Datatype the
transported stream is tagged with.

Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 63 +++++++++++++++++++++
 1 file changed, 63 insertions(+)
diff mbox series

Patch

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 4ef7b9cb1ab7..7084ee06e99e 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -828,6 +828,68 @@  static int rcsi2_set_pad_format(struct v4l2_subdev *sd,
 	return ret;
 }
 
+/*
+ * The R-Car CSI-2 receivers are connected to the VINs (or ISP) by 'channels'
+ * not to be confused with CSI-2 Virtual Channels.
+ *
+ * Inform the VIN instance, to which the channel identified by the source pad is
+ * routed to, about the CSI-2 Virtual Channel and CSI-2 Datatype of the
+ * transported data stream.
+ */
+static int rcsi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_subdev_route *route;
+	int ret;
+
+	if (pad < RCAR_CSI2_SOURCE_VC0 || pad > RCAR_CSI2_SOURCE_VC3)
+		return -EINVAL;
+
+	state = v4l2_subdev_validate_and_lock_state(sd, state);
+
+	memset(fd, 0, sizeof(*fd));
+
+	for_each_active_route(&state->routing, route) {
+		const struct rcar_csi2_format *rcsi2_fmt;
+		struct v4l2_mbus_framefmt *fmt;
+
+		if (route->source_pad != pad)
+			continue;
+
+		fmt = v4l2_state_get_stream_format(state, pad,
+						   route->source_stream);
+		if (!fmt) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		rcsi2_fmt = rcsi2_code_to_fmt(fmt->code);
+
+		/* Only one stream per 'channel' is allowed. */
+		fd->entry[0].pixelcode = fmt->code;
+		fd->entry[0].length = fmt->width * fmt->height * rcsi2_fmt->bpp / 8;
+		fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+
+		/*
+		 * The sink stream id corresponds to the CSI-2 Virtual Channel
+		 * which is output on the channel identified by the current
+		 * source pad.
+		 */
+		fd->entry[0].bus.csi2.vc = route->source_stream;
+		fd->entry[0].bus.csi2.dt = rcsi2_fmt->datatype;
+
+		break;
+	}
+	fd->num_entries = 1;
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
 static int _rcsi2_set_routing(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_state *state,
 			      struct v4l2_subdev_krouting *routing)
@@ -906,6 +968,7 @@  static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = {
 	.init_cfg = rcsi2_init_cfg,
 	.set_fmt = rcsi2_set_pad_format,
 	.get_fmt = v4l2_subdev_get_fmt,
+	.get_frame_desc = rcsi2_get_frame_desc,
 	.set_routing = rcsi2_set_routing,
 };