diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index 8aafd82e6547..61bf1d7ca6de 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -61,6 +61,11 @@ public:
 				       Transform transform = Transform::Identity,
 				       V4L2SubdeviceFormat *sensorFormat = nullptr) = 0;
 
+	virtual V4L2Subdevice::Stream imageStream() const;
+	virtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const;
+	virtual V4L2SubdeviceFormat embeddedDataFormat() const;
+	virtual int setEmbeddedDataEnabled(bool enable);
+
 	virtual const ControlList &properties() const = 0;
 	virtual int sensorInfo(IPACameraSensorInfo *info) const = 0;
 	virtual Transform computeTransform(Orientation *orientation) const = 0;
diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp
index 54cf98b203fd..1217365b2a55 100644
--- a/src/libcamera/sensor/camera_sensor.cpp
+++ b/src/libcamera/sensor/camera_sensor.cpp
@@ -196,6 +196,73 @@ CameraSensor::~CameraSensor() = default;
  * error code otherwise
  */
 
+/**
+ * \brief Retrieve the image source stream
+ *
+ * Sensors that produce multiple streams do not guarantee that the image stream
+ * is always assigned number 0. This function allows callers to retrieve the
+ * image stream on the sensor's source pad, in order to configure the receiving
+ * side accordingly.
+ *
+ * \return The image source stream
+ */
+V4L2Subdevice::Stream CameraSensor::imageStream() const
+{
+	return { 0, 0 };
+}
+
+/**
+ * \brief Retrieve the embedded data source stream
+ *
+ * Some sensors produce embedded data in a stream separate from the image
+ * stream. This function indicates if the sensor supports this feature by
+ * returning the embedded data stream on the sensor's source pad if available,
+ * or an std::optional<> without a value otheriwse.
+ *
+ * \return The embedded data source stream
+ */
+std::optional<V4L2Subdevice::Stream> CameraSensor::embeddedDataStream() const
+{
+	return {};
+}
+
+/**
+ * \brief Retrieve the format on the embedded data stream
+ *
+ * When an embedded data stream is available, this function returns the
+ * corresponding format on the sensor's source pad. The format may vary with
+ * the image stream format, and should therefore be retrieved after configuring
+ * the image stream.
+ *
+ * If the sensor doesn't support embedded data, this function returns a
+ * default-constructed format.
+ *
+ * \return The format on the embedded data stream
+ */
+V4L2SubdeviceFormat CameraSensor::embeddedDataFormat() const
+{
+	return {};
+}
+
+/**
+ * \brief Enable or disable the embedded data stream
+ * \param[in] enable True to enable the embedded data stream, false to disable it
+ *
+ * For sensors that support embedded data, this function enables or disables
+ * generation of embedded data. Some of such sensors always produce embedded
+ * data, in which case this function return -EISCONN if the caller attempts to
+ * disable embedded data.
+ *
+ * If the sensor doesn't support embedded data, this function returns 0 when \a
+ * enable is false, and -ENOSTR otherwise.
+ *
+ * \return 0 on success, or a negative error code otherwise
+ */
+int CameraSensor::setEmbeddedDataEnabled(bool enable)
+{
+	return enable ? -ENOSTR : 0;
+}
+
 /**
  * \fn CameraSensor::properties()
  * \brief Retrieve the camera sensor properties
diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp
index 4c653121d547..9380ec7129f6 100644
--- a/src/libcamera/sensor/camera_sensor_raw.cpp
+++ b/src/libcamera/sensor/camera_sensor_raw.cpp
@@ -84,6 +84,11 @@ public:
 			       Transform transform = Transform::Identity,
 			       V4L2SubdeviceFormat *sensorFormat = nullptr) override;
 
+	V4L2Subdevice::Stream imageStream() const override;
+	std::optional<V4L2Subdevice::Stream> embeddedDataStream() const override;
+	V4L2SubdeviceFormat embeddedDataFormat() const override;
+	int setEmbeddedDataEnabled(bool enable) override;
+
 	const ControlList &properties() const override { return properties_; }
 	int sensorInfo(IPACameraSensorInfo *info) const override;
 	Transform computeTransform(Orientation *orientation) const override;
@@ -878,6 +883,73 @@ int CameraSensorRaw::applyConfiguration(const SensorConfiguration &config,
 	return 0;
 }
 
+V4L2Subdevice::Stream CameraSensorRaw::imageStream() const
+{
+	return streams_.image.source;
+}
+
+std::optional<V4L2Subdevice::Stream> CameraSensorRaw::embeddedDataStream() const
+{
+	if (!streams_.edata)
+		return {};
+
+	return { streams_.edata->source };
+}
+
+V4L2SubdeviceFormat CameraSensorRaw::embeddedDataFormat() const
+{
+	if (!streams_.edata)
+		return {};
+
+	V4L2SubdeviceFormat format;
+	int ret = subdev_->getFormat(streams_.edata->source, &format);
+	if (ret)
+		return {};
+
+	return format;
+}
+
+int CameraSensorRaw::setEmbeddedDataEnabled(bool enable)
+{
+	if (!streams_.edata)
+		return enable ? -ENOSTR : 0;
+
+	V4L2Subdevice::Routing routing{ 2 };
+
+	routing[0].sink = streams_.image.sink;
+	routing[0].source = streams_.image.source;
+	routing[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
+
+	routing[1].sink = streams_.edata->sink;
+	routing[1].source = streams_.edata->source;
+	routing[1].flags = enable ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0;
+
+	int ret = subdev_->setRouting(&routing);
+	if (ret)
+		return ret;
+
+	/*
+	 * Check if the embedded data stream has been enabled or disabled
+	 * correctly. Assume at least one route will match the embedded data
+	 * source stream, as there would be something seriously wrong
+	 * otherwise.
+	 */
+	bool enabled = false;
+
+	for (const V4L2Subdevice::Route &route : routing) {
+		if (route.source != streams_.edata->source)
+			continue;
+
+		enabled = route.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE;
+		break;
+	}
+
+	if (enabled != enable)
+		return enabled ? -EISCONN : -ENOSTR;
+
+	return 0;
+}
+
 int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const
 {
 	info->model = model();
