[libcamera-devel] [PATCH v7 2/9] libcamera: sysfs: Add method to lookup firmware ID

Niklas Söderlund niklas.soderlund at ragnatech.se
Tue Aug 4 18:13:51 CEST 2020


A systems firmware description is recorded differently in sysfs
depending if the system uses OF or ACPI. Add a helper to abstract
this, allowing users not to 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 <niklas.soderlund at ragnatech.se>
---
 include/libcamera/internal/sysfs.h |  2 ++
 src/libcamera/sysfs.cpp            | 57 ++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/include/libcamera/internal/sysfs.h b/include/libcamera/internal/sysfs.h
index 72f436205d8d30e8..ef8ec55909d85bf9 100644
--- a/include/libcamera/internal/sysfs.h
+++ b/include/libcamera/internal/sysfs.h
@@ -15,6 +15,8 @@ namespace sysfs {
 
 std::string charDevPath(const std::string &devicePath);
 
+int firmwareId(const std::string &path, std::string *id);
+
 } /* namespace sysfs */
 
 } /* namespace libcamera */
diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp
index 3b2920663e9c3bcc..98be4df9d38e6fa8 100644
--- a/src/libcamera/sysfs.cpp
+++ b/src/libcamera/sysfs.cpp
@@ -7,9 +7,11 @@
 
 #include "libcamera/internal/sysfs.h"
 
+#include <fstream>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
 
+#include "libcamera/internal/file.h"
 #include "libcamera/internal/log.h"
 
 /**
@@ -43,6 +45,61 @@ std::string charDevPath(const std::string &devicePath)
 	return dev.str();
 }
 
+/**
+ * \brief Try to read a device firmware ID from sysfs
+ * \param[in] path Path in sysfs to search
+ * \param[out] id Location to store ID if found
+ *
+ * A systems firmware description is recorded differently in sysfs depending if
+ * the system uses OF or ACPI. Add a helper to abstract this, allowing users not
+ * to 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 -EINVAL Error when looking up firmware ID
+ * \retval -ENODEV No firmware ID available for \a path
+ */
+int firmwareId(const std::string &path, std::string *id)
+{
+	ASSERT(id);
+
+	/* ID lookup for OF-based systems */
+	File ofFile(path + "/of_node");
+	if (ofFile.exists()) {
+		char *ofPath = realpath(ofFile.fileName().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;
+	}
+
+	/* ID lookup for ACPI-based systems */
+	File acpiFile(path + "/firmware_node/path");
+	if (acpiFile.exists()) {
+		std::ifstream file(acpiFile.fileName());
+		if (!file.is_open())
+			return -EINVAL;
+
+		std::getline(file, *id);
+		file.close();
+
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
 } /* namespace sysfs */
 
 } /* namespace libcamera */
-- 
2.28.0



More information about the libcamera-devel mailing list