diff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp
index da835be..1c6f34d 100644
--- a/src/ipa/libipa/awb.cpp
+++ b/src/ipa/libipa/awb.cpp
@@ -526,6 +526,11 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData,
  * Minimum gain value used to clamp the AWB algorithm calculation results in the
  * range supported by the platform AWB engine.
  *
+ * The minimum defaults to 1.0: gains below 1.0 attenuate a colour channel,
+ * which is normally undesirable. On platforms whose gain range goes below
+ * 1.0, the "gainMin" tuning file property may lower the limit, within the
+ * range supported by the platform AWB engine.
+ *
  * The min and max gain values are initialized by AwbAlgorithm::init().
  */
 
diff --git a/src/ipa/libipa/awb.h b/src/ipa/libipa/awb.h
index d35a851..9d6fa3c 100644
--- a/src/ipa/libipa/awb.h
+++ b/src/ipa/libipa/awb.h
@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include <algorithm>
 #include <array>
 #include <map>
 #include <optional>
@@ -117,7 +118,20 @@ public:
 	{
 		AwbAlgorithmBase::init(tuningData);
 
-		gainMin_ = std::max(Q::TraitsType::min, 1.0f);
+		/*
+		 * Gains are not allowed to go below 1.0 by default: attenuating
+		 * a colour channel discards part of its dynamic range, so
+		 * balancing by amplifying the other channels is normally
+		 * preferable. Some camera modules are however calibrated with
+		 * a white point that requires attenuating a channel, which
+		 * platforms whose AWB gains can go below 1.0 (such as the
+		 * software ISP) are able to apply. Let the tuning file lower
+		 * the limit with the "gainMin" property, within the platform's
+		 * gain range.
+		 */
+		float gainMin = tuningData["gainMin"].get<float>(1.0f);
+		gainMin_ = std::clamp(gainMin, Q::TraitsType::min,
+				      Q::TraitsType::max);
 		gainMax_ = Q::TraitsType::max;
 
 		controls_[&controls::ColourGains] =
