From patchwork Fri Oct 29 11:59:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14415 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 F17F5BDB1C for ; Fri, 29 Oct 2021 11:59:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4C5E5600BD; Fri, 29 Oct 2021 13:59: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="admSQWEF"; dkim-atps=neutral Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2BE1C600B8 for ; Fri, 29 Oct 2021 13:59:25 +0200 (CEST) Received: by mail-pl1-x62c.google.com with SMTP id t21so6658189plr.6 for ; Fri, 29 Oct 2021 04:59:25 -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=2k99Vr8smPJ+QwrHYW4ovDxNd1eiIO/Iakp26gWl9Ac=; b=admSQWEFN4zJRuVpxDvD4iyiOAZ5FCyNQf5p35ZUYVcxIK8uyvSIIKNcZKmshHSc+N dKQQAaDnAEUK4MNy+LhkKvrW+jTtEJVa5cqSo3jyGgTFoNayzVGPAqbEbGwCmDZ4Y1CH v/sGgZxVRF7PpcZQDJjZuOV7SkXpDy9Roahv0= 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=2k99Vr8smPJ+QwrHYW4ovDxNd1eiIO/Iakp26gWl9Ac=; b=useiUDzwR7qEtdC7fJ5TRY7S0dhz34hlewXcw675gRQ8Jzt/w4uk0VHIzEyaFXogTE L1ljs47HV/5/f7MAVZcFDHBd4RqhiJqj6dMg8tz03pfFZ2QyY2mewgkzeIJ924dXVcyV 9u8pc0b6aUwLmTKRS9ynU3/h7HpPRdMR3JTl+DYYaSN0uzkQhkCbLLrwHwL7gh9q6TOl luBoQucN6s6J1nBnIveyJBiKYQmHopqosxlbQhE8ik5TfOeMqdwemLKdwV+rRKGG5cLp vO6XnuH8c/SHjA7do7wtk9Dc+j7mcRueDqA7tFLzyNoya0azNR7Qty36S/Ny/SGOX96p j7OA== X-Gm-Message-State: AOAM533rQSbt4UWjHGP/bEr8hLYeFmx14tRB6NdCDasICaQLa0d+xYv5 lEn933kGwCcwkrALqwwbTmTZUdivxrjZ9ZKS X-Google-Smtp-Source: ABdhPJxNr3WCv5JQF64GbqtHJL3/X9RZEOQ3JLZ8A0UhBnDt8RSbXPcrYmE7mbQi2g2bo3pR07Smsw== X-Received: by 2002:a17:90b:1bcf:: with SMTP id oa15mr3358139pjb.196.1635508761838; Fri, 29 Oct 2021 04:59:21 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:35fe:d53b:684:b538]) by smtp.gmail.com with UTF8SMTPSA id t7sm6587333pfj.217.2021.10.29.04.59.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Oct 2021 04:59:21 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Fri, 29 Oct 2021 19:59:14 +0800 Message-Id: <20211029115917.2467936-1-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: , 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 Fri Oct 29 11:59:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14416 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 7FB2FBDB1C for ; Fri, 29 Oct 2021 11:59:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3407A600BF; Fri, 29 Oct 2021 13:59: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="bC5AkYXb"; dkim-atps=neutral Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 82B78600B8 for ; Fri, 29 Oct 2021 13:59:32 +0200 (CEST) Received: by mail-pg1-x534.google.com with SMTP id e65so9689451pgc.5 for ; Fri, 29 Oct 2021 04:59:32 -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=hjzU0vcbMQNXt//9GoOQNFctvc5bljeO++zFwPQaJEY=; b=bC5AkYXb0sxmIZsXY7v6NMpg2ZXYgqxa9HDGU5I94+8YiYIA2pS1RPvWriNfSAqLNS 8UD0UgU2shih1BrV14A0VUqp00JwNZOnLieTeieAT4lNU1Kd1x0CXn+ExJcqMmhq0Xxk Vs0Jfy+cKWDq2wl5fgd59aODzsHW56IVeRav0= 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=hjzU0vcbMQNXt//9GoOQNFctvc5bljeO++zFwPQaJEY=; b=SucsQhQ1K6XCrQOMT6P3MedyuCCNfeAWddu4LBDkmz3inE+KFA1+4WqT0Ws+8ZaUcQ nEs3xYaLZjdUVu5mlPEHx7Hmr2wrDd3pLoVG8WaYg1+gvfv/3QrwxWOTgXEqge7qEfUx GcE505bXIpHdsv1f610HbPQZCyApPW1FB+A0McPM1wye8hiIryXRpo0FB0SNGaesTp// 4zCl+bh4V5BX2NpOY1iYIUCefKFOreEKupMYF80t8xQZfaDeIClBial8g0gZSpWSQQ2E X7MChuQEWrwjHt0bdGT8dWOKMcbgRfhQlowkABoTe3+wuR2NDYQXB0aZ0CB/oiMkyzhr 7LOA== X-Gm-Message-State: AOAM532Ch25BSD3H60PEOi5NqSznuG54SnMCnaSid4ruFihN2T1r4m7t 6bcVupsr88MEeWMlbx3qJ1wH/8/RRFsyGVOQ X-Google-Smtp-Source: ABdhPJzvqLcLCLS7y0XS6pEBWgplhrm52gKHpiOCj7wPDIROWlczNSzh6DRA0CXM2bypwpzsHFL/PQ== X-Received: by 2002:aa7:9633:0:b0:47b:ea78:f399 with SMTP id r19-20020aa79633000000b0047bea78f399mr10213250pfg.62.1635508770253; Fri, 29 Oct 2021 04:59:30 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:35fe:d53b:684:b538]) by smtp.gmail.com with UTF8SMTPSA id s6sm7058044pfu.137.2021.10.29.04.59.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Oct 2021 04:59:30 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Fri, 29 Oct 2021 19:59:15 +0800 Message-Id: <20211029115917.2467936-2-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211029115917.2467936-1-hanlinchen@chromium.org> References: <20211029115917.2467936-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: , 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 Fri Oct 29 11:59: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: 14417 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 0D621BDB1C for ; Fri, 29 Oct 2021 11:59:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF877600BF; Fri, 29 Oct 2021 13:59:36 +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="dE4PJvvp"; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 053C5600B8 for ; Fri, 29 Oct 2021 13:59:35 +0200 (CEST) Received: by mail-pl1-x644.google.com with SMTP id n18so6684817plc.2 for ; Fri, 29 Oct 2021 04:59:34 -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=RShkMnw06HwHBhacFLM8plrYrT3Ge6TITOvE4FuF+lc=; b=dE4PJvvpOwncNQRkUxVSg6acoqxGpv4iXK24q7HAHhlbszYCzM0u5leUKxK0UjX8MV 1LfImkmH41nZ0qhEHQyF/tT+H5ggHyDEaKV9S/maJ251KaqPdwnrU7fXCe4uWvqUwvQW TEWOnoTxdo2zZ2dQrPV3SZlfy5M5Xw17xhXdY= 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=RShkMnw06HwHBhacFLM8plrYrT3Ge6TITOvE4FuF+lc=; b=LCP7OZrJSejnLFn7GSQW/HlDPuxvd1bVusWE22dkh/Hn5k5DfQJuJTMIc0vJm9Vlsq lckMveCM91+Cib0zixMSLeRDJ++v+pgjKzTd6EOGahs3vD8XdLmBFpJtw5oMXlpcf6O9 gdGDY3yNWcwR/BD9frtJ6qtiPyU4+uFJuSLDUeGAXzDDSkrYGeqjk3RWngYWvlZ+ICSD y25HMQ97SJd0KcLjkE4e2Xa25mp+RpgUhmtvrjgSr3jVx2U/ptGra1A6fQvDVSGNe6EH peYs5UNJL0VHxZkdhPT5NxIy/ngtqKrhWd+XJSaa/m06b+TCUF9/kstwBcrlWnaxJPfc thpg== X-Gm-Message-State: AOAM531Hp2uIlqHpKChstjD2Og81/a8fteHikB1y5AoM1X9VSEICd09P D4EI8v4e1esiytOAWGREcxJkon2du7YUHtmU X-Google-Smtp-Source: ABdhPJyRxXoZj6lxVc9m7XZUpanscxFCxs8Dr46RDak+lSJsaEsM7ovZxiT9zR1zH6iVqjzI1TetmQ== X-Received: by 2002:a17:90a:a609:: with SMTP id c9mr19776182pjq.134.1635508772741; Fri, 29 Oct 2021 04:59:32 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:35fe:d53b:684:b538]) by smtp.gmail.com with UTF8SMTPSA id pj12sm5899656pjb.19.2021.10.29.04.59.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Oct 2021 04:59:32 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Fri, 29 Oct 2021 19:59:16 +0800 Message-Id: <20211029115917.2467936-3-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211029115917.2467936-1-hanlinchen@chromium.org> References: <20211029115917.2467936-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: , 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 | 60 +++++ src/libcamera/camera_lens.cpp | 261 +++++++++++++++++++++ src/libcamera/meson.build | 1 + 6 files changed, 352 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..afc300cf --- /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..6a1ef164 100644 --- a/Documentation/meson.build +++ b/Documentation/meson.build @@ -61,6 +61,7 @@ if sphinx.found() 'guides/pipeline-handler.rst', 'guides/tracing.rst', 'index.rst', + 'lens_driver_requirements.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..c558ea4f --- /dev/null +++ b/include/libcamera/internal/camera_lens.h @@ -0,0 +1,60 @@ +/* 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 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..8529737c --- /dev/null +++ b/src/libcamera/camera_lens.cpp @@ -0,0 +1,261 @@ +/* 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_)); + + 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() + "'"; +} + +} /* 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 Fri Oct 29 11:59: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: 14518 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 74A65BF415 for ; Wed, 10 Nov 2021 13:56:32 +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 756B0501 for ; Wed, 10 Nov 2021 14:56:31 +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="VMpLmWUU"; dkim-atps=neutral Delivered-To: kbingham@ideasonboard.com Received: from perceval.ideasonboard.com by perceval.ideasonboard.com with LMTP id gOo7Ii3ie2EWOQAA4E0KoQ (envelope-from ) for ; Fri, 29 Oct 2021 13:59:41 +0200 Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by perceval.ideasonboard.com (Postfix) with ESMTPS id 7710A881; Fri, 29 Oct 2021 13:59:41 +0200 (CEST) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 144EF600C2; Fri, 29 Oct 2021 13:59:41 +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="VMpLmWUU"; dkim-atps=neutral Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EB0FB600B8 for ; Fri, 29 Oct 2021 13:59:38 +0200 (CEST) Received: by mail-pl1-x62d.google.com with SMTP id t11so6649490plq.11 for ; Fri, 29 Oct 2021 04:59:38 -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=WEuD6Qo9dGtBh7JN3uPzd0sh7jtrp0zRRNTgSKY7mVM=; b=VMpLmWUUkUfrUYK32D/fTkkNR4CFbpbfbCU5JUrn+UM9yfFAzdF9g3jDgKdiEPryh+ 9qIhULx0eyOeLDHeLkzgL5ZCAZlQ0gzsD86QaHpapFxjcOcuHwrppOtx2AbB+pdldSC3 lrpCfiku2HjBqO2u5B0aX+TvdMeC5KT8smzfM= 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=WEuD6Qo9dGtBh7JN3uPzd0sh7jtrp0zRRNTgSKY7mVM=; b=nNKAiO3gPZdeUjPgrZulkx5rmakA/qC0el8/IpP7BSiAuAnq+tAB2KNxkUtuzOU2HA jbrmdmc1fU1rCFN5oZmIV4P67sNH2vL7ImjI57jfML+q7/Vdc5PPMVi7k35UAYjAAFDc TCUVWe7FBfxDQg88u48m9o1rctkfYbmlGAKMcuHg/4xezzobQ63V0rydRPIt7PsDRff3 UWLjzP0e2EXqUjsZ/J37n+Imus5Y5rZD+Z9VZgjuGs6pNA95tuc70sOhWimHedIJYNFa 8FE9wQbT5WvuMT5LuKVZRsUSH6jxd6c42Oydh8Z84pPwO9bh2hqy3wdf0CjCK6YxvOdK y3rA== X-Gm-Message-State: AOAM531yrOKF21XYxCeZSIXQhKRGXB+1i78pv39dRcQ11s4wYxIJl371 CNGdQ5f89wipHGFvS1ig0UDQIiriem7CfTna X-Google-Smtp-Source: =?utf-8?q?ABdhPJzBhYNo9UUV+bIjavZ36C/3XyFbbAvri9D6t?= =?utf-8?q?Tv+pGApSXoMUbUUFN/JUMzcWN8i2VVJ91KfAg=3D=3D?= X-Received: by 2002:a17:90a:d582:: with SMTP id v2mr11077660pju.46.1635508774666; Fri, 29 Oct 2021 04:59:34 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:35fe:d53b:684:b538]) by smtp.gmail.com with UTF8SMTPSA id n29sm2224842pfv.29.2021.10.29.04.59.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Oct 2021 04:59:34 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Fri, 29 Oct 2021 19:59:17 +0800 Message-Id: <20211029115917.2467936-4-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211029115917.2467936-1-hanlinchen@chromium.org> References: <20211029115917.2467936-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" X-TUID: qXTHFnL+LICb 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..6c44957f 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 = action.lensControls; + cio2_.lens()->setControls(&lensControls); + } break; } case ipa::ipu3::ActionParamFilled: {