diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 0c4519de..49fe8fb1 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -474,11 +474,12 @@ bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg)
 	StreamConfiguration config;
 
 	config = cfg;
-	if (data_->mainPath_->validate(sensor, &config) != Valid)
+	if (data_->mainPath_->validate(sensor, sensorConfig, &config) != Valid)
 		return false;
 
 	config = cfg;
-	if (data_->selfPath_ && data_->selfPath_->validate(sensor, &config) != Valid)
+	if (data_->selfPath_ &&
+	    data_->selfPath_->validate(sensor, sensorConfig, &config) != Valid)
 		return false;
 
 	return true;
@@ -495,6 +496,31 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 
 	status = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace);
 
+	/*
+	 * Make sure that if a sensor configuration has been requested it
+	 * is valid.
+	 */
+	if (sensorConfig && !sensorConfig->isValid()) {
+		LOG(RkISP1, Error) << "Invalid sensor configuration request";
+		return Invalid;
+	}
+
+	if (sensorConfig) {
+		std::optional<unsigned int> bitDepth = sensorConfig->bitDepth;
+		if (bitDepth != 8 && bitDepth != 10 && bitDepth != 12) {
+			/*
+			 * Default to the first supported bit depth, if an
+			 * unsupported one is supplied.
+			 */
+			V4L2SubdeviceFormat format = {};
+			format.code = sensor->mbusCodes().at(0);
+
+			sensorConfig->bitDepth =
+				MediaBusFormatInfo::info(format.code).bitsPerPixel;
+			status = Adjusted;
+		}
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > pathCount) {
 		config_.resize(pathCount);
@@ -540,7 +566,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 		/* Try to match stream without adjusting configuration. */
 		if (mainPathAvailable) {
 			StreamConfiguration tryCfg = cfg;
-			if (data_->mainPath_->validate(sensor, &tryCfg) == Valid) {
+			if (data_->mainPath_->validate(sensor, sensorConfig, &tryCfg) == Valid) {
 				mainPathAvailable = false;
 				cfg = tryCfg;
 				cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_));
@@ -550,7 +576,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 
 		if (selfPathAvailable) {
 			StreamConfiguration tryCfg = cfg;
-			if (data_->selfPath_->validate(sensor, &tryCfg) == Valid) {
+			if (data_->selfPath_->validate(sensor, sensorConfig, &tryCfg) == Valid) {
 				selfPathAvailable = false;
 				cfg = tryCfg;
 				cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_));
@@ -561,7 +587,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 		/* Try to match stream allowing adjusting configuration. */
 		if (mainPathAvailable) {
 			StreamConfiguration tryCfg = cfg;
-			if (data_->mainPath_->validate(sensor, &tryCfg) == Adjusted) {
+			if (data_->mainPath_->validate(sensor, sensorConfig, &tryCfg) == Adjusted) {
 				mainPathAvailable = false;
 				cfg = tryCfg;
 				cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_));
@@ -572,7 +598,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 
 		if (selfPathAvailable) {
 			StreamConfiguration tryCfg = cfg;
-			if (data_->selfPath_->validate(sensor, &tryCfg) == Adjusted) {
+			if (data_->selfPath_->validate(sensor, sensorConfig, &tryCfg) == Adjusted) {
 				selfPathAvailable = false;
 				cfg = tryCfg;
 				cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_));
@@ -589,26 +615,63 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 
 	/* Select the sensor format. */
 	PixelFormat rawFormat;
+	Size rawSize;
 	Size maxSize;
 
 	for (const StreamConfiguration &cfg : config_) {
-		if (cfg.pixelFormat.isRaw())
+		if (cfg.pixelFormat.isRaw()) {
 			rawFormat = cfg.pixelFormat;
+			rawSize = cfg.size;
+		}
 
 		maxSize = std::max(maxSize, cfg.size);
 	}
 
+	if (rawFormat.isValid() && sensorConfig) {
+		if (sensorConfig->outputSize != rawSize) {
+			sensorConfig->outputSize = rawSize;
+			status = Adjusted;
+		}
+
+		const PixelFormatInfo &info = PixelFormatInfo::info(rawFormat);
+		if (sensorConfig->bitDepth != info.bitsPerPixel) {
+			sensorConfig->bitDepth = info.bitsPerPixel;
+			status = Adjusted;
+		}
+	}
+
 	std::vector<unsigned int> mbusCodes;
+	Size sz = maxSize;
 
 	if (rawFormat.isValid()) {
 		mbusCodes = { rawFormats.at(rawFormat) };
+		sz = rawSize;
+	} else if (sensorConfig) {
+		for (const auto &value : rawFormats) {
+			const PixelFormatInfo &info = PixelFormatInfo::info(value.first);
+			if (info.bitsPerPixel == sensorConfig->bitDepth)
+				mbusCodes.push_back(value.second);
+		}
+		sz = sensorConfig->outputSize;
 	} else {
 		std::transform(rawFormats.begin(), rawFormats.end(),
 			       std::back_inserter(mbusCodes),
 			       [](const auto &value) { return value.second; });
 	}
 
-	sensorFormat_ = sensor->getFormat(mbusCodes, maxSize);
+	sensorFormat_ = sensor->getFormat(mbusCodes, sz);
+	if (sensorConfig) {
+		int ret = data_->sensor_->applyConfiguration(*sensorConfig,
+							     combinedTransform_,
+							     &sensorFormat_);
+		if (ret) {
+			LOG(RkISP1, Error)
+				<< "Sensor Configuration not supported: "
+				<< strerror(-ret);
+
+			return Invalid;
+		}
+	}
 
 	if (sensorFormat_.size.isNull())
 		sensorFormat_.size = sensor->resolution();
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
index 7c1f0c73..30becb75 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
@@ -253,8 +253,10 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size,
 	return cfg;
 }
 
-CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
-						 StreamConfiguration *cfg)
+CameraConfiguration::Status
+RkISP1Path::validate(const CameraSensor *sensor,
+		     std::optional<SensorConfiguration> sensorConfig,
+		     StreamConfiguration *cfg)
 {
 	const std::vector<unsigned int> &mbusCodes = sensor->mbusCodes();
 	Size resolution = filterSensorResolution(sensor);
@@ -281,12 +283,18 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
 			    mbusCodes.end())
 				continue;
 
-			/*
-			 * Store the raw format with the highest bits per pixel
-			 * for later usage.
+			/* If the bits per pixel is supplied from the sensor
+			 * configuration, choose a raw format that complies with
+			 * it. Otherwise, store the raw format with the highest
+			 * bits per pixel for later usage.
 			 */
 			const PixelFormatInfo &info = PixelFormatInfo::info(format);
-			if (info.bitsPerPixel > rawBitsPerPixel) {
+
+			if (sensorConfig &&
+			    info.bitsPerPixel == sensorConfig->bitDepth) {
+				rawFormat = format;
+				rawBitsPerPixel = info.bitsPerPixel;
+			} else if (info.bitsPerPixel > rawBitsPerPixel) {
 				rawBitsPerPixel = info.bitsPerPixel;
 				rawFormat = format;
 			}
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
index 9f75fe1f..8aae00ef 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
@@ -27,6 +27,7 @@ namespace libcamera {
 class CameraSensor;
 class MediaDevice;
 class V4L2Subdevice;
+class SensorConfiguration;
 struct StreamConfiguration;
 struct V4L2SubdeviceFormat;
 
@@ -45,6 +46,7 @@ public:
 						  const Size &resolution,
 						  StreamRole role);
 	CameraConfiguration::Status validate(const CameraSensor *sensor,
+					     std::optional<SensorConfiguration> sensorConfig,
 					     StreamConfiguration *cfg);
 
 	int configure(const StreamConfiguration &config,
