@@ -1664,7 +1664,8 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
unsigned int i, j;
int ret = -EINVAL;
- if (disallow & V4L2_SUBDEV_ROUTING_NO_STREAM_MIX) {
+ if (disallow & (V4L2_SUBDEV_ROUTING_NO_STREAM_MIX |
+ V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING)) {
remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads),
GFP_KERNEL);
if (!remote_pads)
@@ -1704,8 +1705,6 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "sink");
goto out;
}
-
- remote_pads[route->sink_pad] = route->source_pad;
}
/*
@@ -1720,7 +1719,38 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "source");
goto out;
}
+ }
+
+ /*
+ * V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING: Pads on the sink
+ * side can not do stream multiplexing, i.e. there can be only
+ * a single stream in a sink pad.
+ */
+ if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING) {
+ if (remote_pads[route->sink_pad] != U32_MAX) {
+ dev_dbg(sd->dev,
+ "route %u attempts to multiplex on %s pad %u\n",
+ i, "sink", route->sink_pad);
+ goto out;
+ }
+ }
+ /*
+ * V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING: Pads on the
+ * source side can not do stream multiplexing, i.e. there can
+ * be only a single stream in a source pad.
+ */
+ if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING) {
+ if (remote_pads[route->source_pad] != U32_MAX) {
+ dev_dbg(sd->dev,
+ "route %u attempts to multiplex on %s pad %u\n",
+ i, "source", route->source_pad);
+ goto out;
+ }
+ }
+
+ if (remote_pads) {
+ remote_pads[route->sink_pad] = route->source_pad;
remote_pads[route->source_pad] = route->sink_pad;
}
@@ -1647,6 +1647,10 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,
* all streams from a sink pad must be routed to a single source pad
* @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX:
* all streams on a source pad must originate from a single sink pad
+ * @V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING:
+ * source pads shall not contain multiplexed streams
+ * @V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING:
+ * sink pads shall not contain multiplexed streams
* @V4L2_SUBDEV_ROUTING_ONLY_1_TO_1:
* only non-overlapping 1-to-1 stream routing is allowed (a combination of
* @V4L2_SUBDEV_ROUTING_NO_1_TO_N and @V4L2_SUBDEV_ROUTING_NO_N_TO_1)
@@ -1655,18 +1659,25 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,
* that source pad shall not get routes from any other sink pad
* (a combination of @V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX and
* @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX)
+ * @V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING:
+ * no multiplexed streams allowed on either source or sink sides.
*/
enum v4l2_subdev_routing_restriction {
V4L2_SUBDEV_ROUTING_NO_1_TO_N = BIT(0),
V4L2_SUBDEV_ROUTING_NO_N_TO_1 = BIT(1),
V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX = BIT(2),
V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX = BIT(3),
+ V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING = BIT(4),
+ V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING = BIT(5),
V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 =
V4L2_SUBDEV_ROUTING_NO_1_TO_N |
V4L2_SUBDEV_ROUTING_NO_N_TO_1,
V4L2_SUBDEV_ROUTING_NO_STREAM_MIX =
V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX |
V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX,
+ V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING =
+ V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING |
+ V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING,
};
/**