diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index d8acd800b143..342251c21018 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -40,6 +40,12 @@ public:
 
 	std::string toString() const;
 
+	bool operator==(const ControlValue &other) const;
+	bool operator!=(const ControlValue &other) const
+	{
+		return !(*this == other);
+	}
+
 private:
 	ControlType type_;
 
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 70c1af481af2..bfab177fc508 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -194,6 +194,33 @@ std::string ControlValue::toString() const
 	return "<ValueType Error>";
 }
 
+/**
+ * \brief Compare ControlValue instances for equality
+ * \return True if the values have identical types and values, false otherwise
+ */
+bool ControlValue::operator==(const ControlValue &other) const
+{
+	if (type_ != other.type_)
+		return false;
+
+	switch (type_) {
+	case ControlTypeBool:
+		return bool_ == other.bool_;
+	case ControlTypeInteger32:
+		return integer32_ == other.integer32_;
+	case ControlTypeInteger64:
+		return integer64_ == other.integer64_;
+	default:
+		return false;
+	}
+}
+
+/**
+ * \fn bool ControlValue::operator!=()
+ * \brief Compare ControlValue instances for non equality
+ * \return False if the values have identical types and values, true otherwise
+ */
+
 /**
  * \class ControlId
  * \brief Control static metadata
