From: "Marek Behún" <kabel@kernel.org>
To: Tom Rini <trini@konsulko.com>,
u-boot@lists.denx.de, Stefan Roese <sr@denx.de>
Cc: "Simon Glass" <sjg@chromium.org>,
"Ilias Apalodimas" <ilias.apalodimas@linaro.org>,
"Nikita Kiryanov" <nikita@compulab.co.il>,
"Marek Behún" <kabel@kernel.org>
Subject: [PATCH 11/11] cmd: eeprom: Extend to EEPROMs probed via driver model
Date: Tue, 21 May 2024 09:13:35 +0200 [thread overview]
Message-ID: <20240521071335.4193-12-kabel@kernel.org> (raw)
In-Reply-To: <20240521071335.4193-1-kabel@kernel.org>
Extend the 'eeprom' command to allow accessing EEPROMs probed via
driver model, uclass UCLASS_I2C_EEPROM.
When the CONFIG_I2C_EEPROM config option is enabled (and so the
i2c-eeprom driver is built), the 'eeprom' command now accepts driver
model device name as EEPROM specifier for the 'eeprom' command, in
addition to the legacy [[bus] devaddr] specifier.
Moreover if no device specifier is given, then the first
UCLASS_I2C_EEPROM device is used, if found.
Signed-off-by: Marek Behún <kabel@kernel.org>
---
cmd/eeprom.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 112 insertions(+), 10 deletions(-)
diff --git a/cmd/eeprom.c b/cmd/eeprom.c
index 9c4af88738..a39fc5ffdc 100644
--- a/cmd/eeprom.c
+++ b/cmd/eeprom.c
@@ -22,8 +22,10 @@
#include <common.h>
#include <config.h>
#include <command.h>
+#include <dm.h>
#include <eeprom.h>
#include <i2c.h>
+#include <i2c_eeprom.h>
#include <eeprom_layout.h>
#include <linux/delay.h>
@@ -209,10 +211,41 @@ static long parse_numeric_param(char *str)
}
struct eeprom_dev_spec {
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ struct udevice *dev;
+#endif
int i2c_bus;
ulong i2c_addr;
};
+static void eeprom_dev_spec_init(struct eeprom_dev_spec *dev)
+{
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (!dev->dev)
+#endif
+ eeprom_init(dev->i2c_bus);
+}
+
+static int eeprom_dev_spec_read(struct eeprom_dev_spec *dev,
+ unsigned offset, uchar *buffer, unsigned cnt)
+{
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (dev->dev)
+ return i2c_eeprom_read(dev->dev, offset, buffer, cnt);
+#endif
+ return eeprom_read(dev->i2c_addr, offset, buffer, cnt);
+}
+
+static int eeprom_dev_spec_write(struct eeprom_dev_spec *dev,
+ unsigned offset, uchar *buffer, unsigned cnt)
+{
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (dev->dev)
+ return i2c_eeprom_write(dev->dev, offset, buffer, cnt);
+#endif
+ return eeprom_write(dev->i2c_addr, offset, buffer, cnt);
+}
+
/**
* parse_eeprom_dev_spec - parse the eeprom device specifier
*
@@ -226,6 +259,28 @@ struct eeprom_dev_spec {
static int parse_eeprom_dev_spec(struct eeprom_dev_spec *dev, int argc,
char *const argv[])
{
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (argc == 0) {
+ if (!uclass_first_device_err(UCLASS_I2C_EEPROM, &dev->dev))
+ return 0;
+ }
+
+ if (argc == 1) {
+ if (!uclass_get_device_by_name(UCLASS_I2C_EEPROM, argv[0],
+ &dev->dev))
+ return 1;
+
+ /*
+ * If we could not find the device by name and the parameter is
+ * not numeric (and so won't be handled later), fail.
+ */
+ if (parse_numeric_param(argv[0]) == -1) {
+ printf("Can't get eeprom device: %s\n", argv[0]);
+ return CMD_RET_USAGE;
+ }
+ }
+#endif
+
#ifdef CONFIG_SYS_I2C_EEPROM_ADDR
if (argc == 0) {
dev->i2c_bus = -1;
@@ -265,6 +320,7 @@ static unsigned char eeprom_buf[CONFIG_SYS_EEPROM_SIZE];
#endif
enum eeprom_action {
+ EEPROM_LIST,
EEPROM_READ,
EEPROM_WRITE,
EEPROM_PRINT,
@@ -274,6 +330,10 @@ enum eeprom_action {
static enum eeprom_action parse_action(char *cmd)
{
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (!strncmp(cmd, "list", 4))
+ return EEPROM_LIST;
+#endif
if (!strncmp(cmd, "read", 4))
return EEPROM_READ;
if (!strncmp(cmd, "write", 5))
@@ -288,6 +348,24 @@ static enum eeprom_action parse_action(char *cmd)
return EEPROM_ACTION_INVALID;
}
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+static int do_eeprom_list(void)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int err;
+
+ err = uclass_get(UCLASS_I2C_EEPROM, &uc);
+ if (err)
+ return CMD_RET_FAILURE;
+
+ uclass_foreach_dev(dev, uc)
+ printf("%s (%s)\n", dev->name, dev->driver->name);
+
+ return CMD_RET_SUCCESS;
+}
+#endif
+
static int do_eeprom_rw(struct eeprom_dev_spec *dev, bool read,
ulong addr, ulong off, ulong cnt)
{
@@ -298,9 +376,9 @@ static int do_eeprom_rw(struct eeprom_dev_spec *dev, bool read,
printf(fmt, dev->i2c_addr, read ? "read" : "write", addr, off, cnt);
if (read)
- ret = eeprom_read(dev->i2c_addr, off, memloc, cnt);
+ ret = eeprom_dev_spec_read(dev, off, memloc, cnt);
else
- ret = eeprom_write(dev->i2c_addr, off, memloc, cnt);
+ ret = eeprom_dev_spec_write(dev, off, memloc, cnt);
puts("done\n");
return ret;
@@ -314,7 +392,7 @@ static int do_eeprom_layout(struct eeprom_dev_spec *dev, int layout_ver,
eeprom_layout_setup(layout, eeprom_buf, CONFIG_SYS_EEPROM_SIZE,
layout_ver);
- return eeprom_read(dev->i2c_addr, 0, eeprom_buf, layout->data_size);
+ return eeprom_dev_spec_read(dev, 0, eeprom_buf, layout->data_size);
}
static int do_eeprom_print(struct eeprom_dev_spec *dev, int layout_ver)
@@ -345,7 +423,7 @@ static int do_eeprom_update(struct eeprom_dev_spec *dev, int layout_ver,
if (ret)
return CMD_RET_FAILURE;
- return eeprom_write(dev->i2c_addr, 0, layout.data, layout.data_size);
+ return eeprom_dev_spec_write(dev, 0, layout.data, layout.data_size);
}
#endif
@@ -353,6 +431,8 @@ static int do_eeprom_update(struct eeprom_dev_spec *dev, int layout_ver,
static int eeprom_action_expected_argc(enum eeprom_action action)
{
switch (action) {
+ case EEPROM_LIST:
+ return 0;
case EEPROM_READ:
case EEPROM_WRITE:
return 3;
@@ -389,6 +469,11 @@ int do_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (action == EEPROM_ACTION_INVALID)
return CMD_RET_USAGE;
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ if (action == EEPROM_LIST)
+ return do_eeprom_list();
+#endif
+
#ifdef CONFIG_EEPROM_LAYOUT_VERSIONS
if (action == EEPROM_PRINT || action == EEPROM_UPDATE) {
if (!strcmp(argv[index], "-l")) {
@@ -425,7 +510,7 @@ int do_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
}
#endif
- eeprom_init(dev.i2c_bus);
+ eeprom_dev_spec_init(&dev);
switch (action) {
case EEPROM_READ:
@@ -450,19 +535,37 @@ int do_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
#define EEPROM_LAYOUT_SPEC ""
#endif
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+# define EEPROM_DEV_SPEC "[device_specifier]"
+#else
+# define EEPROM_DEV_SPEC "[[bus] devaddr]"
+#endif
+
U_BOOT_CMD(
eeprom, 8, 1, do_eeprom,
"EEPROM sub-system",
- "read [[bus] devaddr] addr off cnt\n"
- "eeprom write [[bus] devaddr] addr off cnt\n"
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ "list\n"
+ "eeprom "
+#endif
+ "read " EEPROM_DEV_SPEC " addr off cnt\n"
+ "eeprom write " EEPROM_DEV_SPEC " addr off cnt\n"
" - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'"
#ifdef CONFIG_CMD_EEPROM_LAYOUT
"\n"
- "eeprom print " EEPROM_LAYOUT_SPEC "[[bus] devaddr]\n"
+ "eeprom print " EEPROM_LAYOUT_SPEC EEPROM_DEV_SPEC "\n"
" - Print layout fields and their data in human readable format\n"
- "eeprom update " EEPROM_LAYOUT_SPEC "[[bus] devaddr] field_name field_value\n"
+ "eeprom update " EEPROM_LAYOUT_SPEC EEPROM_DEV_SPEC " field_name field_value\n"
" - Update a specific eeprom field with new data.\n"
" The new data must be written in the same human readable format as shown by the print command."
+#endif
+#if CONFIG_IS_ENABLED(I2C_EEPROM)
+ "\n\n"
+ "DEVICE SPECIFIER - the eeprom device can be specified\n"
+ " [dev_name] - by device name (devices can listed with the eeprom list command)\n"
+ " [[bus] devaddr] - or by I2C bus and I2C device address\n"
+ "If no device specifier is given, the first driver-model found device is used."
+#endif
#ifdef CONFIG_EEPROM_LAYOUT_VERSIONS
"\n\n"
"LAYOUT VERSIONS\n"
@@ -471,5 +574,4 @@ U_BOOT_CMD(
"The values which can be provided with the -l option are:\n"
CONFIG_EEPROM_LAYOUT_HELP_STRING"\n"
#endif
-#endif
);
--
2.44.1
next prev parent reply other threads:[~2024-05-21 7:15 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-21 7:13 [PATCH 00/11] 'eeprom' command improvements Marek Behún
2024-05-21 7:13 ` [PATCH 01/11] common: eeprom_layout: Assign default layout methods and parameters before specific ones Marek Behún
2024-05-21 7:13 ` [PATCH 02/11] common: eeprom_layout: Split field finding code from the field update function Marek Behún
2024-05-21 7:13 ` [PATCH 03/11] common: eeprom_field: Fix updating binary field Marek Behún
2024-05-21 7:13 ` [PATCH 04/11] common: eeprom_field: Drop unnecessary comparison Marek Behún
2024-05-21 7:13 ` [PATCH 05/11] cmd: eeprom: Fix usage help for the eeprom command Marek Behún
2024-05-21 7:13 ` [PATCH 06/11] cmd: eeprom: Hide eeprom layout versioning behind a Kconfig option Marek Behún
2024-05-21 7:13 ` [PATCH 07/11] cmd: eeprom: Deduplicate parse_i2c_bus_addr() calls Marek Behún
2024-05-21 7:13 ` [PATCH 08/11] cmd: eeprom: Refactor eeprom device specifier parsing Marek Behún
2024-05-21 7:13 ` [PATCH 09/11] cmd: eeprom: Refactor command execution into function by action Marek Behún
2024-05-21 7:13 ` [PATCH 10/11] cmd: eeprom: Don't read/write whole EEPROM if not necessary Marek Behún
2024-05-21 7:13 ` Marek Behún [this message]
2024-06-07 18:57 ` [PATCH 00/11] 'eeprom' command improvements Tom Rini
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=20240521071335.4193-12-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=ilias.apalodimas@linaro.org \
--cc=nikita@compulab.co.il \
--cc=sjg@chromium.org \
--cc=sr@denx.de \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.