From patchwork Tue Jun 28 08:33:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 16399 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 429B8BD808 for ; Tue, 28 Jun 2022 08:33:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 95D9165637; Tue, 28 Jun 2022 10:33:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656405233; bh=oT2FTzU2WITXhEetKTO3hCMCs7Rh51Nm3iY9GZUYxGs=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=E83tb7Yl9voo91FKB6bZc7jPho1jINgv/XHnA2Lp7byHr7uHEjoIZ8gUXmwKVt+Sg Kh4IimWIYfl/2mzG1Y5dnE++FzI1yI6oZRWKKI7Z2/o485HWEZLJKOjgEwiyb0WkXv VYaWzKSARoxXJYdra6gOuqeyPKD0EgUhzLbmrZsvSz+Ql7PZsKIplNFEmAs5XHVKp2 WTrq54C2VaT/WgC1lYE3XiUXgwEdVijIVP/yfJWt4pcVzbO5yfUIQHbo0YpI3HQt1+ zaUIj1/Y0bodqTNowzR4zQxUKf5UzkIGSWylS9lMJOT3J5z2zPaVGTuN2uTIW4zbbq X5ym4eoFoifUQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A41676559A for ; Tue, 28 Jun 2022 10:33:51 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="PBDGwa9/"; dkim-atps=neutral Received: from pyrite.rasen.tech (softbank036240122163.bbtec.net [36.240.122.163]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3A6FC55A; Tue, 28 Jun 2022 10:33:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656405231; bh=oT2FTzU2WITXhEetKTO3hCMCs7Rh51Nm3iY9GZUYxGs=; h=From:To:Cc:Subject:Date:From; b=PBDGwa9/uE+omOJ42A3c9PM8THoOAH8hHRSXPAZJs070RtT5hqHjC0nrM9C2Hs15y YQr7O1SnWEhrpxR0B68N0EcwDghv+NWKPj/Tf+HfbXC/dMZ4y9+XvwVCnC8dKqDSFW BjvAcA3K8sfxYxGvWOLlOGlvPZ9Ueir1wz2/YaPc= To: libcamera-devel@lists.libcamera.org Date: Tue, 28 Jun 2022 17:33:43 +0900 Message-Id: <20220628083343.1992147-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] pipeline: rkisp1: Support devices without self path X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Paul Elder via libcamera-devel From: Paul Elder Reply-To: Paul Elder Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- 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 stat_; std::unique_ptr 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 data = - std::make_unique(this, &mainPath_, &selfPath_); + std::make_unique(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);