summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhi-Bang Nguyen <pnguyen@baylibre.com>2021-02-11 16:26:37 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-11-19 22:37:12 +0200
commit0567d3ad75422c99e574a351dafb4f7a7447e0fe (patch)
treea9a72ff4360e3b73be0b91d65c806c89bf77c50e
parent1459930de57920b5161fee2662f9604de91b9de5 (diff)
libcamera: v4l2_subdevice: Add VIDIOC_SUBDEV_G_ROUTING ioctl
Signed-off-by: Phi-Bang Nguyen <pnguyen@baylibre.com>
-rw-r--r--include/libcamera/internal/v4l2_subdevice.h5
-rw-r--r--src/libcamera/v4l2_subdevice.cpp40
2 files changed, 45 insertions, 0 deletions
diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h
index 97b89fb9..7281b4bc 100644
--- a/include/libcamera/internal/v4l2_subdevice.h
+++ b/include/libcamera/internal/v4l2_subdevice.h
@@ -11,6 +11,8 @@
#include <string>
#include <vector>
+#include <linux/v4l2-subdev.h>
+
#include <libcamera/base/class.h>
#include <libcamera/base/log.h>
@@ -61,6 +63,9 @@ public:
int setFormat(unsigned int pad, V4L2SubdeviceFormat *format,
Whence whence = ActiveFormat);
+ int getRouting(std::vector<struct v4l2_subdev_route> *routes,
+ Whence whence = ActiveFormat);
+
static std::unique_ptr<V4L2Subdevice>
fromEntityName(const MediaDevice *media, const std::string &entity);
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index 023e2328..a0cc5eb4 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -443,6 +443,46 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format,
}
/**
+ * \brief Retrieve the subdevice's internal routing table
+ * \param[out] routes The routing table
+ * \param[in] whence The routing table to get, \ref V4L2Subdevice::ActiveFormat
+ * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat"
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int V4L2Subdevice::getRouting(std::vector<struct v4l2_subdev_route> *routes,
+ Whence whence)
+{
+ struct v4l2_subdev_routing rt = {};
+
+ rt.which = whence == ActiveFormat ? V4L2_SUBDEV_FORMAT_ACTIVE
+ : V4L2_SUBDEV_FORMAT_TRY;
+
+ int ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt);
+ if (ret == 0 || ret == -ENOTTY)
+ return ret;
+
+ if (ret != -ENOSPC) {
+ LOG(V4L2, Error)
+ << "Failed to retrieve number of routes: "
+ << strerror(-ret);
+ return ret;
+ }
+
+ routes->resize(rt.num_routes);
+ rt.routes = reinterpret_cast<uintptr_t>(routes->data());
+
+ ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt);
+ if (ret) {
+ LOG(V4L2, Error)
+ << "Failed to retrieve routes: " << strerror(-ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
* \brief Create a new video subdevice instance from \a entity in media device
* \a media
* \param[in] media The media device where the entity is registered