From patchwork Fri Feb 24 07:30:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18306 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 591B6BDCBF for ; Fri, 24 Feb 2023 07:30:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C1DC76261A; Fri, 24 Feb 2023 08:30:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1677223832; bh=/Igy0YN7Y2TAwXL2qhQQmGdqzCAivCVVQ0paQVWnQNY=; h=To:Date:List-Id:List-Post:From:List-Subscribe:List-Unsubscribe: List-Archive:Reply-To:List-Help:Subject:From; b=TCFD00IurRWgJlgcYHClE6er4LgDw5Azo4D1NmhiIg13NBBCKXO4vFOistFz62RX6 Q09OJF4m31BQtfdmKKUSh6xERFzTEuWwDbkKDiKFQQ4OE8m1CRtMDdGrEBsuVavb9W Qs5CIgsP/AVOh3FZ8H7gHQgwakbKasbzTCGv4lrO0PvkQHiqsrGvNRExl1IEWA9If8 0pTUMKOMHbf5zzm/UhgUDaSVxAdy7vapd/3pwp8fz+ywwYz3nt0lMCtFTlPY2yS+4n 1DY75ioxhSChyFzbyZkncII1rGpTM6Hi6VXIlFPDZJeKjHbZItRXXUA0peWLz3V+k+ vs4enh37Xp7zw== To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Feb 2023 07:30:23 +0000 MIME-Version: 1.0 Message-ID: List-Id: List-Post: X-Patchwork-Original-From: Naushir Patuck via libcamera-devel From: Naushir Patuck Precedence: list X-Mailman-Version: 2.1.29 X-BeenThere: libcamera-devel@lists.libcamera.org List-Subscribe: , List-Unsubscribe: , List-Archive: Reply-To: Naushir Patuck List-Help: Subject: [libcamera-devel] [PATCH] pipeline: raspberrypi: Iterate over all Unicam instances in match() Content-Disposition: inline Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" On Raspberry Pi Compute Module platforms, it is possible to attach a single camera device only to the secondary Unicam port. The current logic of PipelineHandlerRPi::match() will return a failure during enumeration of the first Unicam media device (due to no sensor attached, or sensor failure) and thus the second Unicam media device will never be enumerated. Fix this by looping over all Unicam instances in PipelineHandlerRPi::match() until a camera is correctly registered, or return a failure otherwise. Reported-on: https://github.com/raspberrypi/libcamera/issues/44 Signed-off-by: Naushir Patuck Reviewed-by: David Plowman --- .../pipeline/raspberrypi/raspberrypi.cpp | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 841209548350..ef01b7e166ba 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1246,41 +1246,54 @@ int PipelineHandlerRPi::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) { - DeviceMatch unicam("unicam"); - MediaDevice *unicamDevice = acquireMediaDevice(enumerator, unicam); + constexpr unsigned int numUnicamDevices = 2; - if (!unicamDevice) { - LOG(RPI, Debug) << "Unable to acquire a Unicam instance"; - return false; - } + /* + * Loop over all Unicam instances, but return out once a match is found. + * This is to ensure we correctly enumrate the camera when an instance + * of Unicam has registered with media controller, but has not registered + * device nodes due to a sensor subdevice failure. + */ + for (unsigned int i = 0; i < numUnicamDevices; i++) { + DeviceMatch unicam("unicam"); + MediaDevice *unicamDevice = acquireMediaDevice(enumerator, unicam); - DeviceMatch isp("bcm2835-isp"); - MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp); + if (!unicamDevice) { + LOG(RPI, Debug) << "Unable to acquire a Unicam instance"; + continue; + } - if (!ispDevice) { - LOG(RPI, Debug) << "Unable to acquire ISP instance"; - return false; - } + DeviceMatch isp("bcm2835-isp"); + MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp); - /* - * The loop below is used to register multiple cameras behind one or more - * video mux devices that are attached to a particular Unicam instance. - * Obviously these cameras cannot be used simultaneously. - */ - unsigned int numCameras = 0; - for (MediaEntity *entity : unicamDevice->entities()) { - if (entity->function() != MEDIA_ENT_F_CAM_SENSOR) + if (!ispDevice) { + LOG(RPI, Debug) << "Unable to acquire ISP instance"; continue; + } - int ret = registerCamera(unicamDevice, ispDevice, entity); - if (ret) - LOG(RPI, Error) << "Failed to register camera " - << entity->name() << ": " << ret; - else - numCameras++; + /* + * The loop below is used to register multiple cameras behind one or more + * video mux devices that are attached to a particular Unicam instance. + * Obviously these cameras cannot be used simultaneously. + */ + unsigned int numCameras = 0; + for (MediaEntity *entity : unicamDevice->entities()) { + if (entity->function() != MEDIA_ENT_F_CAM_SENSOR) + continue; + + int ret = registerCamera(unicamDevice, ispDevice, entity); + if (ret) + LOG(RPI, Error) << "Failed to register camera " + << entity->name() << ": " << ret; + else + numCameras++; + } + + if (numCameras) + return true; } - return !!numCameras; + return false; } void PipelineHandlerRPi::releaseDevice(Camera *camera)