From patchwork Mon Aug 3 21:17:28 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: 9158 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 26877BD87B for ; Mon, 3 Aug 2020 21:18:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D2E7D61B02; Mon, 3 Aug 2020 23:18:04 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B7F54605A9 for ; Mon, 3 Aug 2020 23:18:01 +0200 (CEST) X-Halon-ID: 9db76d77-d5ce-11ea-86ee-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 9db76d77-d5ce-11ea-86ee-0050569116f7; Mon, 03 Aug 2020 23:16:37 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 3 Aug 2020 23:17:28 +0200 Message-Id: <20200803211733.1037019-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200803211733.1037019-1-niklas.soderlund@ragnatech.se> References: <20200803211733.1037019-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 4/9] libcamera: utils: Add method to lookup firmware ID in sysfs 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" A devices firmware description is recorded differently in sysfs depending on if the devices uses OF or ACPI. Add a helper to abstract this, allowing users to not care which of the two are used. For OF-based systems the ID is the full path of the device in the device tree description. For ACPI-based 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. Signed-off-by: Niklas Söderlund --- include/libcamera/internal/utils.h | 2 + src/libcamera/utils.cpp | 61 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h index 45cd6f120c51586b..69977340e2593db6 100644 --- a/include/libcamera/internal/utils.h +++ b/include/libcamera/internal/utils.h @@ -200,6 +200,8 @@ details::StringSplitter split(const std::string &str, const std::string &delim); std::string libcameraBuildPath(); std::string libcameraSourcePath(); +int tryLookupFirmwareID(const std::string &devPath, std::string *id); + constexpr unsigned int alignDown(unsigned int value, unsigned int alignment) { return value / alignment * alignment; diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp index 615df46ac142a2a9..07ebce61f230e5f0 100644 --- a/src/libcamera/utils.cpp +++ b/src/libcamera/utils.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -444,6 +445,66 @@ std::string libcameraSourcePath() return path + "/"; } +/** + * \brief Try to read a device firmware ID from sysfs + * \param[in] devPath Path in sysfs to search + * \param[out] id Location to store ID if found + * + * The ID recorded in the devices firmware description is recorded differently + * in sysfs depending on if the devices uses OF or ACPI. This helper abstracts + * this away, allowing callers to not care which of the two are used. + * + * For OF-based systems the ID is the full path of the device in the device tree + * description. For ACPI-based 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. + * + * \return 0 on success or a negative error code otherwise + * \retval -ENOMEM \a id is nullptr + * \retval -EINVAL Error when looking up firmware ID + * \retval -ENODEV No firmware ID aviable for device + */ +int tryLookupFirmwareID(const std::string &devPath, std::string *id) +{ + struct stat statbuf; + std::string path; + + if (!id) + return -EINVAL; + + /* Try to lookup ID as if the system where OF-based. */ + path = devPath + "/of_node"; + if (stat(path.c_str(), &statbuf) == 0) { + char *ofPath = realpath(path.c_str(), nullptr); + if (!ofPath) + return -EINVAL; + + *id = ofPath; + free(ofPath); + + static const std::string dropStr = "/sys/firmware/devicetree/"; + if (id->find(dropStr) == 0) + id->erase(0, dropStr.length()); + + return 0; + } + + /* Try to lookup ID as if the system where ACPI-based. */ + path = devPath + "/firmware_node/path"; + if (stat(path.c_str(), &statbuf) == 0) { + std::ifstream file(path.c_str()); + if (!file.is_open()) + return -EINVAL; + + std::getline(file, *id); + file.close(); + + return 0; + } + + return -ENODEV; +} + /** * \fn alignDown(unsigned int value, unsigned int alignment) * \brief Align \a value down to \a alignment