@@ -942,6 +942,59 @@ static int rcsi2_set_pad_format(struct v4l2_subdev *sd,
return ret;
}
+static int __rcsi2_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ unsigned int i;
+ int ret = 0;
+
+ ret = v4l2_subdev_routing_validate_1_to_1(routing);
+ if (ret)
+ return ret;
+
+ v4l2_subdev_lock_state(state);
+
+ /*
+ * Routing is fixed for this device.
+ *
+ * Only routes in the form of CSI2:0/x->CSI2:x+1/0 are allowed.
+ *
+ * We have anyway to implement set_routing to mark the route as active.
+ */
+ for (i = 0; i < routing->num_routes; ++i) {
+ const struct v4l2_subdev_route *route = &routing->routes[i];
+ unsigned int vc = route->sink_stream;
+ unsigned int pad = vc + 1;
+
+ if (route->sink_pad != 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (route->source_pad != pad ||
+ route->source_stream != 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ ret = v4l2_subdev_set_routing(sd, state, routing);
+
+out:
+ v4l2_subdev_unlock_state(state);
+
+ return ret;
+}
+
+static int rcsi2_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ return __rcsi2_set_routing(sd, state, routing);
+}
+
static int rcsi2_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
@@ -992,15 +1045,7 @@ static int rcsi2_init_cfg(struct v4l2_subdev *sd,
.routes = routes,
};
- int ret = v4l2_subdev_routing_validate_1_to_1(&routing);
- if (ret)
- return ret;
-
- v4l2_subdev_lock_state(state);
- ret = v4l2_subdev_set_routing(sd, state, &routing);
- v4l2_subdev_unlock_state(state);
-
- return ret;
+ return __rcsi2_set_routing(sd, state, &routing);
}
static const struct v4l2_subdev_video_ops rcar_csi2_video_ops = {
@@ -1011,6 +1056,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,
+ .set_routing = rcsi2_set_routing,
};
static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
Add the set_routing() subdev operation to allow userspace to activate routes on the R-Car CSI-2 receiver. Routing for this device is fixed. Validate that the provided route respects it. Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> --- drivers/media/platform/rcar-vin/rcar-csi2.c | 64 ++++++++++++++++++--- 1 file changed, 55 insertions(+), 9 deletions(-)