[{"id":21553,"web_url":"https://patchwork.libcamera.org/comment/21553/","msgid":"<4a168185-1621-3871-3099-ed843ed6bb94@ideasonboard.com>","date":"2021-12-02T17:11:12","subject":"Re: [libcamera-devel] [PATCH v7 3/5] libcamera: camera_lens: Add a\n\tnew class to model a camera lens","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Han-Lin\n\nThank you for the patch.\n\nOn 12/2/21 7:33 PM, Han-Lin Chen wrote:\n> The CameraLens class abstracts camera lens and provides helper\n> functions to ease interactions with them.\n>\n> Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n\nLooks good,\n\nReviewed-by: Umang Jain <umang.jain@ideasonboard.com>\n\n> ---\n>   Documentation/index.rst                    |   1 +\n>   Documentation/lens_driver_requirements.rst |  27 ++++\n>   Documentation/meson.build                  |   1 +\n>   include/libcamera/internal/camera_lens.h   |  45 +++++++\n>   include/libcamera/internal/meson.build     |   1 +\n>   src/libcamera/camera_lens.cpp              | 142 +++++++++++++++++++++\n>   src/libcamera/meson.build                  |   1 +\n>   7 files changed, 218 insertions(+)\n>   create mode 100644 Documentation/lens_driver_requirements.rst\n>   create mode 100644 include/libcamera/internal/camera_lens.h\n>   create mode 100644 src/libcamera/camera_lens.cpp\n>\n> diff --git a/Documentation/index.rst b/Documentation/index.rst\n> index 1f4fc485..0ee10044 100644\n> --- a/Documentation/index.rst\n> +++ b/Documentation/index.rst\n> @@ -21,3 +21,4 @@\n>      Tracing guide <guides/tracing>\n>      Environment variables <environment_variables>\n>      Sensor driver requirements <sensor_driver_requirements>\n> +   Lens driver requirements <lens_driver_requirements>\n> diff --git a/Documentation/lens_driver_requirements.rst b/Documentation/lens_driver_requirements.rst\n> new file mode 100644\n> index 00000000..b96e502d\n> --- /dev/null\n> +++ b/Documentation/lens_driver_requirements.rst\n> @@ -0,0 +1,27 @@\n> +.. SPDX-License-Identifier: CC-BY-SA-4.0\n> +\n> +.. _lens-driver-requirements:\n> +\n> +Lens Driver Requirements\n> +========================\n> +\n> +libcamera handles lens devices in the CameraLens class and defines\n> +a consistent interface through its API towards other library components.\n> +\n> +The CameraLens class uses the V4L2 subdev kernel API to interface with the\n> +camera lens through a sub-device exposed to userspace by the lens driver.\n> +\n> +In order for libcamera to be fully operational and provide all the required\n> +information to interface with the camera lens to applications and pipeline\n> +handlers, a set of mandatory features the driver has to support has been defined.\n> +\n> +Mandatory Requirements\n> +----------------------\n> +\n> +The lens driver is assumed to be fully compliant with the V4L2 specification.\n> +\n> +The lens driver shall support the following V4L2 controls:\n> +\n> +* `V4L2_CID_FOCUS_ABSOLUTE`_\n> +\n> +.. _V4L2_CID_FOCUS_ABSOLUTE: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/ext-ctrls-camera.html\n> diff --git a/Documentation/meson.build b/Documentation/meson.build\n> index 4c972675..33af82aa 100644\n> --- a/Documentation/meson.build\n> +++ b/Documentation/meson.build\n> @@ -66,6 +66,7 @@ if sphinx.found()\n>           'guides/pipeline-handler.rst',\n>           'guides/tracing.rst',\n>           'index.rst',\n> +        'lens_driver_requirements.rst',\n>           'sensor_driver_requirements.rst',\n>          '../README.rst',\n>       ]\n> diff --git a/include/libcamera/internal/camera_lens.h b/include/libcamera/internal/camera_lens.h\n> new file mode 100644\n> index 00000000..6f2ea1bc\n> --- /dev/null\n> +++ b/include/libcamera/internal/camera_lens.h\n> @@ -0,0 +1,45 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Google Inc.\n> + *\n> + * camera_lens.h - A camera lens controller\n> + */\n> +#pragma once\n> +\n> +#include <memory>\n> +#include <string>\n> +\n> +#include <libcamera/base/class.h>\n> +#include <libcamera/base/log.h>\n> +\n> +namespace libcamera {\n> +\n> +class MediaEntity;\n> +class V4L2Subdevice;\n> +\n> +class CameraLens : protected Loggable\n> +{\n> +public:\n> +\texplicit CameraLens(const MediaEntity *entity);\n> +\t~CameraLens();\n> +\n> +\tint init();\n> +\tint setFocusPostion(int32_t position);\n> +\n> +\tconst std::string &model() const { return model_; }\n> +\n> +protected:\n> +\tstd::string logPrefix() const override;\n> +\n> +private:\n> +\tLIBCAMERA_DISABLE_COPY_AND_MOVE(CameraLens)\n> +\n> +\tint validateLensDriver();\n> +\n> +\tconst MediaEntity *entity_;\n> +\tstd::unique_ptr<V4L2Subdevice> subdev_;\n> +\n> +\tstd::string model_;\n> +};\n> +\n> +} /* namespace libcamera */\n> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\n> index 665fd6de..a96bbb95 100644\n> --- a/include/libcamera/internal/meson.build\n> +++ b/include/libcamera/internal/meson.build\n> @@ -14,6 +14,7 @@ libcamera_internal_headers = files([\n>       'byte_stream_buffer.h',\n>       'camera.h',\n>       'camera_controls.h',\n> +    'camera_lens.h',\n>       'camera_sensor.h',\n>       'camera_sensor_properties.h',\n>       'control_serializer.h',\n> diff --git a/src/libcamera/camera_lens.cpp b/src/libcamera/camera_lens.cpp\n> new file mode 100644\n> index 00000000..189cb025\n> --- /dev/null\n> +++ b/src/libcamera/camera_lens.cpp\n> @@ -0,0 +1,142 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Google Inc.\n> + *\n> + * camera_lens.cpp - A camera lens\n> + */\n> +\n> +#include \"libcamera/internal/camera_lens.h\"\n> +\n> +#include <libcamera/base/utils.h>\n> +\n> +#include \"libcamera/internal/v4l2_subdevice.h\"\n> +\n> +/**\n> + * \\file camera_lens.h\n> + * \\brief A camera lens controller\n> + */\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(CameraLens)\n> +\n> +/**\n> + * \\class CameraLens\n> + * \\brief A camera lens based on V4L2 subdevices\n> + *\n> + * The CameraLens class eases handling of lens for pipeline handlers by\n> + * hiding the details of the V4L2 subdevice kernel API and caching lens\n> + * information.\n> + */\n> +\n> +/**\n> + * \\brief Construct a CameraLens\n> + * \\param[in] entity The media entity backing the camera lens controller\n> + *\n> + * Once constructed the instance must be initialized with init().\n> + */\n> +CameraLens::CameraLens(const MediaEntity *entity)\n> +\t: entity_(entity)\n> +{\n> +}\n> +\n> +/**\n> + * \\brief Destroy a CameraLens\n> + */\n> +CameraLens::~CameraLens() = default;\n> +\n> +/**\n> + * \\brief Initialize the camera lens instance\n> + *\n> + * This function performs the initialisation steps of the CameraLens that may\n> + * fail. It shall be called once and only once after constructing the instance.\n> + *\n> + * \\return 0 on success or a negative error code otherwise\n> + */\n> +int CameraLens::init()\n> +{\n> +\tif (entity_->function() != MEDIA_ENT_F_LENS) {\n> +\t\tLOG(CameraLens, Error)\n> +\t\t\t<< \"Invalid lens function \"\n> +\t\t\t<< utils::hex(entity_->function());\n> +\t\treturn -EINVAL;\n> +\t}\n> +\n> +\t/* Create and open the subdev. */\n> +\tsubdev_ = std::make_unique<V4L2Subdevice>(entity_);\n> +\tint ret = subdev_->open();\n> +\tif (ret < 0)\n> +\t\treturn ret;\n> +\n> +\tret = validateLensDriver();\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tmodel_ = subdev_->model();\n> +\treturn 0;\n> +}\n> +\n> +/**\n> + * \\brief This function sets the focal point of the lens to a specific position.\n> + * \\param[in] position The focal point of the lens\n> + *\n> + * This function sets the value of focal point of the lens as in \\a position.\n> + *\n> + * \\return 0 on success or -EINVAL otherwise\n> + */\n> +int CameraLens::setFocusPostion(int32_t position)\n> +{\n> +\tControlList lensCtrls(subdev_->controls());\n> +\tlensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, static_cast<int32_t>(position));\n> +\n> +\tif (subdev_->setControls(&lensCtrls))\n> +\t\treturn -EINVAL;\n> +\n> +\treturn 0;\n> +}\n> +\n> +int CameraLens::validateLensDriver()\n> +{\n> +\tint ret = 0;\n> +\tstatic constexpr uint32_t mandatoryControls[] = {\n> +\t\tV4L2_CID_FOCUS_ABSOLUTE,\n> +\t};\n> +\n> +\tconst ControlInfoMap &controls = subdev_->controls();\n> +\tfor (uint32_t ctrl : mandatoryControls) {\n> +\t\tif (!controls.count(ctrl)) {\n> +\t\t\tLOG(CameraLens, Error)\n> +\t\t\t\t<< \"Mandatory V4L2 control \" << utils::hex(ctrl)\n> +\t\t\t\t<< \" not available\";\n> +\t\t\tret = -EINVAL;\n> +\t\t}\n> +\t}\n> +\n> +\tif (ret) {\n> +\t\tLOG(CameraLens, Error)\n> +\t\t\t<< \"The lens kernel driver needs to be fixed\";\n> +\t\tLOG(CameraLens, Error)\n> +\t\t\t<< \"See Documentation/lens_driver_requirements.rst in\"\n> +\t\t\t<< \" the libcamera sources for more information\";\n> +\t\treturn ret;\n> +\t}\n> +\n> +\treturn ret;\n> +}\n> +\n> +/**\n> + * \\fn CameraLens::model()\n> + * \\brief Retrieve the lens model name\n> + *\n> + * The lens model name is a free-formed string that uniquely identifies the\n> + * lens model.\n> + *\n> + * \\return The lens model name\n> + */\n> +\n> +std::string CameraLens::logPrefix() const\n> +{\n> +\treturn \"'\" + entity_->name() + \"'\";\n> +}\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 6727a777..3bee8fee 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -5,6 +5,7 @@ libcamera_sources = files([\n>       'byte_stream_buffer.cpp',\n>       'camera.cpp',\n>       'camera_controls.cpp',\n> +    'camera_lens.cpp',\n>       'camera_manager.cpp',\n>       'camera_sensor.cpp',\n>       'camera_sensor_properties.cpp',","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E8EE6BDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  2 Dec 2021 17:11:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3618D6082A;\n\tThu,  2 Dec 2021 18:11:19 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 57A016011A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  2 Dec 2021 18:11:17 +0100 (CET)","from [192.168.1.106] (unknown [103.251.226.170])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1D74F2A5;\n\tThu,  2 Dec 2021 18:11:15 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jOtsiwUx\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1638465077;\n\tbh=WYj8AgD1/4pPEZyTAghOaI61qMO7gRhUvd2nnZHHx+8=;\n\th=Subject:To:References:From:Date:In-Reply-To:From;\n\tb=jOtsiwUxgFrOrnA+hXY5RwMpyTvaYNB0cJNieMg1V74a1TPpx0KM0tFi2dsVC3WP+\n\tJv4bS4N3jKNIuLf0ywjx69xvwVyLpDlRx/1F6RGRzpOZ0uSahX4sY1sQoT85Aq5hJT\n\t29OzKHyOpj0ZhgloUYxRbh4wMhItOZFypzAmPtXQ=","To":"Han-Lin Chen <hanlinchen@chromium.org>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20211202140317.3118364-1-hanlinchen@chromium.org>\n\t<20211202140317.3118364-4-hanlinchen@chromium.org>","From":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<4a168185-1621-3871-3099-ed843ed6bb94@ideasonboard.com>","Date":"Thu, 2 Dec 2021 22:41:12 +0530","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.10.2","MIME-Version":"1.0","In-Reply-To":"<20211202140317.3118364-4-hanlinchen@chromium.org>","Content-Type":"text/plain; charset=utf-8; format=flowed","Content-Transfer-Encoding":"7bit","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH v7 3/5] libcamera: camera_lens: Add a\n\tnew class to model a camera lens","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]