From 34d7b4776b00979f28c9176dc9aea30c52d48c42 Mon Sep 17 00:00:00 2001
From: Paul Elder <paul.elder@ideasonboard.com>
Date: Tue, 26 Nov 2024 00:16:56 +0900
Subject: libcamera: controls: Add support for querying direction information

Add support to ControlId for querying direction information. This allows
applications to query whether a ControlId is meant for being set in
controls or to be returned in metadata or both. This also has a side
effect of properly encoding this information, as previously it was only
mentioned losely and inconsistently in the control id definition.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/controls.h         | 20 ++++++++++++++++++--
 include/libcamera/ipa/ipa_controls.h |  3 ++-
 2 files changed, 20 insertions(+), 3 deletions(-)

(limited to 'include')

diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index b24336cc..7c7828ae 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include <libcamera/base/class.h>
+#include <libcamera/base/flags.h>
 #include <libcamera/base/span.h>
 
 #include <libcamera/geometry.h>
@@ -249,14 +250,25 @@ private:
 class ControlId
 {
 public:
+	enum class Direction {
+		In = (1 << 0),
+		Out = (1 << 1),
+	};
+
+	using DirectionFlags = Flags<Direction>;
+
 	ControlId(unsigned int id, const std::string &name, const std::string &vendor,
-		  ControlType type, std::size_t size = 0,
+		  ControlType type, DirectionFlags direction,
+		  std::size_t size = 0,
 		  const std::map<std::string, int32_t> &enumStrMap = {});
 
 	unsigned int id() const { return id_; }
 	const std::string &name() const { return name_; }
 	const std::string &vendor() const { return vendor_; }
 	ControlType type() const { return type_; }
+	DirectionFlags direction() const { return direction_; }
+	bool isInput() const { return !!(direction_ & Direction::In); }
+	bool isOutput() const { return !!(direction_ & Direction::Out); }
 	bool isArray() const { return size_ > 0; }
 	std::size_t size() const { return size_; }
 	const std::map<int32_t, std::string> &enumerators() const { return reverseMap_; }
@@ -268,11 +280,14 @@ private:
 	std::string name_;
 	std::string vendor_;
 	ControlType type_;
+	DirectionFlags direction_;
 	std::size_t size_;
 	std::map<std::string, int32_t> enumStrMap_;
 	std::map<int32_t, std::string> reverseMap_;
 };
 
+LIBCAMERA_FLAGS_ENABLE_OPERATORS(ControlId::Direction)
+
 static inline bool operator==(unsigned int lhs, const ControlId &rhs)
 {
 	return lhs == rhs.id();
@@ -300,9 +315,10 @@ public:
 	using type = T;
 
 	Control(unsigned int id, const char *name, const char *vendor,
+		ControlId::DirectionFlags direction,
 		const std::map<std::string, int32_t> &enumStrMap = {})
 		: ControlId(id, name, vendor, details::control_type<std::remove_cv_t<T>>::value,
-			    details::control_type<std::remove_cv_t<T>>::size, enumStrMap)
+			    direction, details::control_type<std::remove_cv_t<T>>::size, enumStrMap)
 	{
 	}
 
diff --git a/include/libcamera/ipa/ipa_controls.h b/include/libcamera/ipa/ipa_controls.h
index 5fd13394..980668c8 100644
--- a/include/libcamera/ipa/ipa_controls.h
+++ b/include/libcamera/ipa/ipa_controls.h
@@ -46,7 +46,8 @@ struct ipa_control_info_entry {
 	uint32_t id;
 	uint32_t type;
 	uint32_t offset;
-	uint32_t padding[1];
+	uint8_t direction;
+	uint8_t padding[3];
 };
 
 #ifdef __cplusplus
-- 
cgit v1.2.1