From patchwork Thu Oct 28 10:03:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14387 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 21527BF415 for ; Thu, 28 Oct 2021 10:03:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1EAE2600BC; Thu, 28 Oct 2021 12:03:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="WLYvL0CE"; dkim-atps=neutral Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 33939600B6 for ; Thu, 28 Oct 2021 12:03:24 +0200 (CEST) Received: by mail-pj1-x102b.google.com with SMTP id om14so4282635pjb.5 for ; Thu, 28 Oct 2021 03:03:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=exF50TRUVcuWg1k+CnOCmAP50iF7VYe1lN+LEY0vVHY=; b=WLYvL0CEh+QWtdgkTAhWLSvV4KcIxn8bLsJ0iF/Wnm+3tQVEs4VOugrvP9NI/+PC6n JhPGcYCF+yy0Tz5HoQAyoYobtmbmW/9mBkQNH2mbrbxblwKMXTpfBN/wIl0zXMfaIECz rEGdQ9pEM0Q7dbxqYV+SS1DScaESKP7wxPXWw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=exF50TRUVcuWg1k+CnOCmAP50iF7VYe1lN+LEY0vVHY=; b=7S5kRFNdcRe31VBwLPEEAMyDv53fOqeJ+sC9H90n0ZQPn/Wod2GHKTUpST7v5G0q5b 8+fQzPIyMm7iLiXE1pKQHY7MJKHd+2kSqeo4JBNEkck5cpFVA7t2d8l1081XcHJG8qwV 3L8FlCa0H3KjJnCyXzsDn+rBLNydiWZWVbXS6/MCv+4x/SLPhnplfvlr2BqojifbSx6+ g8pdbOOKF3f9XeMeYgCZ7HWEmp5H7lUFPLFLHiy359kfLFTkpfDc74v5pXuI9gCCE6cY 01/J+J+AhB6H3MorTKLpuXAGuXXH2FAKsTXa+NRUo0Zb9gYwu6COFkC33jNRxZp6AfAH ZwaA== X-Gm-Message-State: AOAM533KolEw/p1OsjXuR3IkVL+atFiUD/Lv0WKv+KKj+89B2wffqwR9 cge3na8SpvMJowIUe7ZsaLM5NtUgd5qjBACu X-Google-Smtp-Source: ABdhPJxCPiFDoGJJZy/7L+9YP9u9LxKJU4k0CMhIEbH5vufCm301c7PFryH/2ZebV+DTxg2XNvF9fA== X-Received: by 2002:a17:90a:db02:: with SMTP id g2mr11655964pjv.158.1635415402540; Thu, 28 Oct 2021 03:03:22 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id l1sm2325588pgt.39.2021.10.28.03.03.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:22 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:16 +0800 Message-Id: <20211028100319.1097720-1-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/4] ipa: ipu3: Extend ipu3 ipa interface for sensor and lens controls 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: , Cc: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" IPU3Event and IPU3Action use single ControlList for both libcamera and V4L2 controls, and it's content could be either one based on the context. Extend IPU3Event and IPU3Action for sensor and lens V4L2 controls, and preserve the original one for only libcamera Controls to make the content of an event more specific. Signed-off-by: Han-Lin Chen --- include/libcamera/ipa/ipu3.mojom | 4 ++++ src/ipa/ipu3/ipu3.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom index 2f254ed4..cc0d822f 100644 --- a/include/libcamera/ipa/ipu3.mojom +++ b/include/libcamera/ipa/ipu3.mojom @@ -23,11 +23,15 @@ struct IPU3Event { int64 frameTimestamp; uint32 bufferId; libcamera.ControlList controls; + libcamera.ControlList sensorControls; + libcamera.ControlList lensControls; }; struct IPU3Action { IPU3Operations op; libcamera.ControlList controls; + libcamera.ControlList sensorControls; + libcamera.ControlList lensControls; }; struct IPAConfigInfo { diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 5c51607d..6775570e 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -646,7 +646,7 @@ void IPAIPU3::setControls(unsigned int frame) ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); - op.controls = ctrls; + op.sensorControls = ctrls; queueFrameAction.emit(frame, op); } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index eb714aa6..8816efc5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1248,7 +1248,7 @@ void IPU3CameraData::queueFrameAction(unsigned int id, { switch (action.op) { case ipa::ipu3::ActionSetSensorControls: { - const ControlList &controls = action.controls; + const ControlList &controls = action.sensorControls; delayedCtrls_->push(controls); break; } From patchwork Thu Oct 28 10:03:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14388 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 6A483BF415 for ; Thu, 28 Oct 2021 10:03:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1B08E600C4; Thu, 28 Oct 2021 12:03:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="fslmLtEX"; dkim-atps=neutral Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3AB7C600BF for ; Thu, 28 Oct 2021 12:03:26 +0200 (CEST) Received: by mail-pj1-x102b.google.com with SMTP id nn3-20020a17090b38c300b001a03bb6c4ebso4282952pjb.1 for ; Thu, 28 Oct 2021 03:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KwoGT7NzquHqxePhlUMI5IGOo9vSGuIcTWArhUGmf98=; b=fslmLtEXoftsGPnXpqatmwWxnSqo5Q62ZnK4fTvhGa7c/I0Ew+eaJjMJRkQurKQtQv oBhjN47++KCRDLUu9reWWjWZb0pHl+WYLaXXzQkcVMltflKRLT1gsxW3dT9GudVVGD1x Fjfu2Fws7hjqwlJ7SOpYfpgaOjCKoS2QpYnLI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KwoGT7NzquHqxePhlUMI5IGOo9vSGuIcTWArhUGmf98=; b=0LWvP6he48IpWbYBZO0ozoRAA5+NT6ngoJpClxzVIe1MCybybSHP2eRJWw4fsoL9Bb nQT5j9fTjrd2ZJQ+b8n1b+M5ocV43O4nrkF6vYfA1vLThQozJeg2upwsVExgDNPScVPD 1JX+JfkNNOyTxhgkYFz8rarzTUsnEN0OP2dR2QsN+qc5D0gp0REAIvh4UPBT7kmUYXTY UW4hmthi+YY7Uh/qV+8UL94O38LX5CuRMWy5lJ8KHsR5Wqzv85oYIIuK410yYV7j+LsH eg7399GqDMu1ufrrjLU+qYxFw9Zc7TxsIg4wGJ+FDcfi1ysggQdyNCEqgEpVFNeKbhDi o8Mw== X-Gm-Message-State: AOAM531PwEj5UYxFX7rNUbE+oKNSLsKAeDgTRZtLMFOzQZNqx0FR9YAL ZbGd7W3wi9UFIyRH/9Rh0cAifyw+rKS+JTyT X-Google-Smtp-Source: ABdhPJwsxFMF4mEl1k5V0gUUsS3SbuZEQ118xtDza7sllhAv2KfT9GSU+70nEczfRMb5RBwOFuA+hQ== X-Received: by 2002:a17:90b:1bce:: with SMTP id oa14mr11714387pjb.225.1635415404560; Thu, 28 Oct 2021 03:03:24 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id y13sm2960550pfa.43.2021.10.28.03.03.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:24 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:17 +0800 Message-Id: <20211028100319.1097720-2-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211028100319.1097720-1-hanlinchen@chromium.org> References: <20211028100319.1097720-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] ipu3: ipa: Report effective sensor controls with stastistics to IPA 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: , Cc: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Intel close sourced IPA requires the effective controls applied to the sensor when the stastistics are generated. Report effective sensor controls with the stastistics to IPA. Signed-off-by: Han-Lin Chen --- src/libcamera/pipeline/ipu3/frames.h | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h index 3ef7e445..a897e307 100644 --- a/src/libcamera/pipeline/ipu3/frames.h +++ b/src/libcamera/pipeline/ipu3/frames.h @@ -12,6 +12,7 @@ #include #include +#include #include namespace libcamera { @@ -34,6 +35,8 @@ public: FrameBuffer *paramBuffer; FrameBuffer *statBuffer; + ControlList effectiveSensorControls; + bool paramDequeued; bool metadataProcessed; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 8816efc5..6a7f5b9a 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -667,6 +667,8 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) return ret; } + data->delayedCtrls_->reset(); + return updateControls(data); } @@ -1363,6 +1365,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) request->metadata().set(controls::SensorTimestamp, buffer->metadata().timestamp); + info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence); + if (request->findBuffer(&rawStream_)) pipe()->completeBuffer(request, buffer); @@ -1419,6 +1423,7 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer) ev.frame = info->id; ev.bufferId = info->statBuffer->cookie(); ev.frameTimestamp = request->metadata().get(controls::SensorTimestamp); + ev.sensorControls = info->effectiveSensorControls; ipa_->processEvent(ev); } From patchwork Thu Oct 28 10:03:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14389 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 0F0E6BF415 for ; Thu, 28 Oct 2021 10:03:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B9ECD600C8; Thu, 28 Oct 2021 12:03:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="dyupfWlM"; dkim-atps=neutral Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 649FB600B6 for ; Thu, 28 Oct 2021 12:03:28 +0200 (CEST) Received: by mail-pl1-x643.google.com with SMTP id y1so4050310plk.10 for ; Thu, 28 Oct 2021 03:03:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=T+YtwfVKPiRerZyKIcMAPnGgKqs6QOneDYJcS89O0CE=; b=dyupfWlMc/3XX5zvCszuO8av/LTdmlgivc51d8CGv41Jar/syqIS2QVPtbwyQHA4G7 7NF2eDU5O1lMiHG2g8yOg60gwttXVsO+bq7LsZI40TqpTDEIX9vZjCNpsU9rOMu0Jo4y RC/Kk2y6jnO+ntdlKECphgCAxxYsqROSfv43s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=T+YtwfVKPiRerZyKIcMAPnGgKqs6QOneDYJcS89O0CE=; b=njIZb8DKPZCHRBuXQaophMcjJdS8x1MBmTSuD1Sp8CNSvJxXhhNV8O/uw1lVewoP64 okVOXOxUZUplvNAIoKzvJFDTo9RXMp0widKM500uDyjEewnK9oYrQeI9dUq0x7bsjlC6 WM2PLcYdgD7ngDv6CGfg8kD5Uubux9qKkU+NLIgN5shuu6reGgOyoTm41fcewQm7YDz5 Ag634OUxBT2dqJVnaq16evE0cpEjp1q6dTMcKC1EecLLBCXQrLuBo0liu0w+nMSV7VX4 elyAeac8MY/jIIJk1Xn5a9CULYxtz93CRyI5+lBKHvPRM8d7kMa1NbQglNTJFfrmWvaq WFwg== X-Gm-Message-State: AOAM532A/8oNCwRF0/HutWC4Qi5MYZZFSYMxa3eh1AW2o70/t/B7En4w m4P5FxbgS2sXrLZPD2wBlBnss/3SXMrgjUZi X-Google-Smtp-Source: ABdhPJy3Yuy8DEKYx5GHYyp0VNIldRc51gP7JZV4O7AlWJpx7ZFQqGAdEhbdc2r7ADHvBBaK/yY8lg== X-Received: by 2002:a17:90a:d583:: with SMTP id v3mr3455334pju.216.1635415406654; Thu, 28 Oct 2021 03:03:26 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id s21sm3086735pfk.175.2021.10.28.03.03.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:26 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:18 +0800 Message-Id: <20211028100319.1097720-3-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211028100319.1097720-1-hanlinchen@chromium.org> References: <20211028100319.1097720-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/4] libcamera: camera_lens: Add a new class to model a camera lens 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: , Cc: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The CameraLens class abstracts camera lens and provides helper functions to ease interactions with them. Signed-off-by: Han-Lin Chen --- Documentation/index.rst | 1 + Documentation/lens_driver_requirements.rst | 28 ++ Documentation/meson.build | 1 + include/libcamera/internal/camera_lens.h | 61 +++++ src/libcamera/camera_lens.cpp | 289 +++++++++++++++++++++ src/libcamera/meson.build | 1 + 6 files changed, 381 insertions(+) create mode 100644 Documentation/lens_driver_requirements.rst create mode 100644 include/libcamera/internal/camera_lens.h create mode 100644 src/libcamera/camera_lens.cpp diff --git a/Documentation/index.rst b/Documentation/index.rst index 1f4fc485..0ee10044 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -21,3 +21,4 @@ Tracing guide Environment variables Sensor driver requirements + Lens driver requirements diff --git a/Documentation/lens_driver_requirements.rst b/Documentation/lens_driver_requirements.rst new file mode 100644 index 00000000..226cb813 --- /dev/null +++ b/Documentation/lens_driver_requirements.rst @@ -0,0 +1,28 @@ +.. SPDX-License-Identifier: CC-BY-SA-4.0 + +.. _lens-driver-requirements: + +Lens Driver Requirements +========================== + +libcamera handles lens devices in the CameraLens class and defines +a consistent interface through its API towards other library components. + +The CameraLens class uses the V4L2 subdev kernel API to interface with the +camera lens through one or multiple sub-devices exposed in userspace by +the lens driver. + +In order for libcamera to be fully operational and provide all the required +information to interface with the camera lens to applications and pipeline +handlers, a set of mandatory features the driver has to support has been defined. + +Mandatory Requirements +---------------------- + +The lens driver is assumed to be fully compliant with the V4L2 specification. + +The lens driver shall support the following V4L2 controls: + +* `V4L2_CID_FOCUS_ABSOLUTE`_ + +.. _V4L2_CID_FOCUS_ABSOLUTE: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/ext-ctrls-camera.html diff --git a/Documentation/meson.build b/Documentation/meson.build index df36a808..746af4cf 100644 --- a/Documentation/meson.build +++ b/Documentation/meson.build @@ -60,6 +60,7 @@ if sphinx.found() 'guides/ipa.rst', 'guides/pipeline-handler.rst', 'guides/tracing.rst', + 'lens_driver_requirements.rst', 'index.rst', 'sensor_driver_requirements.rst', '../README.rst', diff --git a/include/libcamera/internal/camera_lens.h b/include/libcamera/internal/camera_lens.h new file mode 100644 index 00000000..f03de5fc --- /dev/null +++ b/include/libcamera/internal/camera_lens.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * camera_lens.h - A camera lens + */ +#ifndef __LIBCAMERA_INTERNAL_CAMERA_LENS_H__ +#define __LIBCAMERA_INTERNAL_CAMERA_LENS_H__ + +#include +#include + +#include +#include "libcamera/internal/v4l2_subdevice.h" + +namespace libcamera { + +class MediaEntity; + +class CameraLens : protected Loggable +{ +public: + explicit CameraLens(const MediaEntity *entity); + ~CameraLens(); + + int init(); + + const std::string &model() const { return model_; } + const std::string &id() const { return id_; } + const MediaEntity *entity() const { return entity_; } + + const ControlInfoMap &controls() const; + ControlList getControls(const std::vector &ids); + int setControls(ControlList *ctrls); + + V4L2Subdevice *device() { return subdev_.get(); } + + const ControlList &properties() const { return properties_; } + +protected: + std::string logPrefix() const override; + +private: + LIBCAMERA_DISABLE_COPY(CameraLens) + + int generateId(); + int validateLensDriver(); + int initProperties(); + + const MediaEntity *entity_; + std::unique_ptr subdev_; + + std::string model_; + std::string id_; + + ControlList properties_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_INTERNAL_CAMERA_LENS_H__ */ diff --git a/src/libcamera/camera_lens.cpp b/src/libcamera/camera_lens.cpp new file mode 100644 index 00000000..0c80d3c3 --- /dev/null +++ b/src/libcamera/camera_lens.cpp @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * camera_lens.cpp - A camera lens + */ + +#include "libcamera/internal/camera_lens.h" +#include "libcamera/internal/media_device.h" + +#include + +#include + +#include "libcamera/internal/sysfs.h" + +/** + * \file camera_lens.h + * \brief A camera lens + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(CameraLens) + +/** + * \class CameraLens + * \brief A camera lens based on V4L2 subdevices + * + * The CameraLens class eases handling of lens for pipeline handlers by + * hiding the details of the V4L2 subdevice kernel API and caching lens + * information. + * + * The implementation is currently limited to lens that expose a single V4L2 + * subdevice. It will be extended to support more complex devices as the needs + * arise. + */ + +/** + * \brief Construct a CameraLens + * \param[in] entity The media entity backing the camera lens + * + * Once constructed the instance must be initialized with init(). + */ +CameraLens::CameraLens(const MediaEntity *entity) + : entity_(entity), + properties_(properties::properties) +{ +} + +/** + * \brief Destroy a CameraLens + */ +CameraLens::~CameraLens() +{ +} + +/** + * \brief Initialize the camera lens instance + * + * This function performs the initialisation steps of the CameraLens that may + * fail. It shall be called once and only once after constructing the instance. + * + * \return 0 on success or a negative error code otherwise + */ +int CameraLens::init() +{ + if (entity_->function() != MEDIA_ENT_F_LENS) { + LOG(CameraLens, Error) + << "Invalid lens function " + << utils::hex(entity_->function()); + return -EINVAL; + } + + /* Create and open the subdev. */ + subdev_ = std::make_unique(entity_); + int ret = subdev_->open(); + if (ret < 0) + return ret; + + ret = validateLensDriver(); + if (ret) + return ret; + + ret = initProperties(); + if (ret) + return ret; + + return 0; +} + +int CameraLens::validateLensDriver() +{ + int err = 0; + static constexpr uint32_t mandatoryControls[] = { + V4L2_CID_FOCUS_ABSOLUTE + }; + + const ControlInfoMap &controls = subdev_->controls(); + for (uint32_t ctrl : mandatoryControls) { + if (!controls.count(ctrl)) { + LOG(CameraLens, Error) + << "Mandatory V4L2 control " << utils::hex(ctrl) + << " not available"; + err = -EINVAL; + } + } + + if (err) { + LOG(CameraLens, Error) + << "The lens kernel driver needs to be fixed"; + LOG(CameraLens, Error) + << "See Documentation/lens_driver_requirements.rst in the libcamera sources for more information"; + return err; + } + + return 0; +} + +int CameraLens::initProperties() +{ + /* + * Extract the camera lens model name from the media entity name. + * + * There is no standardized naming scheme for lens entities in the + * Linux kernel at the moment. + * + * - The most common rule, used by I2C lens, associates the model + * name with the I2C bus number and address (e.g. 'dw9714 8-000c'). + * + * Other schemes probably exist. As a best effort heuristic, use the + * part of the entity name before the first space if the name contains + * an I2C address, and use the full entity name otherwise. + */ + std::string entityName = entity_->name(); + std::regex i2cRegex{ " [0-9]+-[0-9a-f]{4}" }; + std::smatch match; + + if (std::regex_search(entityName, match, i2cRegex)) + model_ = entityName.substr(0, entityName.find(' ')); + else + model_ = entityName; + + properties_.set(properties::Model, utils::toAscii(model_)); + + /* Generate a unique ID for the lens. */ + int ret = generateId(); + if (ret) + return ret; + + return 0; +} + +/** + * \fn CameraLens::model() + * \brief Retrieve the lens model name + * + * The lens model name is a free-formed string that uniquely identifies the + * lens model. + * + * \return The lens model name + */ + +/** + * \fn CameraLens::id() + * \brief Retrieve the lens ID + * + * The lens ID is a free-form string that uniquely identifies the lens in + * the system. + * + * \return The lens ID + */ + +/** + * \fn CameraLens::entity() + * \brief Retrieve the lens media entity + * \return The lens media entity + */ + +/** + * \brief Retrieve the supported V4L2 controls and their information + * + * Control information is updated automatically to reflect the current lens + * configuration when the setFormat() function is called, without invalidating + * any iterator on the ControlInfoMap. + * + * \return A map of the V4L2 controls supported by the lens + */ +const ControlInfoMap &CameraLens::controls() const +{ + return subdev_->controls(); +} + +/** + * \brief Read V4L2 controls from the lens + * \param[in] ids The list of controls to read, specified by their ID + * + * This function reads the value of all controls contained in \a ids, and + * returns their values as a ControlList. The control identifiers are defined by + * the V4L2 specification (V4L2_CID_*). + * + * If any control in \a ids is not supported by the device, is disabled (i.e. + * has the V4L2_CTRL_FLAG_DISABLED flag set), or if any other error occurs + * during validation of the requested controls, no control is read and this + * function returns an empty control list. + * + * \sa V4L2Device::getControls() + * + * \return The control values in a ControlList on success, or an empty list on + * error + */ +ControlList CameraLens::getControls(const std::vector &ids) +{ + return subdev_->getControls(ids); +} + +/** + * \brief Write V4L2 controls to the lens + * \param[in] ctrls The list of controls to write + * + * This function writes the value of all controls contained in \a ctrls, and + * stores the values actually applied to the device in the corresponding \a + * ctrls entry. The control identifiers are defined by the V4L2 specification + * (V4L2_CID_*). + * + * If any control in \a ctrls is not supported by the device, is disabled (i.e. + * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, or if any other + * error occurs during validation of the requested controls, no control is + * written and this function returns -EINVAL. + * + * If an error occurs while writing the controls, the index of the first + * control that couldn't be written is returned. All controls below that index + * are written and their values are updated in \a ctrls, while all other + * controls are not written and their values are not changed. + * + * \sa V4L2Device::setControls() + * + * \return 0 on success or an error code otherwise + * \retval -EINVAL One of the control is not supported or not accessible + * \retval i The index of the control that failed + */ +int CameraLens::setControls(ControlList *ctrls) +{ + return subdev_->setControls(ctrls); +} + +/** + * \fn CameraLens::device() + * \brief Retrieve the camera lens device + * \todo Remove this function by integrating DelayedControl with CameraLens + * \return The camera lens device + */ + +/** + * \fn CameraLens::properties() + * \brief Retrieve the camera lens properties + * \return The list of camera lens properties + */ + +std::string CameraLens::logPrefix() const +{ + return "'" + entity_->name() + "'"; +} + +int CameraLens::generateId() +{ + const std::string devPath = subdev_->devicePath(); + + /* Try to get ID from firmware description. */ + id_ = sysfs::firmwareNodePath(devPath); + if (!id_.empty()) + return 0; + + /* + * Virtual lens not described in firmware + * + * Verify it's a platform device and construct ID from the device path + * and model of lens. + */ + if (devPath.find("/sys/devices/platform/", 0) == 0) { + id_ = devPath.substr(strlen("/sys/devices/")) + " " + model(); + return 0; + } + + LOG(CameraLens, Error) << "Can't generate lens ID"; + return -EINVAL; +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 6727a777..3bee8fee 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_sources = files([ 'byte_stream_buffer.cpp', 'camera.cpp', 'camera_controls.cpp', + 'camera_lens.cpp', 'camera_manager.cpp', 'camera_sensor.cpp', 'camera_sensor_properties.cpp', From patchwork Thu Oct 28 10:03:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14503 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by patchwork.libcamera.org (Postfix) with ESMTPS id B424EBDB1C for ; Tue, 9 Nov 2021 19:29:41 +0000 (UTC) Received: from pendragon.ideasonboard.com (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B8211FD1 for ; Tue, 9 Nov 2021 20:29:40 +0100 (CET) Authentication-Results: perceval.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Zl7+Gub+"; dkim-atps=neutral Delivered-To: kbingham@ideasonboard.com Received: from perceval.ideasonboard.com by perceval.ideasonboard.com with LMTP id yFXLNHV1emFzBgAA4E0KoQ (envelope-from ) for ; Thu, 28 Oct 2021 12:03:33 +0200 Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by perceval.ideasonboard.com (Postfix) with ESMTPS id C2992513; Thu, 28 Oct 2021 12:03:33 +0200 (CEST) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 58ABE60103; Thu, 28 Oct 2021 12:03:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Zl7+Gub+"; dkim-atps=neutral Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6082F600B6 for ; Thu, 28 Oct 2021 12:03:30 +0200 (CEST) Received: by mail-pg1-x52f.google.com with SMTP id r28so5964027pga.0 for ; Thu, 28 Oct 2021 03:03:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v3TIv1B+NBMqukcEHLimuJfzih/lGpnEG+7CxByQeSE=; b=Zl7+Gub+W7rkKOp5L8m8GafmFpZUp2/Zjv8gSuVs3ZTW+chV1uuI74y+3ukO/QXCj0 +n05ir1eb4zojujB8S7YpSJqsbXTWt6oJlErieFRx3YdIY284eOE1tG8FqyC4CTMR2Em 3c64Smi6oipZr2gbpROwbFly1Vh/QtboBM/Nk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v3TIv1B+NBMqukcEHLimuJfzih/lGpnEG+7CxByQeSE=; b=GhmdiX4MuFn6zhb3ovfTm9osLb4Chl0LtSuJNL2DxFLeuKVYRn1kaZtLDgyVCY8EMB SBikDRKvy7tqEyuqoa1uUpdQDUUE4GxNRZCQEgxGIzF0YKFfwozpxIDNSe1OdvNUqmmN FrgKJylG5kUDnAIuSLJ4gn4VkVGQuAYuWtGuwPRnE/4xG1q8ONQgcQVpsMmtexKwjKkj 2XU+0tRBH1XnsUgYw3qzKGNlsqen/HxHOABcx8Fsob6gG3yifwcHcT6oNURvOgL6ZkUA Qzjypci9SBDieRo04l1Jr7ww3U0YnAaVsEyfZg4hCXiGMFmGirQ0Y/NCRICITWbXSmM4 LkFw== X-Gm-Message-State: AOAM5338YSrTQllk/HzsINrlNbVXVLJXv+V7PSWs3biQ40oGd3F9Cx1u XygSim6YKIq7NDsBfZj7b1tzoE7668RyD4nb X-Google-Smtp-Source: =?utf-8?q?ABdhPJwLEFuGH4Yz6STOAS5u+Prpk5ko5q0XTjW7w?= =?utf-8?q?QdjDe+gIRhJbVphF2tj5zwFn1vtOBExR3OvuQ=3D=3D?= X-Received: by 2002:a63:a80c:: with SMTP id o12mr2447140pgf.422.1635415408736; Thu, 28 Oct 2021 03:03:28 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id f4sm2241488pgn.93.2021.10.28.03.03.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:28 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:19 +0800 Message-Id: <20211028100319.1097720-4-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211028100319.1097720-1-hanlinchen@chromium.org> References: <20211028100319.1097720-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] ipu3: ipa: Allow IPA to apply controls to the lens device 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: , Cc: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" X-TUID: 09URPkhGSLE3 Resent-From: Kieran Bingham Resent-To: parsemail@patchwork.libcamera.org Allow IPA to apply controls to the lens device. Signed-off-by: Han-Lin Chen --- meson.build | 6 ++++++ src/libcamera/pipeline/ipu3/cio2.cpp | 30 ++++++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/cio2.h | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 9 +++++++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 7892a9e3..2a4b68a2 100644 --- a/meson.build +++ b/meson.build @@ -108,6 +108,12 @@ if cc.has_argument('-Wno-c99-designator') ] endif +if get_option('android_platform') == 'cros' + common_arguments += [ + '-DOS_CHROMEOS', + ] +endif + c_arguments += common_arguments cpp_arguments += common_arguments diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 59dda56b..143e2a95 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -16,6 +16,7 @@ #include #include +#include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" @@ -159,6 +160,35 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) return -EINVAL; } +#if defined(OS_CHROMEOS) + /* + * \todo Read the lens model from the sensor itself or from a device database. + * For now use default values taken from ChromeOS. + */ + static std::unordered_map sensorLens = { + { "ov13858", "dw9714" }, + { "imx258", "dw9807" }, + { "imx355", "ak7375" } + }; + + auto it = sensorLens.find(sensor_->model()); + if (it != sensorLens.end()) { + const std::vector &entities = media->entities(); + for (auto ent: entities) { + if (ent->function() == MEDIA_ENT_F_LENS) { + lens_ = std::make_unique(ent); + ret = lens_->init(); + if (!ret && lens_->model() == it->second) { + break; + } + lens_.reset(); + } + if (!lens_) + LOG(IPU3, Warning) << "Lens device " << it->second << " not found"; + } + } +#endif + /* * \todo Define when to open and close video device nodes, as they * might impact on power consumption. diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index ba8f0052..635566c8 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -18,6 +18,7 @@ namespace libcamera { +class CameraLens; class CameraSensor; class FrameBuffer; class MediaDevice; @@ -52,6 +53,7 @@ public: int stop(); CameraSensor *sensor() { return sensor_.get(); } + CameraLens *lens() { return lens_.get(); } const CameraSensor *sensor() const { return sensor_.get(); } FrameBuffer *queueBuffer(Request *request, FrameBuffer *rawBuffer); @@ -67,6 +69,7 @@ private: void cio2BufferReady(FrameBuffer *buffer); std::unique_ptr sensor_; + std::unique_ptr lens_; std::unique_ptr csi2_; std::unique_ptr output_; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 6a7f5b9a..36e93fb0 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -24,6 +24,7 @@ #include #include "libcamera/internal/camera.h" +#include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" @@ -1250,8 +1251,12 @@ void IPU3CameraData::queueFrameAction(unsigned int id, { switch (action.op) { case ipa::ipu3::ActionSetSensorControls: { - const ControlList &controls = action.sensorControls; - delayedCtrls_->push(controls); + const ControlList &sensorControls = action.sensorControls; + delayedCtrls_->push(sensorControls); + if (cio2_.lens()) { + ControlList& lensControls = const_cast(action.lensControls); + cio2_.lens()->setControls(&lensControls); + } break; } case ipa::ipu3::ActionParamFilled: {