#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>
}
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
*
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;
#endif
enum eeprom_action {
+ EEPROM_LIST,
EEPROM_READ,
EEPROM_WRITE,
EEPROM_PRINT,
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))
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)
{
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;
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)
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
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;
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")) {
}
#endif
- eeprom_init(dev.i2c_bus);
+ eeprom_dev_spec_init(&dev);
switch (action) {
case EEPROM_READ:
#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"
"The values which can be provided with the -l option are:\n"
CONFIG_EEPROM_LAYOUT_HELP_STRING"\n"
#endif
-#endif
);