diff mbox series

[11/19] media: max9286: Use V4L2 Streams

Message ID 20240430103956.60190-12-jacopo.mondi@ideasonboard.com (mailing list archive)
State New, archived
Headers show
Series [01/19] media: adv748x: Add support for active state | expand

Commit Message

Jacopo Mondi April 30, 2024, 10:39 a.m. UTC
Use V4L2 streams by introducing a static route table that reports
how the enabled source links are routed through the CSI-2 source pad.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 43 +++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 16 deletions(-)

Comments

Laurent Pinchart May 2, 2024, 6:25 p.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Tue, Apr 30, 2024 at 12:39:47PM +0200, Jacopo Mondi wrote:
> Use V4L2 streams by introducing a static route table that reports
> how the enabled source links are routed through the CSI-2 source pad.
> 
> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 43 +++++++++++++++++++++++--------------
>  1 file changed, 27 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index ae1b73fde832..f203e4527257 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -800,7 +800,7 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>  		 * Get the format from the first used sink pad, as all sink
>  		 * formats must be identical.
>  		 */
> -		format = v4l2_subdev_state_get_format(state, source_idx);
> +		format = v4l2_subdev_state_get_format(state, source_idx, 0);
>  
>  		max9286_set_video_format(priv, format);
>  		max9286_set_fsync_period(priv, state);
> @@ -918,13 +918,14 @@ static int max9286_set_fmt(struct v4l2_subdev *sd,
>  	if (i == ARRAY_SIZE(max9286_formats))
>  		format->format.code = max9286_formats[0].code;
>  
> -	*v4l2_subdev_state_get_format(state, format->pad) = format->format;
> +	*v4l2_subdev_state_get_format(state, format->pad, 0) = format->format;
>  
>  	/*
> -	 * Apply the same format on the source pad: all links must have the
> +	 * Apply the same format on the opposite stream: all links must have the
>  	 * same format.
>  	 */
> -	*v4l2_subdev_state_get_format(state, MAX9286_SRC_PAD) = format->format;
> +	*v4l2_subdev_state_get_opposite_stream_format(state, format->pad, 0) =
> +		format->format;

This would look nicer with an intermediate local variable.

>  
>  	return 0;
>  }
> @@ -957,23 +958,32 @@ static const struct v4l2_mbus_framefmt max9286_default_format = {
>  	.xfer_func	= V4L2_XFER_FUNC_DEFAULT,
>  };
>  
> -static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
> -{
> -	*fmt = max9286_default_format;
> -}
> -
>  static int max9286_init_state(struct v4l2_subdev *sd,
>  			      struct v4l2_subdev_state *state)
>  {
> -	struct v4l2_mbus_framefmt *format;
> -	unsigned int i;
> +	struct v4l2_subdev_route routes[MAX9286_N_SINKS];
> +	struct max9286_priv *priv = sd_to_max9286(sd);
> +	struct max9286_source *source;
> +	unsigned int num_routes = 0;
>  
> -	for (i = 0; i < MAX9286_N_SINKS; i++) {
> -		format = v4l2_subdev_state_get_format(state, i);
> -		max9286_init_format(format);
> +	for_each_source(priv, source) {
> +		struct v4l2_subdev_route *route = &routes[num_routes++];
> +		unsigned int index = to_index(priv, source);
> +
> +		route->sink_pad = index;
> +		route->sink_stream = 0;
> +		route->source_pad = MAX9286_SRC_PAD;
> +		route->source_stream = index;
> +		route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
>  	}
>  
> -	return 0;
> +	struct v4l2_subdev_krouting routing = {
> +		.num_routes = num_routes,

You need to set .len_routes too (the field will appear in v6.10, it's in
the stage tree already).

> +		.routes = routes,
> +	};
> +
> +	return v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
> +						&max9286_default_format);
>  }
>  
>  static const struct v4l2_subdev_internal_ops max9286_subdev_internal_ops = {
> @@ -1014,7 +1024,8 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
>  	/* Configure V4L2 for the MAX9286 itself */
>  	v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops);
>  	priv->sd.internal_ops = &max9286_subdev_internal_ops;
> -	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> +			  V4L2_SUBDEV_FL_STREAMS;
>  
>  	v4l2_ctrl_handler_init(&priv->ctrls, 1);
>  	priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls,
diff mbox series

Patch

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index ae1b73fde832..f203e4527257 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -800,7 +800,7 @@  static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
 		 * Get the format from the first used sink pad, as all sink
 		 * formats must be identical.
 		 */
-		format = v4l2_subdev_state_get_format(state, source_idx);
+		format = v4l2_subdev_state_get_format(state, source_idx, 0);
 
 		max9286_set_video_format(priv, format);
 		max9286_set_fsync_period(priv, state);
@@ -918,13 +918,14 @@  static int max9286_set_fmt(struct v4l2_subdev *sd,
 	if (i == ARRAY_SIZE(max9286_formats))
 		format->format.code = max9286_formats[0].code;
 
-	*v4l2_subdev_state_get_format(state, format->pad) = format->format;
+	*v4l2_subdev_state_get_format(state, format->pad, 0) = format->format;
 
 	/*
-	 * Apply the same format on the source pad: all links must have the
+	 * Apply the same format on the opposite stream: all links must have the
 	 * same format.
 	 */
-	*v4l2_subdev_state_get_format(state, MAX9286_SRC_PAD) = format->format;
+	*v4l2_subdev_state_get_opposite_stream_format(state, format->pad, 0) =
+		format->format;
 
 	return 0;
 }
@@ -957,23 +958,32 @@  static const struct v4l2_mbus_framefmt max9286_default_format = {
 	.xfer_func	= V4L2_XFER_FUNC_DEFAULT,
 };
 
-static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
-{
-	*fmt = max9286_default_format;
-}
-
 static int max9286_init_state(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_state *state)
 {
-	struct v4l2_mbus_framefmt *format;
-	unsigned int i;
+	struct v4l2_subdev_route routes[MAX9286_N_SINKS];
+	struct max9286_priv *priv = sd_to_max9286(sd);
+	struct max9286_source *source;
+	unsigned int num_routes = 0;
 
-	for (i = 0; i < MAX9286_N_SINKS; i++) {
-		format = v4l2_subdev_state_get_format(state, i);
-		max9286_init_format(format);
+	for_each_source(priv, source) {
+		struct v4l2_subdev_route *route = &routes[num_routes++];
+		unsigned int index = to_index(priv, source);
+
+		route->sink_pad = index;
+		route->sink_stream = 0;
+		route->source_pad = MAX9286_SRC_PAD;
+		route->source_stream = index;
+		route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
 	}
 
-	return 0;
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = num_routes,
+		.routes = routes,
+	};
+
+	return v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
+						&max9286_default_format);
 }
 
 static const struct v4l2_subdev_internal_ops max9286_subdev_internal_ops = {
@@ -1014,7 +1024,8 @@  static int max9286_v4l2_register(struct max9286_priv *priv)
 	/* Configure V4L2 for the MAX9286 itself */
 	v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops);
 	priv->sd.internal_ops = &max9286_subdev_internal_ops;
-	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			  V4L2_SUBDEV_FL_STREAMS;
 
 	v4l2_ctrl_handler_init(&priv->ctrls, 1);
 	priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls,