aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2019-03-01 14:49:58 (GMT)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2019-03-01 14:49:58 (GMT)
commit46d2b342ce44f8c9266375126f61ab34285e95c2 (patch)
treed146017fcd9dfc369e98a1f0dd88332999b53224
parent410942e345b889d09456f5f862ee6cd415d8ae59 (diff)
v4l2-ctl: --list-devices can now be combined with -z
Using '-z media-bus-info --list-devices' will show all devices as specified in the media topology of the media device with the given bus info. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-common.cpp74
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.1.in4
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.cpp2
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.h2
4 files changed, 76 insertions, 6 deletions
diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp
index 11fe602..09901f1 100644
--- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
@@ -10,6 +10,7 @@
#include <ctype.h>
#include <errno.h>
#include <sys/ioctl.h>
+#include <sys/sysmacros.h>
#include <sys/time.h>
#include <dirent.h>
#include <math.h>
@@ -109,7 +110,9 @@ void common_usage(void)
#ifndef NO_LIBV4L2
" -w, --wrapper use the libv4l2 wrapper library.\n"
#endif
- " --list-devices list all v4l devices\n"
+ " --list-devices list all v4l devices. If -z was given, then list just the\n"
+ " devices of the media device with the bus info string as\n"
+ " specified by the -z option.\n"
" --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"
" --get-priority query the current access priority [VIDIOC_G_PRIORITY]\n"
" --set-priority <prio>\n"
@@ -171,6 +174,68 @@ static bool sort_on_device_name(const std::string &s1, const std::string &s2)
return n1 < n2;
}
+static void list_media_devices(const std::string &media_bus_info)
+{
+ DIR *dp;
+ struct dirent *ep;
+ int media_fd = -1;
+ std::map<dev_t, std::string> devices;
+
+ dp = opendir("/dev");
+ if (dp == NULL) {
+ perror ("Couldn't open the directory");
+ return;
+ }
+ while ((ep = readdir(dp))) {
+ std::string s("/dev/");
+
+ s += ep->d_name;
+ if (memcmp(ep->d_name, "media", 5)) {
+ if (!is_v4l_dev(ep->d_name))
+ continue;
+ struct stat st;
+ if (stat(s.c_str(), &st))
+ continue;
+ devices[st.st_rdev] = s;
+ continue;
+ }
+ int fd = open(s.c_str(), O_RDWR);
+
+ if (fd < 0)
+ continue;
+ struct media_device_info mdi;
+
+ if (!ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi) &&
+ media_bus_info == mdi.bus_info)
+ media_fd = fd;
+ else
+ close(fd);
+ }
+ closedir(dp);
+ if (media_fd < 0)
+ return;
+
+ media_v2_topology topology;
+ memset(&topology, 0, sizeof(topology));
+ if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology)) {
+ close(media_fd);
+ return;
+ }
+
+ media_v2_interface *ifaces = new media_v2_interface[topology.num_interfaces];
+ topology.ptr_interfaces = (__u64)ifaces;
+
+ if (!ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology))
+ for (unsigned i = 0; i < topology.num_interfaces; i++) {
+ dev_t dev = makedev(ifaces[i].devnode.major,
+ ifaces[i].devnode.minor);
+
+ if (devices.find(dev) != devices.end())
+ printf("%s\n", devices[dev].c_str());
+ }
+ close(media_fd);
+}
+
static void list_devices()
{
DIR *dp;
@@ -727,7 +792,7 @@ static bool parse_next_subopt(char **subs, char **value)
return true;
}
-void common_cmd(int ch, char *optarg)
+void common_cmd(const std::string &media_bus_info, int ch, char *optarg)
{
char *value, *subs;
@@ -774,7 +839,10 @@ void common_cmd(int ch, char *optarg)
prio = (enum v4l2_priority)strtoul(optarg, 0L, 0);
break;
case OptListDevices:
- list_devices();
+ if (media_bus_info.empty())
+ list_devices();
+ else
+ list_media_devices(media_bus_info);
break;
}
}
diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in
index f37d6e3..e9fff78 100644
--- a/utils/v4l2-ctl/v4l2-ctl.1.in
+++ b/utils/v4l2-ctl/v4l2-ctl.1.in
@@ -122,7 +122,9 @@ The subset of the N-dimensional array to get/set for control \fI<ctrl>\fR,
for every dimension an (\fI<offset>\fR, \fI<size>\fR) tuple is given.
.TP
\fB--list-devices\fR
-List all v4l devices.
+List all v4l devices. If \fB-z\fR was given, then list just the
+devices of the media device with the bus info string as
+specified by the \fB-z\fR option.
.TP
\fB--log-status\fR
Log the board status in the kernel log [VIDIOC_LOG_STATUS].
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index cbe31c8..6cacc57 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -1221,7 +1221,7 @@ int main(int argc, char **argv)
common_usage();
return 1;
default:
- common_cmd(ch, optarg);
+ common_cmd(media_bus_info, ch, optarg);
tuner_cmd(ch, optarg);
io_cmd(ch, optarg);
stds_cmd(ch, optarg);
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index f4170e7..9292c15 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -324,7 +324,7 @@ void print_video_formats_ext(cv4l_fd &fd, __u32 type);
// v4l2-ctl-common.cpp
void common_usage(void);
-void common_cmd(int ch, char *optarg);
+void common_cmd(const std::string &media_bus_info, int ch, char *optarg);
void common_set(cv4l_fd &fd);
void common_get(cv4l_fd &fd);
void common_list(cv4l_fd &fd);

Privacy Policy