diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom
index ba786e647ca1..1ea51f99e2bb 100644
--- a/include/libcamera/ipa/raspberrypi.mojom
+++ b/include/libcamera/ipa/raspberrypi.mojom
@@ -21,6 +21,7 @@ struct SensorConfig {
 
 struct InitParams {
 	bool lensPresent;
+	libcamera.IPACameraSensorInfo sensorInfo;
 };
 
 struct InitResult {
diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
index db7a0eb3a1ca..7fe8ee738e01 100644
--- a/src/ipa/rpi/common/ipa_base.cpp
+++ b/src/ipa/rpi/common/ipa_base.cpp
@@ -12,6 +12,7 @@
 #include <libcamera/base/log.h>
 #include <libcamera/base/span.h>
 #include <libcamera/control_ids.h>
+#include <libcamera/property_ids.h>
 
 #include "controller/af_algorithm.h"
 #include "controller/af_status.h"
@@ -60,19 +61,22 @@ const ControlInfoMap::Map ipaControls{
 	{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
 	{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },
 	{ &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },
-	{ &controls::AwbEnable, ControlInfo(false, true) },
-	{ &controls::ColourGains, ControlInfo(0.0f, 32.0f) },
-	{ &controls::AwbMode, ControlInfo(controls::AwbModeValues) },
 	{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
 	{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
-	{ &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },
 	{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
-	{ &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },
 	{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
 	{ &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
 	{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }
 };
 
+/* IPA controls handled conditionally, if the sensor is not mono */
+const ControlInfoMap::Map ipaColourControls{
+	{ &controls::AwbEnable, ControlInfo(false, true) },
+	{ &controls::AwbMode, ControlInfo(controls::AwbModeValues) },
+	{ &controls::ColourGains, ControlInfo(0.0f, 32.0f) },
+	{ &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },
+};
+
 /* IPA controls handled conditionally, if the lens has a focus control */
 const ControlInfoMap::Map ipaAfControls{
 	{ &controls::AfMode, ControlInfo(controls::AfModeValues) },
@@ -146,6 +150,11 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams &params, Ini
 	ControlInfoMap::Map ctrlMap = ipaControls;
 	if (lensPresent_)
 		ctrlMap.merge(ControlInfoMap::Map(ipaAfControls));
+
+	monoSensor_ = params.sensorInfo.cfaPattern == properties::draft::ColorFilterArrangementEnum::MONO;
+	if (!monoSensor_)
+		ctrlMap.merge(ControlInfoMap::Map(ipaColourControls));
+
 	result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);
 
 	return platformInit(params, result);
@@ -220,6 +229,10 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
 		ControlInfo(static_cast<int32_t>(mode_.minShutter.get<std::micro>()),
 			    static_cast<int32_t>(mode_.maxShutter.get<std::micro>()));
 
+	/* Declare colour processing related controls for non-mono sensors. */
+	if (!monoSensor_)
+		ctrlMap.merge(ControlInfoMap::Map(ipaColourControls));
+
 	/* Declare Autofocus controls, only if we have a controllable lens */
 	if (lensPresent_)
 		ctrlMap.merge(ControlInfoMap::Map(ipaAfControls));
@@ -780,6 +793,10 @@ void IpaBase::applyControls(const ControlList &controls)
 		}
 
 		case controls::AWB_ENABLE: {
+			/* Silently ignore this control for a mono sensor. */
+			if (monoSensor_)
+				break;
+
 			RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
 				controller_.getAlgorithm("awb"));
 			if (!awb) {
@@ -799,6 +816,10 @@ void IpaBase::applyControls(const ControlList &controls)
 		}
 
 		case controls::AWB_MODE: {
+			/* Silently ignore this control for a mono sensor. */
+			if (monoSensor_)
+				break;
+
 			RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
 				controller_.getAlgorithm("awb"));
 			if (!awb) {
@@ -819,6 +840,10 @@ void IpaBase::applyControls(const ControlList &controls)
 		}
 
 		case controls::COLOUR_GAINS: {
+			/* Silently ignore this control for a mono sensor. */
+			if (monoSensor_)
+				break;
+
 			auto gains = ctrl.second.get<Span<const float>>();
 			RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
 				controller_.getAlgorithm("awb"));
@@ -867,6 +892,10 @@ void IpaBase::applyControls(const ControlList &controls)
 		}
 
 		case controls::SATURATION: {
+			/* Silently ignore this control for a mono sensor. */
+			if (monoSensor_)
+				break;
+
 			RPiController::CcmAlgorithm *ccm = dynamic_cast<RPiController::CcmAlgorithm *>(
 				controller_.getAlgorithm("ccm"));
 			if (!ccm) {
diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h
index 6f9c46bb16b1..39d00760d012 100644
--- a/src/ipa/rpi/common/ipa_base.h
+++ b/src/ipa/rpi/common/ipa_base.h
@@ -87,6 +87,7 @@ private:
 	std::map<unsigned int, MappedFrameBuffer> buffers_;
 
 	bool lensPresent_;
+	bool monoSensor_;
 	ControlList libcameraMetadata_;
 
 	std::array<RPiController::Metadata, numMetadataContexts> rpiMetadata_;
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index 3bb5ec531e4f..3aef1f43d697 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -1130,6 +1130,8 @@ int CameraData::loadPipelineConfiguration()
 
 int CameraData::loadIPA(ipa::RPi::InitResult *result)
 {
+	int ret;
+
 	ipa_ = IPAManager::createIPA<ipa::RPi::IPAProxyRPi>(pipe(), 1, 1);
 
 	if (!ipa_)
@@ -1153,8 +1155,14 @@ int CameraData::loadIPA(ipa::RPi::InitResult *result)
 	IPASettings settings(configurationFile, sensor_->model());
 	ipa::RPi::InitParams params;
 
+	ret = sensor_->sensorInfo(&params.sensorInfo);
+	if (ret) {
+		LOG(RPI, Error) << "Failed to retrieve camera sensor info";
+		return ret;
+	}
+
 	params.lensPresent = !!sensor_->focusLens();
-	int ret = platformInitIpa(params);
+	ret = platformInitIpa(params);
 	if (ret)
 		return ret;
 
