diff --git a/src/ipa/softisp/algorithms/adjust.cpp b/src/ipa/softisp/algorithms/adjust.cpp
index 56e2cf0e8..0cba321f1 100644
--- a/src/ipa/softisp/algorithms/adjust.cpp
+++ b/src/ipa/softisp/algorithms/adjust.cpp
@@ -8,6 +8,8 @@
 
 #include "adjust.h"
 
+#include <errno.h>
+
 #include <libcamera/base/log.h>
 #include <libcamera/base/utils.h>
 
@@ -19,17 +21,34 @@ namespace libcamera {
 
 namespace ipa::softisp::algorithms {
 
-constexpr float kDefaultContrast = 1.0f;
 constexpr float kDefaultSaturation = 1.0f;
 
+constexpr float kMinContrast = 0.0f;
+constexpr float kMaxContrast = 2.0f;
+
 LOG_DEFINE_CATEGORY(IPASoftIspAdjust)
 
-int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData)
+int Adjust::init(IPAContext &context, const ValueNode &tuningData)
 {
+	const ValueNode &contrastNode = tuningData["contrast"];
+	const std::optional<float> contrast = contrastNode.get<float>();
+	if (contrastNode && !contrast) {
+		LOG(IPASoftIspAdjust, Error) << "Failed to parse contrast";
+		return -EINVAL;
+	}
+
+	defaultContrast_ = contrast.value_or(kDefaultContrast);
+	if (!(defaultContrast_ >= kMinContrast && defaultContrast_ <= kMaxContrast)) {
+		LOG(IPASoftIspAdjust, Error)
+			<< "contrast must be in the range [" << kMinContrast
+			<< ", " << kMaxContrast << "]";
+		return -EINVAL;
+	}
+
 	context.ctrlMap[&controls::Gamma] =
 		ControlInfo(0.1f, 10.0f, kDefaultGamma);
 	context.ctrlMap[&controls::Contrast] =
-		ControlInfo(0.0f, 2.0f, kDefaultContrast);
+		ControlInfo(kMinContrast, kMaxContrast, defaultContrast_);
 	if (context.ccmEnabled)
 		context.ctrlMap[&controls::Saturation] =
 			ControlInfo(0.0f, 2.0f, kDefaultSaturation);
@@ -40,7 +59,7 @@ int Adjust::configure(IPAContext &context,
 		      [[maybe_unused]] const IPAConfigInfo &configInfo)
 {
 	context.activeState.knobs.gamma = kDefaultGamma;
-	context.activeState.knobs.contrast = std::optional<float>();
+	context.activeState.knobs.contrast = defaultContrast_;
 	context.activeState.knobs.saturation = std::optional<float>();
 
 	return 0;
@@ -59,7 +78,7 @@ void Adjust::queueRequest(typename Module::Context &context,
 
 	const auto &contrast = controls.get(controls::Contrast);
 	if (contrast.has_value()) {
-		context.activeState.knobs.contrast = contrast;
+		context.activeState.knobs.contrast = contrast.value();
 		LOG(IPASoftIspAdjust, Debug) << "Setting contrast to " << contrast.value();
 	}
 
@@ -107,7 +126,7 @@ void Adjust::prepare(IPAContext &context,
 	}
 
 	params->gamma = 1.0 / context.activeState.knobs.gamma;
-	const float contrast = context.activeState.knobs.contrast.value_or(kDefaultContrast);
+	const float contrast = context.activeState.knobs.contrast;
 	params->contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001));
 }
 
@@ -120,8 +139,7 @@ void Adjust::process([[maybe_unused]] IPAContext &context,
 	const auto &gamma = frameContext.gamma;
 	metadata.set(controls::Gamma, gamma);
 
-	const auto &contrast = frameContext.contrast;
-	metadata.set(controls::Contrast, contrast.value_or(kDefaultContrast));
+	metadata.set(controls::Contrast, frameContext.contrast);
 
 	const auto &saturation = frameContext.saturation;
 	metadata.set(controls::Saturation, saturation.value_or(kDefaultSaturation));
diff --git a/src/ipa/softisp/algorithms/adjust.h b/src/ipa/softisp/algorithms/adjust.h
index 1acf7cdf1..726e24cfc 100644
--- a/src/ipa/softisp/algorithms/adjust.h
+++ b/src/ipa/softisp/algorithms/adjust.h
@@ -18,6 +18,7 @@ namespace libcamera {
 namespace ipa::softisp::algorithms {
 
 constexpr float kDefaultGamma = 2.2f;
+constexpr float kDefaultContrast = 1.0f;
 
 class Adjust : public Algorithm
 {
@@ -43,6 +44,8 @@ public:
 
 private:
 	void applySaturation(Matrix<float, 3, 3> &ccm, float saturation);
+
+	float defaultContrast_ = kDefaultContrast;
 };
 
 } /* namespace ipa::softisp::algorithms */
diff --git a/src/ipa/softisp/ipa_context.h b/src/ipa/softisp/ipa_context.h
index 397e6c99b..6c1a517d1 100644
--- a/src/ipa/softisp/ipa_context.h
+++ b/src/ipa/softisp/ipa_context.h
@@ -52,7 +52,7 @@ struct IPAActiveState {
 	struct {
 		float gamma;
 		/* 0..2 range, 1.0 = normal */
-		std::optional<float> contrast;
+		float contrast;
 		std::optional<float> saturation;
 	} knobs;
 };
@@ -68,7 +68,7 @@ struct IPAFrameContext : public FrameContext {
 	} sensor;
 
 	float gamma;
-	std::optional<float> contrast;
+	float contrast;
 	std::optional<float> saturation;
 };
 
