All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/2] v4l2-ctl: add ROUTING get and set options
@ 2017-12-14 19:09 Niklas Söderlund
  2017-12-14 19:09 ` [RFC 1/2] Synchronize with the Kernel headers for routing operations Niklas Söderlund
  2017-12-14 19:09 ` [RFC 2/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund
  0 siblings, 2 replies; 3+ messages in thread
From: Niklas Söderlund @ 2017-12-14 19:09 UTC (permalink / raw)
  To: linux-media, Sakari Ailus
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, Benoit Parrot, Maxime Ripard,
	Niklas Söderlund

Hi,

This small series adds support for the [GS]_ROUTING subdev ioctls 
introduced in Sakari's vc branch.

git://linuxtv.org/sailus/media_tree.git#vc

The use-case for this is to control the internal routing between pads 
inside a subdevice. Currently this is used on the ADV7482 to select 
which of it's 8 analog inputs are routed to the source pad. It is also 
used in the R-Car CSI-2, ADV7482 and MAX9286 drivers to deserve which 
pad is routed to which stream of the multiplexed link between the R-Car 
CSI-2 and either the ADV7482 or the MAX9286.

Niklas Söderlund (2):
  Synchronize with the Kernel headers for routing operations
  v4l2-ctl: add ROUTING get and set options

 include/linux/v4l2-subdev.h         |  41 ++++++++++
 utils/v4l2-ctl/Android.mk           |   2 +-
 utils/v4l2-ctl/Makefile.am          |   2 +-
 utils/v4l2-ctl/v4l2-ctl-routing.cpp | 154 ++++++++++++++++++++++++++++++++++++
 utils/v4l2-ctl/v4l2-ctl.cpp         |  10 +++
 utils/v4l2-ctl/v4l2-ctl.h           |   9 +++
 6 files changed, 216 insertions(+), 2 deletions(-)
 create mode 100644 utils/v4l2-ctl/v4l2-ctl-routing.cpp

-- 
2.14.2

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC 1/2] Synchronize with the Kernel headers for routing operations
  2017-12-14 19:09 [RFC 0/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund
@ 2017-12-14 19:09 ` Niklas Söderlund
  2017-12-14 19:09 ` [RFC 2/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund
  1 sibling, 0 replies; 3+ messages in thread
From: Niklas Söderlund @ 2017-12-14 19:09 UTC (permalink / raw)
  To: linux-media, Sakari Ailus
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, Benoit Parrot, Maxime Ripard,
	Niklas Söderlund

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 include/linux/v4l2-subdev.h | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index dbce2b554e026869..e19ee64075d6cbdf 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * V4L2 subdev userspace API
  *
@@ -154,6 +155,44 @@ struct v4l2_subdev_selection {
 	__u32 reserved[8];
 };
 
+#define V4L2_SUBDEV_ROUTE_FL_ACTIVE	(1 << 0)
+#define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE	(1 << 1)
+
+/**
+ * struct v4l2_subdev_route - A signal route inside a subdev
+ * @sink_pad: the sink pad
+ * @sink_stream: the sink stream
+ * @source_pad: the source pad
+ * @source_stream: the source stream
+ * @flags: route flags:
+ *
+ *	V4L2_SUBDEV_ROUTE_FL_ACTIVE: Is the stream in use or not? An
+ *	active stream will start when streaming is enabled on a video
+ *	node. Set by the user.
+ *
+ *	V4L2_SUBDEV_ROUTE_FL_IMMUTABLE: Is the stream immutable, i.e.
+ *	can it be activated and inactivated? Set by the driver.
+ */
+struct v4l2_subdev_route {
+	__u32 sink_pad;
+	__u32 sink_stream;
+	__u32 source_pad;
+	__u32 source_stream;
+	__u32 flags;
+	__u32 reserved[5];
+};
+
+/**
+ * struct v4l2_subdev_routing - Routing information
+ * @routes: the routes array
+ * @num_routes: the total number of routes in the routes array
+ */
+struct v4l2_subdev_routing {
+	struct v4l2_subdev_route *routes;
+	__u32 num_routes;
+	__u32 reserved[5];
+};
+
 /* Backwards compatibility define --- to be removed */
 #define v4l2_subdev_edid v4l2_edid
 
@@ -176,5 +215,7 @@ struct v4l2_subdev_selection {
 #define VIDIOC_SUBDEV_ENUM_DV_TIMINGS		_IOWR('V', 98, struct v4l2_enum_dv_timings)
 #define VIDIOC_SUBDEV_QUERY_DV_TIMINGS		_IOR('V', 99, struct v4l2_dv_timings)
 #define VIDIOC_SUBDEV_DV_TIMINGS_CAP		_IOWR('V', 100, struct v4l2_dv_timings_cap)
+#define VIDIOC_SUBDEV_G_ROUTING			_IOWR('V', 38, struct v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_S_ROUTING			_IOWR('V', 39, struct v4l2_subdev_routing)
 
 #endif
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC 2/2] v4l2-ctl: add ROUTING get and set options
  2017-12-14 19:09 [RFC 0/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund
  2017-12-14 19:09 ` [RFC 1/2] Synchronize with the Kernel headers for routing operations Niklas Söderlund
@ 2017-12-14 19:09 ` Niklas Söderlund
  1 sibling, 0 replies; 3+ messages in thread
From: Niklas Söderlund @ 2017-12-14 19:09 UTC (permalink / raw)
  To: linux-media, Sakari Ailus
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, Benoit Parrot, Maxime Ripard,
	Niklas Söderlund

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 utils/v4l2-ctl/Android.mk           |   2 +-
 utils/v4l2-ctl/Makefile.am          |   2 +-
 utils/v4l2-ctl/v4l2-ctl-routing.cpp | 154 ++++++++++++++++++++++++++++++++++++
 utils/v4l2-ctl/v4l2-ctl.cpp         |  10 +++
 utils/v4l2-ctl/v4l2-ctl.h           |   9 +++
 5 files changed, 175 insertions(+), 2 deletions(-)
 create mode 100644 utils/v4l2-ctl/v4l2-ctl-routing.cpp

diff --git a/utils/v4l2-ctl/Android.mk b/utils/v4l2-ctl/Android.mk
index 707895026f88962d..f83347e04ff477c7 100644
--- a/utils/v4l2-ctl/Android.mk
+++ b/utils/v4l2-ctl/Android.mk
@@ -21,5 +21,5 @@ LOCAL_SRC_FILES := \
     v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp v4l2-ctl-vidout.cpp \
     v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \
     v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \
-    v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c
+    v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-routing.cpp
 include $(BUILD_EXECUTABLE)
diff --git a/utils/v4l2-ctl/Makefile.am b/utils/v4l2-ctl/Makefile.am
index cae4e747a0afa047..69bf466e89bbf72e 100644
--- a/utils/v4l2-ctl/Makefile.am
+++ b/utils/v4l2-ctl/Makefile.am
@@ -6,7 +6,7 @@ v4l2_ctl_SOURCES = v4l2-ctl.cpp v4l2-ctl.h v4l2-ctl-common.cpp v4l2-ctl-tuner.cp
 	v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp v4l2-ctl-vidout.cpp \
 	v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \
 	v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \
-	v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-meta.cpp
+	v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-meta.cpp v4l2-ctl-routing.cpp
 v4l2_ctl_CPPFLAGS = -I$(top_srcdir)/utils/common
 
 if WITH_LIBV4L
diff --git a/utils/v4l2-ctl/v4l2-ctl-routing.cpp b/utils/v4l2-ctl/v4l2-ctl-routing.cpp
new file mode 100644
index 0000000000000000..55a2e44949785015
--- /dev/null
+++ b/utils/v4l2-ctl/v4l2-ctl-routing.cpp
@@ -0,0 +1,154 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include "v4l2-ctl.h"
+
+#include <linux/v4l2-subdev.h>
+
+/*
+ * The max value comes from a check in the kernel source code
+ * drivers/media/v4l2-core/v4l2-ioctl.c check_array_args()
+ */
+#define NUM_ROUTES_MAX 256
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+struct v4l2_subdev_routing routing;
+struct v4l2_subdev_route routes[NUM_ROUTES_MAX];
+
+struct flag_name {
+	__u32 flag;
+	const char *name;
+};
+
+static void print_flags(const struct flag_name *flag_names, unsigned int num_entries, __u32 flags)
+{
+	bool first = true;
+	unsigned int i;
+
+	for (i = 0; i < num_entries; i++) {
+		if (!(flags & flag_names[i].flag))
+			continue;
+		if (!first)
+			printf(",");
+		printf("%s", flag_names[i].name);
+		flags &= ~flag_names[i].flag;
+		first = false;
+	}
+
+	if (flags) {
+		if (!first)
+			printf(",");
+		printf("0x%x", flags);
+	}
+}
+
+static void print_routes(const struct v4l2_subdev_routing *r)
+{
+	unsigned int i;
+
+	static const struct flag_name route_flags[] = {
+		{ V4L2_SUBDEV_ROUTE_FL_ACTIVE, "ENABLED" },
+		{ V4L2_SUBDEV_ROUTE_FL_IMMUTABLE, "IMMUTABLE" },
+	};
+
+	for (i = 0; i < r->num_routes; i++) {
+		printf("%d/%d -> %d/%d [",
+		       r->routes[i].sink_pad, r->routes[i].sink_stream,
+		       r->routes[i].source_pad, r->routes[i].source_stream);
+		print_flags(route_flags, ARRAY_SIZE(route_flags), r->routes[i].flags);
+		printf("]\n");
+	}
+}
+
+void routing_usage(void)
+{
+	printf("\nRoute options:\n"
+	       "  --get-routing		Print the route topology\n"
+	       "  --set-routing routes	Comma-separated list of route descriptors to setup\n"
+	       "\n"
+	       "Routes are defined as\n"
+	       "	routes		= route { ',' route } ;\n"
+	       "	route		= sink '->' source '[' flags ']' ;\n"
+	       "	sink		= sink-pad '/' sink-stream ;\n"
+	       "	source		= source-pad '/' source-stream ;\n"
+	       "\n"
+	       "where the fields are\n"
+	       "	sink-pad	= Pad numeric identifier for sink\n"
+	       "	sink-stream	= Stream numeric identifier for sink\n"
+	       "	source-pad	= Pad numeric identifier for source\n"
+	       "	source-stream	= Stream numeric identifier for source\n"
+	       "	flags		= Route flags (0: inactive, 1: active)\n"
+	       );
+}
+
+/******************************************************/
+
+void routing_cmd(int ch, char *optarg)
+{
+	struct v4l2_subdev_route *r;
+	char *end, *ref, *tok;
+	unsigned int flags;
+
+	switch (ch) {
+	case OptSetRouting:
+		memset(&routing, 0, sizeof(routing));
+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
+		routing.num_routes = 0;
+		routing.routes = routes;
+
+		if (!optarg)
+			break;
+
+		r = routing.routes;
+		ref = end = strdup(optarg);
+		while ((tok = strsep(&end, ",")) != NULL) {
+			if (sscanf(tok, "%u/%u -> %u/%u [%u]",
+				   &r->sink_pad, &r->sink_stream,
+				   &r->source_pad, &r->source_stream,
+				   &flags) != 5 || (flags != 0 && flags != 1)) {
+				free(ref);
+				fprintf(stderr, "Invalid route information specified\n");
+				routing_usage();
+				exit(1);
+			}
+
+			if (flags == 1)
+				r->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
+
+			r++;
+			routing.num_routes++;
+		}
+		free(ref);
+
+		break;
+	}
+}
+
+void routing_set(int fd)
+{
+	if (options[OptSetRouting]) {
+		if (doioctl(fd, VIDIOC_SUBDEV_S_ROUTING, &routing) == 0)
+			printf("Routing set\n");
+	}
+}
+
+void routing_get(int fd)
+{
+	if (options[OptGetRouting]) {
+		memset(&routing, 0, sizeof(routing));
+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
+		routing.num_routes = NUM_ROUTES_MAX;
+		routing.routes = routes;
+
+		if (doioctl(fd, VIDIOC_SUBDEV_G_ROUTING, &routing) == 0)
+			print_routes(&routing);
+	}
+}
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index e02dc7563e50bd1d..718d5d175fd86364 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -87,6 +87,7 @@ static struct option long_options[] = {
 	{"help-misc", no_argument, 0, OptHelpMisc},
 	{"help-streaming", no_argument, 0, OptHelpStreaming},
 	{"help-edid", no_argument, 0, OptHelpEdid},
+	{"help-routing", no_argument, 0, OptHelpRouting},
 	{"help-all", no_argument, 0, OptHelpAll},
 #ifndef NO_LIBV4L2
 	{"wrapper", no_argument, 0, OptUseWrapper},
@@ -210,6 +211,8 @@ static struct option long_options[] = {
 	{"get-edid", optional_argument, 0, OptGetEdid},
 	{"info-edid", optional_argument, 0, OptInfoEdid},
 	{"fix-edid-checksums", no_argument, 0, OptFixEdidChecksums},
+	{"set-routing", required_argument, 0, OptSetRouting},
+	{"get-routing", no_argument, 0, OptGetRouting},
 	{"tuner-index", required_argument, 0, OptTunerIndex},
 	{"list-buffers", no_argument, 0, OptListBuffers},
 	{"list-buffers-out", no_argument, 0, OptListBuffersOut},
@@ -271,6 +274,7 @@ static void usage_all(void)
        misc_usage();
        streaming_usage();
        edid_usage();
+       routing_usage();
 }
 
 static int test_open(const char *file, int oflag)
@@ -1286,6 +1290,9 @@ int main(int argc, char **argv)
 		case OptHelpEdid:
 			edid_usage();
 			return 0;
+		case OptHelpRouting:
+			routing_usage();
+			return 0;
 		case OptHelpAll:
 			usage_all();
 			return 0;
@@ -1345,6 +1352,7 @@ int main(int argc, char **argv)
 			misc_cmd(ch, optarg);
 			streaming_cmd(ch, optarg);
 			edid_cmd(ch, optarg);
+			routing_cmd(ch, optarg);
 			break;
 		}
 	}
@@ -1484,6 +1492,7 @@ int main(int argc, char **argv)
 	streaming_set(fd, out_fd);
 	misc_set(fd);
 	edid_set(fd);
+	routing_set(fd);
 
 	/* Get options */
 
@@ -1500,6 +1509,7 @@ int main(int argc, char **argv)
 	selection_get(fd);
 	misc_get(fd);
 	edid_get(fd);
+	routing_get(fd);
 
 	/* List options */
 
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index 3b56d8a6cd6c3852..f1051ec61695b106 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -157,6 +157,8 @@ enum Option {
 	OptGetEdid,
 	OptInfoEdid,
 	OptFixEdidChecksums,
+	OptSetRouting,
+	OptGetRouting,
 	OptFreqSeek,
 	OptEncoderCmd,
 	OptTryEncoderCmd,
@@ -215,6 +217,7 @@ enum Option {
 	OptHelpMisc,
 	OptHelpStreaming,
 	OptHelpEdid,
+	OptHelpRouting,
 	OptHelpAll,
 	OptLast = 512
 };
@@ -371,6 +374,12 @@ void edid_cmd(int ch, char *optarg);
 void edid_set(int fd);
 void edid_get(int fd);
 
+// v4l2-ctl-routing.cpp
+void routing_usage(void);
+void routing_cmd(int ch, char *optarg);
+void routing_set(int fd);
+void routing_get(int fd);
+
 /* v4l2-ctl-modes.cpp */
 bool calc_cvt_modeline(int image_width, int image_height,
 		       int refresh_rate, int reduced_blanking,
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-12-14 19:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-14 19:09 [RFC 0/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund
2017-12-14 19:09 ` [RFC 1/2] Synchronize with the Kernel headers for routing operations Niklas Söderlund
2017-12-14 19:09 ` [RFC 2/2] v4l2-ctl: add ROUTING get and set options Niklas Söderlund

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.