From patchwork Tue Nov 3 10:41:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: GuyliandeJong X-Patchwork-Id: 28768 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 9924AC335A for ; Tue, 3 Nov 2026 12:04:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E046B6A7B3; Tue, 3 Nov 2026 13:04:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=proton.me header.i=@proton.me header.b="BYVPdOxm"; dkim-atps=neutral Received: from mail-10630.protonmail.ch (mail-10630.protonmail.ch [79.135.106.30]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9B7A26935F for ; Tue, 3 Nov 2026 11:41:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail2; t=1793702513; x=1793961713; bh=WS5HwVdQPmV+AJTvhYA+LV7Q61iOGCIF215LdTWogl0=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=BYVPdOxmKgAON+mzyqU8NPr1JXnB0qEgCiZFveWZ+zzNYAaQ6rRX/jNycjUqmGhvS SYj80uzyfs9Wf45041ryXMfuWxYxj/QT0adQJPx9thUa7rXinXbsUydbSR8hKzZr+j FQLEX/FlpbPhRkm7HaU/hPMGQccuam6H3+PRurftpMxKEa9tj/fFtdNjERRQuH7Nxk yzetG6XgYfK9R+gBebME1ZnouFF06A+hj+EOV+UNkYYtmilWXXqUXqfkxI994FsHva 6wTOays6M97RviqZ/3ytcHE4e4ffJrCzxsc8kSqnPQ4nzzb4Au31bCJqebk7CwiXUb hIFxRTBNw4JsA== Date: Tue, 03 Nov 2026 10:41:48 +0000 To: libcamera-devel@lists.libcamera.org From: GuyliandeJong Subject: [PATCH 1/3] libipa: camera_sensor_helper: Add OV9734 Message-ID: <20261103104131.87331-2-guyliandejong@proton.me> In-Reply-To: <20261103104131.87331-1-guyliandejong@proton.me> References: <20261103104131.87331-1-guyliandejong@proton.me> Feedback-ID: 112452169:user:proton X-Pm-Message-ID: c1cc94ec8139e2af2470a6c3711d2b6703ad769a MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 03 Nov 2026 13:04:24 +0100 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a camera sensor helper for the OmniVision OV9734, used as the front camera of the Microsoft Surface Laptop 2. The kernel ov9734 driver writes V4L2_CID_ANALOGUE_GAIN directly to the 0x350a gain register, with a range of 16 to 248. The register is a Q4 fixed point value, so 16 is unity gain, giving a linear model of gain = code / 16. The driver doesn't program the black level calibration target, so the sensor default of 0x40 at 10 bits applies, which is 4096 at 16 bits. Without a helper the IPU3 IPA can't be used with this sensor. Signed-off-by: GuyliandeJong --- src/ipa/libipa/camera_sensor_helper.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp index 359040ec..41266005 100644 --- a/src/ipa/libipa/camera_sensor_helper.cpp +++ b/src/ipa/libipa/camera_sensor_helper.cpp @@ -877,6 +877,19 @@ public: }; REGISTER_CAMERA_SENSOR_HELPER("ov8865", CameraSensorHelperOv8865) +class CameraSensorHelperOv9734 : public CameraSensorHelper +{ +public: + CameraSensorHelperOv9734() + { + /* Sensor default black level target: 0x40 at 10 bits. */ + blackLevel_ = 4096; + /* Analogue gain is a Q4 value, 16 is unity gain. */ + gain_ = AnalogueGainLinear{ 1, 0, 0, 16 }; + } +}; +REGISTER_CAMERA_SENSOR_HELPER("ov9734", CameraSensorHelperOv9734) + class CameraSensorHelperOv13858 : public CameraSensorHelper { public: From patchwork Tue Nov 3 10:41:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: GuyliandeJong X-Patchwork-Id: 28767 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 5AB8FC3358 for ; Tue, 3 Nov 2026 12:04:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3E3926A7B0; Tue, 3 Nov 2026 13:04:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=proton.me header.i=@proton.me header.b="xRfwwPsF"; dkim-atps=neutral Received: from mail-43100.protonmail.ch (mail-43100.protonmail.ch [185.70.43.100]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D42E26935F for ; Tue, 3 Nov 2026 11:41:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail2; t=1793702514; x=1793961714; bh=nyJ9XBk/SI0rfVQYAXQoIbE/Dtl4lHNg/Y7nm1+ktb8=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=xRfwwPsFJ3C0Gp34AznwA5YGkEgmazmBsghbxAWt/K281GcS+6014DKBMEy882RQr Y4npYl60hk2GmrzLiZgF2ERyl2/cbIzxv2SA/fOWj9wmwzOULDgzFWr6cRyJviZ9lX qL3ZkYbdP5atlcl/5TKg+552ylS/KWqHKKwnYPrPQ78kRvggJTkxL/rVC60IsfWLnV jVn4W3bG3PSp7Dl30vyMg3a6OTq5oM/+Nxk4iOhWZJnNEtfpLmFFFlxM1LxjW0Apcd 9LIqkz0/FylUvhRx5BRmmB81JM5W/asJvFl6fJ3lOn0zZh/rFcVx1d4olLfTvRE8Fs xvy4ZQddACWVA== Date: Tue, 03 Nov 2026 10:41:52 +0000 To: libcamera-devel@lists.libcamera.org From: GuyliandeJong Subject: [PATCH 2/3] libcamera: camera_sensor: Initialize test pattern mode Message-ID: <20261103104131.87331-3-guyliandejong@proton.me> In-Reply-To: <20261103104131.87331-1-guyliandejong@proton.me> References: <20261103104131.87331-1-guyliandejong@proton.me> Feedback-ID: 112452169:user:proton X-Pm-Message-ID: ecd08c87084ccf902fa182a07f21d0053cb740ba MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 03 Nov 2026 13:04:24 +0100 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The testPatternMode_ member of CameraSensorLegacy and CameraSensorRaw is never initialized in the constructors. It is only assigned by applyTestPatternMode(), which returns early without touching it when the sensor has no test pattern modes. The IPU3 pipeline handler calls setTestPatternMode(TestPatternModeOff) in start(). For a sensor without test pattern modes, setTestPatternMode() compares the mode with the uninitialized value and, if they differ, returns -EINVAL as the sensor doesn't support test patterns. Camera start then fails at random, depending on the content of the memory. This was seen with the OV9734 on a Surface Laptop 2, which has no entry in the camera sensor properties database. Initialize testPatternMode_ to TestPatternModeOff, which matches the state that init() puts the sensor in. Signed-off-by: GuyliandeJong Reviewed-by: Barnabás Pőcze --- src/libcamera/sensor/camera_sensor_legacy.cpp | 1 + src/libcamera/sensor/camera_sensor_raw.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp index 792e4b09..fe5664e0 100644 --- a/src/libcamera/sensor/camera_sensor_legacy.cpp +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp @@ -156,6 +156,7 @@ private: CameraSensorLegacy::CameraSensorLegacy(const MediaEntity *entity) : entity_(entity), pad_(UINT_MAX), staticProps_(nullptr), + testPatternMode_(controls::draft::TestPatternModeOff), bayerFormat_(nullptr), supportHFlips_(false), supportVFlips_(false), flipsAlterBayerOrder_(false), properties_(properties::properties) { diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp index 55b386ce..b87ec0eb 100644 --- a/src/libcamera/sensor/camera_sensor_raw.cpp +++ b/src/libcamera/sensor/camera_sensor_raw.cpp @@ -164,8 +164,10 @@ private: */ CameraSensorRaw::CameraSensorRaw(const MediaEntity *entity) - : entity_(entity), staticProps_(nullptr), supportHFlips_(false), - supportVFlips_(false), flipsAlterBayerOrder_(false), + : entity_(entity), staticProps_(nullptr), + testPatternMode_(controls::draft::TestPatternModeOff), + supportHFlips_(false), supportVFlips_(false), + flipsAlterBayerOrder_(false), properties_(properties::properties) { } From patchwork Tue Nov 3 10:41:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: GuyliandeJong X-Patchwork-Id: 28769 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 6C7F5C3358 for ; Tue, 3 Nov 2026 12:04:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 90DC66A7B7; Tue, 3 Nov 2026 13:04:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=proton.me header.i=@proton.me header.b="W32Gfh2L"; dkim-atps=neutral Received: from mail-244116.protonmail.ch (mail-244116.protonmail.ch [109.224.244.116]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C05B6935F for ; Tue, 3 Nov 2026 11:41:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail2; t=1793702517; x=1793961717; bh=Jv0wAoyEv6d2qAuJQP8E5R1vWcmCf1LXbgEI22Lhi9A=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=W32Gfh2LOniTVyaI2SXFitsDicFip0SFSHVewQxLHiJBLoINXpbm+dloTb33Y3VXk PMjknzcuZApVBfoXapP1GLYenLUC3XUS6782FY2pAClLZgMndXh1Lh+QXC9JklcP20 OPQN41kwWd5gSc1k8q3b6u4wz6RHEdE1iPImvYCZxMAIGv2HQLJmvDORCYfyPUsS8m rVd07evHM5r/b9O716vE+vyk0KDW2BpEzR9CN1AAlBPXHa3HQHtSIwEwNRfTZv4Ld/ XFV2F1WpKTleLagieRWUtlWwOZWN7yvZyfJtVg1pukzC7qlZOJHW1Cx5hwL/Bi6snG leO4XtR3ueQqg== Date: Tue, 03 Nov 2026 10:41:55 +0000 To: libcamera-devel@lists.libcamera.org From: GuyliandeJong Subject: [PATCH 3/3] libcamera: pipeline: ipu3: Bound viewfinder size to the ImgU limits Message-ID: <20261103104131.87331-4-guyliandejong@proton.me> In-Reply-To: <20261103104131.87331-1-guyliandejong@proton.me> References: <20261103104131.87331-1-guyliandejong@proton.me> Feedback-ID: 112452169:user:proton X-Pm-Message-ID: 12d21de6036a88056253d2d9c7ffc04f9ecd735b MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 03 Nov 2026 13:04:24 +0100 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The default size of the Viewfinder and VideoRecording streams is 1280x720, bounded by the sensor resolution. It is also used as the maximum size of the StreamFormats ranges reported for these roles. validate() requires the ImgU outputs to be strictly smaller than the CIO2 output, aligned down to 64x32. For a sensor no wider than 1280 pixels or no taller than 736 lines, the default size is then larger than what validate() accepts. With the OV9734 (1296x734) on a Surface Laptop 2, 1280x720 is reported while validate() adjusts it to 1280x704. Applications that pick sizes from StreamFormats, such as PipeWire, get configurations adjusted behind their back, which made WirePlumber abort. Apply the same margin to the sensor resolution as validate() and as the StillCapture role already does, before bounding it to 1280x720. Larger sensors are not affected. Signed-off-by: GuyliandeJong --- src/libcamera/pipeline/ipu3/ipu3.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 14cab9e5..730fdfc5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -444,10 +444,14 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera, std::span