diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index ddec611f..44198c2c 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -173,6 +173,42 @@ readConstraintModes(std::map<std::string, AgcConstraintMode> &constraintModes,
 	return { 0, first };
 }
 
+int AgcChannelConstraint::read(const libcamera::YamlObject &params)
+{
+	std::string boundString = params["bound"].get<std::string>("");
+	transform(boundString.begin(), boundString.end(),
+		  boundString.begin(), ::toupper);
+	if (boundString != "UPPER" && boundString != "LOWER") {
+		LOG(RPiAgc, Error) << "AGC channelconstraint type should be UPPER or LOWER";
+		return -EINVAL;
+	}
+	bound = boundString == "UPPER" ? Bound::UPPER : Bound::LOWER;
+
+	auto value = params["factor"].get<double>();
+	if (!value)
+		return -EINVAL;
+	factor = *value;
+
+	return 0;
+}
+
+static int readChannelConstraints(std::vector<AgcChannelConstraint> &channelConstraints,
+				  const libcamera::YamlObject &params)
+{
+	int ret = 0;
+
+	for (const auto &p : params.asList()) {
+		AgcChannelConstraint constraint;
+		ret = constraint.read(p);
+		if (ret)
+			return ret;
+
+		channelConstraints.push_back(constraint);
+	}
+
+	return ret;
+}
+
 int AgcConfig::read(const libcamera::YamlObject &params)
 {
 	LOG(RPiAgc, Debug) << "AgcConfig";
@@ -191,6 +227,12 @@ int AgcConfig::read(const libcamera::YamlObject &params)
 	if (ret)
 		return ret;
 
+	if (params.contains("channel_constraints")) {
+		ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
+		if (ret)
+			return ret;
+	}
+
 	ret = yTarget.read(params["y_target"]);
 	if (ret)
 		return ret;
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
index 0e3d44b0..446125ef 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.h
+++ b/src/ipa/rpi/controller/rpi/agc_channel.h
@@ -42,11 +42,21 @@ struct AgcConstraint {
 
 typedef std::vector<AgcConstraint> AgcConstraintMode;
 
+struct AgcChannelConstraint {
+	enum class Bound { LOWER = 0,
+			   UPPER = 1 };
+	Bound bound;
+	unsigned int channel;
+	double factor;
+	int read(const libcamera::YamlObject &params);
+};
+
 struct AgcConfig {
 	int read(const libcamera::YamlObject &params);
 	std::map<std::string, AgcMeteringMode> meteringModes;
 	std::map<std::string, AgcExposureMode> exposureModes;
 	std::map<std::string, AgcConstraintMode> constraintModes;
+	std::vector<AgcChannelConstraint> channelConstraints;
 	Pwl yTarget;
 	double speed;
 	uint16_t startupFrames;
