From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 07/10] boards: add decoder for LXA TLV v1 format
Date: Fri, 11 Apr 2025 09:40:42 +0200 [thread overview]
Message-ID: <20250411074045.2019372-8-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20250411074045.2019372-1-a.fatoum@pengutronix.de>
The LXA TLV format is stored onto the EEPROM of either the Baseboard or
Powerboard. Its contents are mainly for use in Linux userspace.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
---
.../bindings/nvmem/barebox,tlv.yaml | 2 +
common/boards/Kconfig | 5 +
common/boards/Makefile | 1 +
common/boards/lxa/Makefile | 2 +
common/boards/lxa/factory-data.c | 132 ++++++++++++++++++
include/string.h | 2 +
include/tlv/format.h | 3 +
lib/string.c | 21 +++
8 files changed, 168 insertions(+)
create mode 100644 common/boards/lxa/Makefile
create mode 100644 common/boards/lxa/factory-data.c
diff --git a/Documentation/devicetree/bindings/nvmem/barebox,tlv.yaml b/Documentation/devicetree/bindings/nvmem/barebox,tlv.yaml
index b54ab600e309..7a77b9a0b44b 100644
--- a/Documentation/devicetree/bindings/nvmem/barebox,tlv.yaml
+++ b/Documentation/devicetree/bindings/nvmem/barebox,tlv.yaml
@@ -22,6 +22,8 @@ properties:
items:
- enum:
- barebox,tlv-v1 # magic: 0x61bb95f2
+ - lxa,tlv-baseboard-v1 # magic: 0xbc288dfe
+ - lxa,tlv-powerboard-v1 # magic: 0xdca5a870
- const: barebox,tlv
reg:
diff --git a/common/boards/Kconfig b/common/boards/Kconfig
index 586a54d7ca13..74947316954b 100644
--- a/common/boards/Kconfig
+++ b/common/boards/Kconfig
@@ -19,3 +19,8 @@ config BOARD_WOLFVISION
bool
select AIODEV
select ROCKCHIP_SARADC
+
+config BOARD_LXA
+ bool "LXA common board support" if COMPILE_TEST
+ select TLV
+ select TLV_BAREBOX
diff --git a/common/boards/Makefile b/common/boards/Makefile
index 3f8ac57b2f82..058733522411 100644
--- a/common/boards/Makefile
+++ b/common/boards/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_BOARD_QEMU_VIRT) += qemu-virt/
obj-$(CONFIG_BOARD_PHYTEC_SOM_DETECTION) += phytec/
obj-$(CONFIG_BOARD_TQ) += tq/
obj-$(CONFIG_BOARD_WOLFVISION) += wolfvision/
+obj-$(CONFIG_BOARD_LXA) += lxa/
diff --git a/common/boards/lxa/Makefile b/common/boards/lxa/Makefile
new file mode 100644
index 000000000000..29acfec3cb92
--- /dev/null
+++ b/common/boards/lxa/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_TLV) += factory-data.o
diff --git a/common/boards/lxa/factory-data.c b/common/boards/lxa/factory-data.c
new file mode 100644
index 000000000000..cca7b624dbf1
--- /dev/null
+++ b/common/boards/lxa/factory-data.c
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <string.h>
+#include <tlv/tlv.h>
+#include <common.h>
+
+static int lxa_tlv_handle_serial(struct tlv_device *dev, struct tlv_mapping *map,
+ u16 len, const u8 *val)
+{
+ const char *buf;
+ char *period;
+
+ buf = __tlv_format_str(dev, map, len, val);
+ if (!buf)
+ return -ENOMEM;
+
+ /* Strip /\d+\./ prefix to arrive at hostname without period */
+ period = memrchr(buf, '.', len);
+ barebox_set_serial_number(period ? period + 1 : buf);
+
+ return 0;
+}
+
+static int lxa_tlv_format_calib(struct tlv_device *dev, struct tlv_mapping *map,
+ u16 len, const u8 *val)
+{
+ return tlv_format_blob(dev, map, len, val);
+}
+
+static struct tlv_mapping lxa_tlv_baseboard_v1_mappings[] = {
+ /* vendor-specific override */
+ { 0x0004, lxa_tlv_handle_serial, "serial-number"},
+ /* vendor-specific additions */
+ { 0x8000, lxa_tlv_format_calib, "usb-host-curr" },
+ { 0x8001, lxa_tlv_format_calib, "usb-host1-curr" },
+ { 0x8002, lxa_tlv_format_calib, "usb-host2-curr" },
+ { 0x8003, lxa_tlv_format_calib, "usb-host3-curr" },
+ { 0x8010, lxa_tlv_format_calib, "out0-volt" },
+ { 0x8011, lxa_tlv_format_calib, "out1-volt" },
+ { 0x8020, lxa_tlv_format_calib, "iobus-curr" },
+ { 0x8021, lxa_tlv_format_calib, "iobus-volt" },
+ { /* sentintel */ },
+};
+
+static struct tlv_mapping *baseboard_mappings[] = {
+ lxa_tlv_baseboard_v1_mappings, barebox_tlv_v1_mappings, NULL
+};
+
+static struct of_device_id baseboard_matches[] = {
+ { .compatible = "lxa,tlv-baseboard-v1" },
+ { /* sentinel */ }
+};
+
+static struct tlv_decoder lxa_tlv_baseboard_v1 = {
+ .magic = TLV_MAGIC_LXA_BASEBOARD_V1,
+ .driver.name = "lxa-tlv-baseboard-v1",
+ .driver.of_compatible = baseboard_matches,
+ .mappings = baseboard_mappings,
+};
+
+static struct tlv_mapping lxa_tlv_powerboard_v1_mappings[] = {
+ { 0x0003, tlv_format_dec, "factory-timestamp" },
+ { 0x0005, tlv_format_dec, "modification" },
+ { 0x0006, tlv_format_str, "featureset" },
+ { 0x0007, tlv_format_str, "pcba-serial-number"},
+ { 0x0008, tlv_format_str, "pcba-hardware-release"},
+ { 0x9000, lxa_tlv_format_calib, "pwr-volt" },
+ { 0x9001, lxa_tlv_format_calib, "pwr-curr" },
+ { /* sentintel */ },
+};
+
+static struct tlv_mapping *powerboard_mappings[] = {
+ lxa_tlv_powerboard_v1_mappings, NULL
+};
+
+static struct of_device_id powerboard_matches[] = {
+ { .compatible = "lxa,tlv-powerboard-v1" },
+ { /* sentinel */ }
+};
+
+static struct tlv_decoder lxa_tlv_powerboard_v1 = {
+ .magic = TLV_MAGIC_LXA_POWERBOARD_V1,
+ .driver.name = "lxa-tlv-powerboard-v1",
+ .driver.of_compatible = powerboard_matches,
+ .mappings = powerboard_mappings,
+};
+
+
+static struct tlv_mapping lxa_tlv_ioboard_v1_mappings[] = {
+ { 0x0003, tlv_format_dec, "factory-timestamp" },
+ { 0x0005, tlv_format_dec, "modification" },
+ { 0x0006, tlv_format_str, "featureset" },
+ { 0x0007, tlv_format_str, "pcba-serial-number"},
+ { 0x0008, tlv_format_str, "pcba-hardware-release"},
+ { /* sentintel */ },
+};
+
+static struct tlv_mapping *ioboard_mappings[] = {
+ lxa_tlv_ioboard_v1_mappings, NULL
+};
+
+static struct of_device_id ioboard_matches[] = {
+ { .compatible = "lxa,tlv-ioboard-v1" },
+ { /* sentinel */ }
+};
+
+static struct tlv_decoder lxa_tlv_ioboard_v1 = {
+ .magic = TLV_MAGIC_LXA_IOBOARD_V1,
+ .driver.name = "lxa-tlv-ioboard-v1",
+ .driver.of_compatible = ioboard_matches,
+ .mappings = ioboard_mappings,
+};
+
+static int lxa_tlv_v1_register(void)
+{
+ struct tlv_decoder *const decoders[] = {
+ &lxa_tlv_baseboard_v1,
+ &lxa_tlv_powerboard_v1,
+ &lxa_tlv_ioboard_v1,
+ NULL
+ };
+ int err = 0;
+
+ for (struct tlv_decoder *const *d = decoders; *d; d++) {
+ int ret = tlv_register_decoder(*d);
+ if (ret)
+ err = ret;
+ }
+
+ return err;
+}
+postmmu_initcall(lxa_tlv_v1_register);
diff --git a/include/string.h b/include/string.h
index c16529c21273..004a9daece27 100644
--- a/include/string.h
+++ b/include/string.h
@@ -11,6 +11,8 @@ char *strsep_unescaped(char **, const char *);
char *stpcpy(char *dest, const char *src);
bool strends(const char *str, const char *postfix);
+void *memrchr(const void *s, int c, size_t n);
+
void *__default_memset(void *, int, __kernel_size_t);
void *__nokasan_default_memset(void *, int, __kernel_size_t);
diff --git a/include/tlv/format.h b/include/tlv/format.h
index a32ec917a434..29c8a6d42da2 100644
--- a/include/tlv/format.h
+++ b/include/tlv/format.h
@@ -22,6 +22,9 @@
#include <linux/build_bug.h>
#define TLV_MAGIC_BAREBOX_V1 0x61bb95f2
+#define TLV_MAGIC_LXA_BASEBOARD_V1 0xbc288dfe
+#define TLV_MAGIC_LXA_POWERBOARD_V1 0xc6895c21
+#define TLV_MAGIC_LXA_IOBOARD_V1 0xdca5a870
#define TLV_IS_VENDOR_SPECIFIC(val) ((*(u8 *)&(val) & 0x80) == 0x80)
#define TLV_IS_GENERIC(val) ((*(u8 *)&(val) & 0x80) != 0x80)
diff --git a/lib/string.c b/lib/string.c
index f2272be37e76..ff3408d3249e 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -818,6 +818,27 @@ void *memchr(const void *s, int c, size_t n)
#endif
EXPORT_SYMBOL(memchr);
+/**
+ * memrchr - Find last occurrence of character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the last occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memrchr(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ while (n-- > 0) {
+ if ((unsigned char)c == p[n]) {
+ return (void *)(p+n);
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(memrchr);
+
/**
* skip_spaces - Removes leading whitespace from @str.
* @str: The string to be stripped.
--
2.39.5
next prev parent reply other threads:[~2025-04-11 7:44 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-11 7:40 [PATCH 00/10] Add barebox TLV infrastructure Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 01/10] net: factor out eth_of_get_fixup_node Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 02/10] net: export list of registered ethernet addresses Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 03/10] common: add optional systemd.hostname generation Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 04/10] common: add barebox TLV support Ahmad Fatoum
2025-04-14 14:49 ` Sascha Hauer
2025-04-14 14:57 ` Ahmad Fatoum
2025-04-14 15:06 ` Sascha Hauer
2025-04-11 7:40 ` [PATCH 05/10] commands: add TLV debugging command Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 06/10] scripts: add bareboxtlv host/target tool Ahmad Fatoum
2025-04-11 7:40 ` Ahmad Fatoum [this message]
2025-04-11 7:40 ` [PATCH 08/10] scripts: Add Barebox TLV Generator Tooling Ahmad Fatoum
2025-04-14 15:00 ` Sascha Hauer
2025-04-11 7:40 ` [PATCH 09/10] doc: Add User-Documentation for Barebox TLV Ahmad Fatoum
2025-04-11 7:40 ` [PATCH 10/10] ARM: stm32mp: lxa: enable TLV support for TAC & FairyTux2 Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250411074045.2019372-8-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox