diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index b1b73367e874..458b84e8fa8c 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -114,10 +114,12 @@ class ControlRange
 {
 public:
 	explicit ControlRange(const ControlValue &min = 0,
-			      const ControlValue &max = 0);
+			      const ControlValue &max = 0,
+			      const ControlValue &def = 0);
 
 	const ControlValue &min() const { return min_; }
 	const ControlValue &max() const { return max_; }
+	const ControlValue &def() const { return def_; }
 
 	std::string toString() const;
 
@@ -134,6 +136,7 @@ public:
 private:
 	ControlValue min_;
 	ControlValue max_;
+	ControlValue def_;
 };
 
 using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 7d8a0e97ee3a..1678d3cba4f3 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -353,14 +353,21 @@ Control<int64_t>::Control(unsigned int id, const char *name)
  * pipeline handlers to describe the controls they support.
  */
 
+/**
+ * \var ControlRange::def_
+ * \brief The control default value
+ */
+
 /**
  * \brief Construct a ControlRange with minimum and maximum range parameters
  * \param[in] min The control minimum value
  * \param[in] max The control maximum value
+ * \param[in] def The control default value
  */
 ControlRange::ControlRange(const ControlValue &min,
-			   const ControlValue &max)
-	: min_(min), max_(max)
+			   const ControlValue &max,
+			   const ControlValue &def)
+	: min_(min), max_(max), def_(def)
 {
 }
 
@@ -376,6 +383,12 @@ ControlRange::ControlRange(const ControlValue &min,
  * \return A ControlValue with the maximum value for the control
  */
 
+/**
+ * \fn ControlRange::def()
+ * \brief Retrieve the default value of the control
+ * \return A ControlValue with the default value for the control
+ */
+
 /**
  * \brief Provide a string representation of the ControlRange
  */
