From patchwork Tue Oct 27 21:32:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Ziliani X-Patchwork-Id: 28654 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 D66E3C324C for ; Tue, 27 Oct 2026 22:05:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B145269068; Tue, 27 Oct 2026 23:05:12 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="JkJIxIUF"; dkim-atps=neutral Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3BDDE69059 for ; Tue, 27 Oct 2026 22:32:44 +0100 (CET) Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-48e47347279so233929f8f.1 for ; Tue, 27 Oct 2026 14:32:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793136764; x=1793741564; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=38buYmj9XmdXjGlQno0GpJpcBEEKa2oXiVMldTK28cE=; b=JkJIxIUF73kQ7Y18jiTXyyxjsM4LDl5zUWkzb/w8SqNl0sgwDsgQc2FLCjLpegrxur H6s/dHOnbEJwWEvaStGOxvU0xw19ZlOmbJrVpElRz8plHOMHbvmSqmGAEAet5M3y8jdv M+o7WBmYEc1B4FuIMdRAHvejrz9n6LToYH/pli1R6QP3y2wtkgghao8kpV+XXl7k7cPh 7NizqonEyBCWWO6UVj/CeNGlZon/f+oHFLkn9m6pC8H+uxyoi72Y95ILiDGSX98FJ/je 9cXb4xdu+edwmjwsGZkItSglDmkCk4yhG6CYYJgkZnbRgQH5IbB0rsR4UOoSFlSoEKSF t+3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793136764; x=1793741564; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=38buYmj9XmdXjGlQno0GpJpcBEEKa2oXiVMldTK28cE=; b=rSt5T3vCwz8XqIIvZwZDdjXyCF+FcugT+XJQ7p8+Rqa9dA7ojYZJni7nrSAJkxJL4s bV3sTOZquvkGWDHBkvS0IPQJDrp5K3ATREl4rOFgMb+oxk2kWCOutQM9KGyANK/KYEvY v6M8pNe78piqhm5guMwi4Xf8+MeFm8gHtbdo5eqsfQqHaGotYhTOFWDSEZ5gKMx+Pf4w xZw4w+oSYToUJcfAHjrYAwXVVTVBuZcDAD6VtosICfbyvRFRMr/XkiABArTdKJeeHoMt pydSirt9/Q1aLqZloUFy3og1QfegFnXEs5VVBSd8ca73uq1VlG7j0TzqqtJTEvfRt8ci qO5g== X-Gm-Message-State: AFq9FYLxDfDvc3I6d5S4OmtsmqRpSji7AOY8S6QpDkJiAXip0o9aymCI IBIq4oOga0vhNE+c8n98UwAcysLQ1Ctho1nIPwzjRCNilSXubZKn9+dmeSg8EcNX X-Gm-Gg: AYBFou0MmW+WF6wXkfbmhpXHF4JnGuNnDm1wrXv66mzPm6Mxstx3jS5oVT2Fh3Dg2kg zpbvlAVKq45EZ03bWS7CbDwi2xQGOsbe1PAQ4N65hr4eK7tj7uTo+Mfn+ABmaUiY+0q94Kpirj8 JcbIYyBb2S0XAiqB5QvGGRngg8jyNZZkAIXt3TNJiEyaqs+LKWpJwAqFC5tVwURTMYIAnxP3U6I crzdrPEbt9NTRsGf7LswmMUA8xtWoUnzMwlQAJK3FO98U9fQ8Y2YD+HN/BmhpOKRORcqa3UxWE6 3FTDUC/rHu3/qUf8TZfyNanQQ55IPb7ikey/kZ4ESsTkR2X5+ZyCvt6td5k4vJUhWOJBAD7RuAe ZZUbctjz0E20zK8biFN10hhCdd2SKxdz69CIjT+szFqex1UuRhq8CKyY6LNRysLBB9xC+qWuEj8 HV4/JV6Ki2fCi/M9b0y+74tlxASGj9iDuwbv4vv6yDrEJz91GR+UWlib1bx8mararBNaBm1uzdM JVlMrsghpsZPi+hwlZW8JxKrPLQ59Oct5Jkbme+pQv0evzFV8KhE88F6NHHcF1t9f3oafoBYNyB h0BL000viRRsjeQAx+f6ON84/toYtV6gICdIEchgydbQDz64bFiZjhpvLWOKXMJS64Z0ya7kGOE ML9SR31GTuwQsFxvJ X-Received: by 2002:a05:6000:1446:b0:487:91e:d8ed with SMTP id ffacd0b85a97d-48e5d58d47emr1620008f8f.2.1793136763747; Tue, 27 Oct 2026 14:32:43 -0700 (PDT) Received: from PC-Marco.lan ([151.59.114.42]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48e3ebd48eesm24920507f8f.30.2026.10.27.14.32.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Oct 2026 14:32:43 -0700 (PDT) From: Marco Ziliani To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart , Kieran Bingham , Hans de Goede , Harvey Yang , Daniel Scally Subject: [RFC PATCH 1/2] libcamera: camera_lens: Close the lens subdev when not in use Date: Tue, 27 Oct 2026 22:32:39 +0100 Message-ID: <20261027213240.140663-2-rylos78@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261027213240.140663-1-rylos78@gmail.com> References: <20261027213240.140663-1-rylos78@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 27 Oct 2026 23:05:09 +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" Lens drivers such as dw9714, dw9719 and ak7375 power the lens up when the subdev is opened and down when it is closed. On ACPI platforms ipu-bridge also adds a runtime PM device link from the lens to its camera sensor, so an open lens subdev keeps the sensor powered too. CameraLens opens the subdev in init() and keeps it open for the lifetime of the CameraManager. With a long-lived camera manager, such as the WirePlumber libcamera monitor, the lens and the sensor are then never powered down, even when no camera is in use. Close the subdev at the end of init(), once the lens driver has been validated and the controls have been cached, and add open() and close() functions that pipeline handlers can use to power the lens for the duration of a capture session. setFocusPosition() reopens the subdev on demand, so pipeline handlers that don't call open() keep working as before, the lens being powered from the first focus change on. Signed-off-by: Marco Ziliani --- include/libcamera/internal/camera_lens.h | 2 ++ src/libcamera/camera_lens.cpp | 42 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/libcamera/internal/camera_lens.h b/include/libcamera/internal/camera_lens.h index f347c5e0..f63bcfa2 100644 --- a/include/libcamera/internal/camera_lens.h +++ b/include/libcamera/internal/camera_lens.h @@ -27,6 +27,8 @@ public: ~CameraLens(); int init(); + int open(); + void close(); int setFocusPosition(int32_t position); const std::string &model() const { return model_; } diff --git a/src/libcamera/camera_lens.cpp b/src/libcamera/camera_lens.cpp index ccc2a6a6..7be5bfd2 100644 --- a/src/libcamera/camera_lens.cpp +++ b/src/libcamera/camera_lens.cpp @@ -73,9 +73,47 @@ int CameraLens::init() return ret; model_ = subdev_->model(); + + /* + * Lens drivers commonly keep the lens powered for as long as the + * subdev is open, and the lens power often depends on the camera + * sensor (e.g. through a runtime PM device link). Close the subdev + * until the lens is actually used, so that a long-lived camera + * manager doesn't keep the lens and the sensor powered. + */ + subdev_->close(); + return 0; } +/** + * \brief Open the lens subdev + * + * Pipeline handlers call this function when the camera starts, to power the + * lens for the duration of the capture session. The subdev is also opened on + * demand by setFocusPosition(). + * + * \return 0 on success or a negative error code otherwise + */ +int CameraLens::open() +{ + if (subdev_->isOpen()) + return 0; + + return subdev_->open(); +} + +/** + * \brief Close the lens subdev + * + * Pipeline handlers call this function when the camera stops, to let the lens + * driver power the lens down. + */ +void CameraLens::close() +{ + subdev_->close(); +} + /** * \brief This function sets the focal point of the lens to a specific position. * \param[in] position The focal point of the lens @@ -86,6 +124,10 @@ int CameraLens::init() */ int CameraLens::setFocusPosition(int32_t position) { + int ret = open(); + if (ret) + return ret; + ControlList lensCtrls(subdev_->controls()); lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, static_cast(position));