From patchwork Tue Jul 28 23:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9050 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 377F2BD86F for ; Tue, 28 Jul 2020 23:42:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A641F613C6; Wed, 29 Jul 2020 01:42:40 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1284460535 for ; Wed, 29 Jul 2020 01:42:39 +0200 (CEST) X-Halon-ID: 05040132-d12c-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 05040132-d12c-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 01:42:38 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 01:42:22 +0200 Message-Id: <20200728234225.3505868-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200728234225.3505868-1-niklas.soderlund@ragnatech.se> References: <20200728233744.3503740-1-niklas.soderlund@ragnatech.se> <20200728234225.3505868-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/5] libcamera: camera_sensor: Generate a sensor ID 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" Generate a constant and unique string ID for the sensor. The ID is generated from firmware information fetched from the hardware that backs the sensor. The ID is unique and persistent across reboots of the system. For OF based systems the ID is the full path of the sensors in the device tree description. For ACPI bases systems the ID is the ACPI firmware nodes path. Both ID sources are guaranteed to be unique and persistent as long as the firmware of the system is not changed. A special case is needed to deal with the VIMC pipeline that implements a virtual pipeline that is not backed by any hardware device and is therefore not described in the device firmware. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 4 + src/libcamera/camera_sensor.cpp | 85 ++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 06c8292ca30129de..e0d2d9f63b47c2fe 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -47,6 +47,7 @@ public: int init(); const std::string &model() const { return model_; } + const std::string &id() const { return id_; } const MediaEntity *entity() const { return entity_; } const std::vector &mbusCodes() const { return mbusCodes_; } const std::vector &sizes() const { return sizes_; } @@ -67,11 +68,14 @@ protected: std::string logPrefix() const override; private: + int generateID(); + const MediaEntity *entity_; std::unique_ptr subdev_; unsigned int pad_; std::string model_; + std::string id_; V4L2Subdevice::Formats formats_; Size resolution_; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 350f49accad99c7b..a4339759bc847ff0 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -9,10 +9,12 @@ #include #include +#include #include #include #include #include +#include #include @@ -204,6 +206,11 @@ int CameraSensor::init() if (ret < 0) return ret; + /* Generate a unique ID for the sensor. */ + ret = generateID(); + if (ret) + return ret; + /* Retrieve and store the camera sensor properties. */ const ControlInfoMap &controls = subdev_->controls(); int32_t propertyValue; @@ -283,6 +290,17 @@ int CameraSensor::init() * \return The sensor model name */ +/** + * \fn CameraSensor::id() + * \brief Retrieve the sensor ID + * + * The sensor ID is a free-formed string that uniquely identifies the sensor in + * the system. The ID is persisted between different instances of libcamera and + * between resets of the system. + * + * \return The sensor ID + */ + /** * \fn CameraSensor::entity() * \brief Retrieve the sensor media entity @@ -541,4 +559,71 @@ std::string CameraSensor::logPrefix() const return "'" + entity_->name() + "'"; } +int CameraSensor::generateID() +{ + std::string path, devPath = subdev_->devicePath(); + struct stat statbuf; + + /* Try to generate ID from OF device tree path. */ + path = devPath + "/of_node"; + if (stat(path.c_str(), &statbuf) == 0) { + char ofPath[PATH_MAX]; + + if (!realpath(path.c_str(), ofPath)) { + LOG(CameraSensor, Error) << "Failed to read sensor OF based ID"; + return -EINVAL; + } + + id_ = ofPath; + const std::string dropStr = "/sys/firmware/devicetree/"; + if (id_.find(dropStr) == 0) + id_.erase(0, dropStr.length()); + + return 0; + } + + /* Try to generate ID from ACPI path. */ + path = devPath + "/firmware_node/path"; + if (stat(path.c_str(), &statbuf) == 0) { + std::ifstream file(path.c_str()); + + if (!file.is_open()) { + LOG(CameraSensor, Error) << "Failed to read sensor ACPI based ID"; + return -EINVAL; + } + + std::getline(file, id_); + file.close(); + + return 0; + } + + /* + * VIMC is a virtual video pipeline not backed hardware and have no OF + * or ACPI firmware nodes. Handle this pipeline as a special case and + * generate IDs based on the sensor model. + */ + path = devPath + "/modalias"; + if (stat(path.c_str(), &statbuf) == 0) { + std::ifstream file(path.c_str()); + + if (!file.is_open()) { + LOG(CameraSensor, Error) << "Failed to read sensor ACPI based ID"; + return -EINVAL; + } + + std::string modalias; + std::getline(file, modalias); + file.close(); + + if (modalias == "platform:vimc") { + id_ = "VIMC " + model(); + return 0; + } + } + + LOG(CameraSensor, Error) << "Unknown sensor device type, can not generate ID"; + return -EINVAL; +} + } /* namespace libcamera */