[libcamera-devel] [PATCH v2] pipeline: rkisp1: Support devices without self path

Paul Elder paul.elder at ideasonboard.com
Tue Jun 28 10:33:43 CEST 2022


Some hardware supported by the rkisp1 driver, such as the ISP in the
i.MX8MP, don't have a self path. Although at the moment the driver still
exposes the self path, prepare the rkisp1 pipeline handler for when the
self path will be removed for devices that don't support it.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>

---
Changes in v2:
- simplify matching
- clean up self path availability in validate()
- fix configure(), return -ENODEV if multiple roles but no self path
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 40 ++++++++++++++----------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index a233c961..2c457f0e 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -180,6 +180,8 @@ private:
 	std::unique_ptr<V4L2VideoDevice> stat_;
 	std::unique_ptr<V4L2Subdevice> csi_;
 
+	bool hasSelfPath_;
+
 	RkISP1MainPath mainPath_;
 	RkISP1SelfPath selfPath_;
 
@@ -344,7 +346,7 @@ void RkISP1CameraData::paramFilled(unsigned int frame)
 	if (info->mainPathBuffer)
 		mainPath_->queueBuffer(info->mainPathBuffer);
 
-	if (info->selfPathBuffer)
+	if (info->selfPathBuffer && selfPath_)
 		selfPath_->queueBuffer(info->selfPathBuffer);
 }
 
@@ -383,7 +385,7 @@ bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg)
 		return false;
 
 	config = cfg;
-	if (data_->selfPath_->validate(&config) != Valid)
+	if (data_->selfPath_ && data_->selfPath_->validate(&config) != Valid)
 		return false;
 
 	return true;
@@ -393,6 +395,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 {
 	const CameraSensor *sensor = data_->sensor_.get();
 	Status status = Valid;
+	unsigned int pathCount = data_->selfPath_ ? 2 : 1;
 
 	if (config_.empty())
 		return Invalid;
@@ -403,8 +406,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 	}
 
 	/* Cap the number of entries to the available streams. */
-	if (config_.size() > 2) {
-		config_.resize(2);
+	if (config_.size() > pathCount) {
+		config_.resize(pathCount);
 		status = Adjusted;
 	}
 
@@ -421,7 +424,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 		std::reverse(order.begin(), order.end());
 
 	bool mainPathAvailable = true;
-	bool selfPathAvailable = true;
+	bool selfPathAvailable = (pathCount == 2);
 	for (unsigned int index : order) {
 		StreamConfiguration &cfg = config_[index];
 
@@ -500,7 +503,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 }
 
 PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager)
-	: PipelineHandler(manager)
+	: PipelineHandler(manager), hasSelfPath_(true)
 {
 }
 
@@ -527,7 +530,7 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera
 	}
 
 	bool mainPathAvailable = true;
-	bool selfPathAvailable = true;
+	bool selfPathAvailable = data->selfPath_;
 	for (const StreamRole role : roles) {
 		bool useMainPath;
 
@@ -636,10 +639,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
 			ret = mainPath_.configure(cfg, format);
 			streamConfig[0] = IPAStream(cfg.pixelFormat,
 						    cfg.size);
-		} else {
+		} else if (hasSelfPath_) {
 			ret = selfPath_.configure(cfg, format);
 			streamConfig[1] = IPAStream(cfg.pixelFormat,
 						    cfg.size);
+		} else {
+			return -ENODEV;
 		}
 
 		if (ret)
@@ -687,7 +692,7 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S
 
 	if (stream == &data->mainPathStream_)
 		return mainPath_.exportBuffers(count, buffers);
-	else if (stream == &data->selfPathStream_)
+	else if (hasSelfPath_ && stream == &data->selfPathStream_)
 		return selfPath_.exportBuffers(count, buffers);
 
 	return -EINVAL;
@@ -816,7 +821,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
 		}
 	}
 
-	if (data->selfPath_->isEnabled()) {
+	if (hasSelfPath_ && data->selfPath_->isEnabled()) {
 		ret = selfPath_.start();
 		if (ret) {
 			mainPath_.stop();
@@ -843,7 +848,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)
 
 	data->ipa_->stop();
 
-	selfPath_.stop();
+	if (hasSelfPath_)
+		selfPath_.stop();
 	mainPath_.stop();
 
 	ret = stat_->streamOff();
@@ -946,7 +952,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 	int ret;
 
 	std::unique_ptr<RkISP1CameraData> data =
-		std::make_unique<RkISP1CameraData>(this, &mainPath_, &selfPath_);
+		std::make_unique<RkISP1CameraData>(this, &mainPath_,
+						   hasSelfPath_ ? &selfPath_ : nullptr);
 
 	ControlInfoMap::Map ctrls;
 	ctrls.emplace(std::piecewise_construct,
@@ -1002,9 +1009,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
 
 	DeviceMatch dm("rkisp1");
 	dm.add("rkisp1_isp");
-	dm.add("rkisp1_resizer_selfpath");
 	dm.add("rkisp1_resizer_mainpath");
-	dm.add("rkisp1_selfpath");
 	dm.add("rkisp1_mainpath");
 	dm.add("rkisp1_stats");
 	dm.add("rkisp1_params");
@@ -1019,6 +1024,8 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
 		return false;
 	}
 
+	hasSelfPath_ = !!media_->getEntityByName("rkisp1_selfpath");
+
 	/* Create the V4L2 subdevices we will need. */
 	isp_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_isp");
 	if (isp_->open() < 0)
@@ -1049,11 +1056,12 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
 	if (!mainPath_.init(media_))
 		return false;
 
-	if (!selfPath_.init(media_))
+	if (hasSelfPath_ && !selfPath_.init(media_))
 		return false;
 
 	mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);
-	selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);
+	if (hasSelfPath_)
+		selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);
 	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
 	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
 
-- 
2.30.2



More information about the libcamera-devel mailing list