[RFC,v1,16/20] pipeline: rpi: Add platform helpers for camera enumeration
diff mbox series

Message ID 20260918080734.1228227-17-naush@raspberrypi.com
State New
Headers show
Series
  • libcamera: New enumeration API
Related show

Commit Message

Naushir Patuck Sept. 18, 2026, 7:59 a.m. UTC
The vc4 and pisp match() implementations differ only in the media
devices they look for, the frontend link name, the camera data they
allocate and, for pisp, a check of the PiSP variant.

Expose these differences as platforms specific helpers in PipelineHandlerBase
and implement them for both vc4 and pisp. In a subsequent commit, a
generic survey() and createCamera() can be built on them.

The existing match() implementations are left untouched.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 .../pipeline/rpi/common/pipeline_base.h       | 12 ++++
 src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 69 +++++++++++++++++++
 src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 22 ++++++
 3 files changed, 103 insertions(+)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h
index ca12a4875faf..16c509d6a769 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.h
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h
@@ -245,6 +245,18 @@  protected:
 
 	void mapBuffers(Camera *camera, const BufferMap &buffers, unsigned int mask);
 
+	/* Platform-specific helpers used by survey() and createCamera(). */
+	virtual DeviceMatch frontendMatch() const = 0;
+	virtual DeviceMatch backendMatch() const = 0;
+	virtual const char *frontendLinkName() const = 0;
+	virtual bool platformSupported([[maybe_unused]] const MediaDevice *frontend,
+				       [[maybe_unused]] const MediaDevice *backend) const
+	{
+		return true;
+	}
+	virtual std::unique_ptr<CameraData>
+	allocateCameraData(MediaDevice *frontend, MediaDevice *backend) = 0;
+
 	virtual int platformRegister(std::unique_ptr<CameraData> &cameraData,
 				     std::shared_ptr<MediaDevice> unicam,
 				     std::shared_ptr<MediaDevice> isp) = 0;
diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
index 159c6b05ee7b..34de291f4092 100644
--- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp
+++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
@@ -869,12 +869,81 @@  private:
 		return static_cast<PiSPCameraData *>(camera->_d());
 	}
 
+	DeviceMatch frontendMatch() const override
+	{
+		DeviceMatch cfe("rp1-cfe");
+		cfe.add("rp1-cfe-fe-image0");
+		cfe.add("rp1-cfe-fe-stats");
+		cfe.add("rp1-cfe-fe-config");
+		return cfe;
+	}
+
+	DeviceMatch backendMatch() const override
+	{
+		DeviceMatch isp("pispbe");
+		isp.add("pispbe-input");
+		isp.add("pispbe-config");
+		isp.add("pispbe-output0");
+		isp.add("pispbe-output1");
+		isp.add("pispbe-tdn_output");
+		isp.add("pispbe-tdn_input");
+		isp.add("pispbe-stitch_output");
+		isp.add("pispbe-stitch_input");
+		return isp;
+	}
+
+	const char *frontendLinkName() const override
+	{
+		return "csi2";
+	}
+
+	bool platformSupported(const MediaDevice *frontend,
+			       const MediaDevice *backend) const override
+	{
+		const libpisp::PiSPVariant &variant =
+			libpisp::get_variant(frontend->hwRevision(),
+					     backend->hwRevision());
+		return variant.NumFrontEnds() && variant.NumBackEnds();
+	}
+
+	std::unique_ptr<RPi::CameraData>
+	allocateCameraData(MediaDevice *frontend, MediaDevice *backend) override;
+
 	int allocateBuffers(Camera *camera) override;
 	int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,
 			     std::shared_ptr<MediaDevice> cfe,
 			     std::shared_ptr<MediaDevice> isp) override;
 };
 
+std::unique_ptr<RPi::CameraData>
+PipelineHandlerPiSP::allocateCameraData(MediaDevice *frontend, MediaDevice *backend)
+{
+	const libpisp::PiSPVariant &variant =
+		libpisp::get_variant(frontend->hwRevision(),
+				     backend->hwRevision());
+	if (!variant.NumFrontEnds() || !variant.NumBackEnds()) {
+		LOG(RPI, Error) << "Unsupported PiSP variant";
+		return {};
+	}
+
+	std::unique_ptr<RPi::CameraData> cameraData =
+		std::make_unique<PiSPCameraData>(this, variant);
+	PiSPCameraData *pisp =
+		static_cast<PiSPCameraData *>(cameraData.get());
+
+	pisp->fe_ = SharedMemObject<FrontEnd>
+			("pisp_frontend", true, pisp->pispVariant_);
+	pisp->be_ = SharedMemObject<BackEnd>
+			("pisp_backend", BackEnd::Config({}), pisp->pispVariant_);
+
+	if (!pisp->fe_.fd().isValid() || !pisp->be_.fd().isValid()) {
+		LOG(RPI, Error) << "Failed to create ISP shared objects";
+		return {};
+	}
+
+	return cameraData;
+}
+
 bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)
 {
 	constexpr unsigned int numCfeDevices = 2;
diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp
index 200e3b58724a..f6af31072eee 100644
--- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp
+++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp
@@ -158,6 +158,28 @@  private:
 		return static_cast<Vc4CameraData *>(camera->_d());
 	}
 
+	DeviceMatch frontendMatch() const override
+	{
+		return DeviceMatch("unicam");
+	}
+
+	DeviceMatch backendMatch() const override
+	{
+		return DeviceMatch("bcm2835-isp");
+	}
+
+	const char *frontendLinkName() const override
+	{
+		return "unicam-image";
+	}
+
+	std::unique_ptr<RPi::CameraData>
+	allocateCameraData([[maybe_unused]] MediaDevice *frontend,
+			   [[maybe_unused]] MediaDevice *backend) override
+	{
+		return std::make_unique<Vc4CameraData>(this);
+	}
+
 	int allocateBuffers(Camera *camera) override;
 	int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,
 			     std::shared_ptr<MediaDevice> unicam,