diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index edf08666..23456cbf 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -824,7 +824,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 		 * buffer for capture (unless the stream is being stopped), and
 		 * complete the request with all the user-facing buffers.
 		 */
-		if (buffer->metadata().status != FrameMetadata::FrameCancelled)
+		if (buffer->metadata().status != FrameMetadata::FrameCancelled &&
+		    !rawRequested_)
 			video_->queueBuffer(buffer);
 
 		if (conversionQueue_.empty())
@@ -870,13 +871,14 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 	 */
 	if (useConversion_) {
 		if (conversionQueue_.empty()) {
-			video_->queueBuffer(buffer);
+			if (!rawRequested_)
+				video_->queueBuffer(buffer);
 			return;
 		}
 
 		if (converter_)
 			converter_->queueBuffers(buffer, conversionQueue_.front().outputs);
-		else
+		else if (swispRequested_)
 			/*
 			 * request->sequence() cannot be retrieved from `buffer' inside
 			 * queueBuffers because unique_ptr's make buffer->request() invalid
@@ -886,6 +888,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 					     conversionQueue_.front().outputs);
 
 		conversionQueue_.pop();
+		if (rawRequested_)
+			pipe->completeBuffer(request, buffer);
 		return;
 	}
 
@@ -905,7 +909,8 @@ void SimpleCameraData::clearIncompleteRequests()
 void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
 {
 	/* Queue the input buffer back for capture. */
-	video_->queueBuffer(buffer);
+	if (!rawRequested_)
+		video_->queueBuffer(buffer);
 }
 
 void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
@@ -1450,7 +1455,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		return -EBUSY;
 	}
 
-	if (data->useConversion_) {
+	if (data->useConversion_ && !data->rawRequested_) {
 		/*
 		 * When using the converter allocate a fixed number of internal
 		 * buffers.
@@ -1458,7 +1463,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		ret = video->allocateBuffers(kNumInternalBuffers,
 					     &data->conversionBuffers_);
 	} else {
-		/* Otherwise, prepare for using buffers from the only stream. */
+		/* Otherwise, prepare for using buffers from the only or raw stream. */
 		Stream *stream = &data->streams_[0];
 		ret = video->importBuffers(stream->configuration().bufferCount);
 	}
@@ -1489,8 +1494,9 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		}
 
 		/* Queue all internal buffers for capture. */
-		for (std::unique_ptr<FrameBuffer> &buffer : data->conversionBuffers_)
-			video->queueBuffer(buffer.get());
+		if (!data->rawRequested_)
+			for (std::unique_ptr<FrameBuffer> &buffer : data->conversionBuffers_)
+				video->queueBuffer(buffer.get());
 	}
 
 	return 0;
@@ -1532,7 +1538,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)
 		 * queue, it will be handed to the converter in the capture
 		 * completion handler.
 		 */
-		if (data->useConversion_) {
+		if (data->useConversion_ && !isRawFormat(stream->configuration().pixelFormat)) {
 			buffers.emplace(stream, buffer);
 		} else {
 			ret = data->video_->queueBuffer(buffer);
