[U-Boot] [PATCH v2] cmd: cros_ec: Move crosec commands to cmd subdirectory

Moritz Fischer moritz.fischer at ettus.com
Wed Oct 5 02:08:08 CEST 2016


Move crosec commands from drivers/misc/cros_ec.c to
cmd/cros_ec.c

Acked-by: Simon Glass <sjg at chromium.org>
Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Heiko Schocher <hs at denx.de>
Cc: Bin Meng <bmeng.cn at gmail.com>
Cc: Miao Yan <yanmiaobest at gmail.com>
Cc: Masahiro Yamada <yamada.masahiro at socionext.com>
Cc: Stefan Roese <sr at denx.de>
Cc: Przemyslaw Marczak <p.marczak at samsung.com>
Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
Cc: Nishanth Menon <nm at ti.com>
Cc: u-boot at lists.denx.de

---
Changes from v1:

- Default to build CMD_CROS_EC in when CROS_EC is activated
- Get rid of leftover const ec_current_image_name[] artifact from
  moving stuff to separate file
- Added Simon's Acked-By:

---
 cmd/Kconfig            |  13 ++
 cmd/Makefile           |   1 +
 cmd/cros_ec.c          | 366 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/cros_ec.c | 351 -----------------------------------------------
 include/cros_ec.h      |  11 ++
 5 files changed, 391 insertions(+), 351 deletions(-)
 create mode 100644 cmd/cros_ec.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 86554ea..e339d86 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -677,6 +677,19 @@ config CMD_TPM_TEST
 
 endmenu
 
+menu "Firmware commands"
+config CMD_CROS_EC
+	bool "Enable crosec command"
+	depends on CROS_EC
+	default y
+	help
+	  Enable command-line access to the Chrome OS EC (Embedded
+	  Controller). This provides the 'crosec' command which has
+	  a number of sub-commands for performing EC tasks such as
+	  updating its flash, accessing a small saved context area
+	  and talking to the I2C bus behind the EC (if there is one).
+endmenu
+
 menu "Filesystem commands"
 config CMD_EXT2
 	bool "ext2 command support"
diff --git a/cmd/Makefile b/cmd/Makefile
index 81b98ee..9c9a9d1 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
 obj-$(CONFIG_CMD_TPM) += tpm.o
 obj-$(CONFIG_CMD_TPM_TEST) += tpm_test.o
+obj-$(CONFIG_CMD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CMD_TSI148) += tsi148.o
 obj-$(CONFIG_CMD_UBI) += ubi.o
 obj-$(CONFIG_CMD_UBIFS) += ubifs.o
diff --git a/cmd/cros_ec.c b/cmd/cros_ec.c
new file mode 100644
index 0000000..543dd28
--- /dev/null
+++ b/cmd/cros_ec.c
@@ -0,0 +1,366 @@
+/*
+ * Chromium OS cros_ec driver
+ *
+ * Copyright (c) 2016 The Chromium OS Authors.
+ * Copyright (c) 2016 National Instruments Corp
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cros_ec.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+/* Note: depends on enum ec_current_image */
+static const char * const ec_current_image_name[] = {"unknown", "RO", "RW"};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * Perform a flash read or write command
+ *
+ * @param dev		CROS-EC device to read/write
+ * @param is_write	1 do to a write, 0 to do a read
+ * @param argc		Number of arguments
+ * @param argv		Arguments (2 is region, 3 is address)
+ * @return 0 for ok, 1 for a usage error or -ve for ec command error
+ *	(negative EC_RES_...)
+ */
+static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc,
+			 char * const argv[])
+{
+	uint32_t offset, size = -1U, region_size;
+	unsigned long addr;
+	char *endp;
+	int region;
+	int ret;
+
+	region = cros_ec_decode_region(argc - 2, argv + 2);
+	if (region == -1)
+		return 1;
+	if (argc < 4)
+		return 1;
+	addr = simple_strtoul(argv[3], &endp, 16);
+	if (*argv[3] == 0 || *endp != 0)
+		return 1;
+	if (argc > 4) {
+		size = simple_strtoul(argv[4], &endp, 16);
+		if (*argv[4] == 0 || *endp != 0)
+			return 1;
+	}
+
+	ret = cros_ec_flash_offset(dev, region, &offset, &region_size);
+	if (ret) {
+		debug("%s: Could not read region info\n", __func__);
+		return ret;
+	}
+	if (size == -1U)
+		size = region_size;
+
+	ret = is_write ?
+		cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) :
+		cros_ec_flash_read(dev, (uint8_t *)addr, offset, size);
+	if (ret) {
+		debug("%s: Could not %s region\n", __func__,
+		      is_write ? "write" : "read");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct cros_ec_dev *dev;
+	struct udevice *udev;
+	const char *cmd;
+	int ret = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	cmd = argv[1];
+	if (0 == strcmp("init", cmd)) {
+		/* Remove any existing device */
+		ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
+		if (!ret)
+			device_remove(udev);
+		ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+		if (ret) {
+			printf("Could not init cros_ec device (err %d)\n", ret);
+			return 1;
+		}
+		return 0;
+	}
+
+	ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+	if (ret) {
+		printf("Cannot get cros-ec device (err=%d)\n", ret);
+		return 1;
+	}
+	dev = dev_get_uclass_priv(udev);
+	if (0 == strcmp("id", cmd)) {
+		char id[MSG_BYTES];
+
+		if (cros_ec_read_id(dev, id, sizeof(id))) {
+			debug("%s: Could not read KBC ID\n", __func__);
+			return 1;
+		}
+		printf("%s\n", id);
+	} else if (0 == strcmp("info", cmd)) {
+		struct ec_response_mkbp_info info;
+
+		if (cros_ec_info(dev, &info)) {
+			debug("%s: Could not read KBC info\n", __func__);
+			return 1;
+		}
+		printf("rows     = %u\n", info.rows);
+		printf("cols     = %u\n", info.cols);
+		printf("switches = %#x\n", info.switches);
+	} else if (0 == strcmp("curimage", cmd)) {
+		enum ec_current_image image;
+
+		if (cros_ec_read_current_image(dev, &image)) {
+			debug("%s: Could not read KBC image\n", __func__);
+			return 1;
+		}
+		printf("%d\n", image);
+	} else if (0 == strcmp("hash", cmd)) {
+		struct ec_response_vboot_hash hash;
+		int i;
+
+		if (cros_ec_read_hash(dev, &hash)) {
+			debug("%s: Could not read KBC hash\n", __func__);
+			return 1;
+		}
+
+		if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256)
+			printf("type:    SHA-256\n");
+		else
+			printf("type:    %d\n", hash.hash_type);
+
+		printf("offset:  0x%08x\n", hash.offset);
+		printf("size:    0x%08x\n", hash.size);
+
+		printf("digest:  ");
+		for (i = 0; i < hash.digest_size; i++)
+			printf("%02x", hash.hash_digest[i]);
+		printf("\n");
+	} else if (0 == strcmp("reboot", cmd)) {
+		int region;
+		enum ec_reboot_cmd cmd;
+
+		if (argc >= 3 && !strcmp(argv[2], "cold")) {
+			cmd = EC_REBOOT_COLD;
+		} else {
+			region = cros_ec_decode_region(argc - 2, argv + 2);
+			if (region == EC_FLASH_REGION_RO)
+				cmd = EC_REBOOT_JUMP_RO;
+			else if (region == EC_FLASH_REGION_RW)
+				cmd = EC_REBOOT_JUMP_RW;
+			else
+				return CMD_RET_USAGE;
+		}
+
+		if (cros_ec_reboot(dev, cmd, 0)) {
+			debug("%s: Could not reboot KBC\n", __func__);
+			return 1;
+		}
+	} else if (0 == strcmp("events", cmd)) {
+		uint32_t events;
+
+		if (cros_ec_get_host_events(dev, &events)) {
+			debug("%s: Could not read host events\n", __func__);
+			return 1;
+		}
+		printf("0x%08x\n", events);
+	} else if (0 == strcmp("clrevents", cmd)) {
+		uint32_t events = 0x7fffffff;
+
+		if (argc >= 3)
+			events = simple_strtol(argv[2], NULL, 0);
+
+		if (cros_ec_clear_host_events(dev, events)) {
+			debug("%s: Could not clear host events\n", __func__);
+			return 1;
+		}
+	} else if (0 == strcmp("read", cmd)) {
+		ret = do_read_write(dev, 0, argc, argv);
+		if (ret > 0)
+			return CMD_RET_USAGE;
+	} else if (0 == strcmp("write", cmd)) {
+		ret = do_read_write(dev, 1, argc, argv);
+		if (ret > 0)
+			return CMD_RET_USAGE;
+	} else if (0 == strcmp("erase", cmd)) {
+		int region = cros_ec_decode_region(argc - 2, argv + 2);
+		uint32_t offset, size;
+
+		if (region == -1)
+			return CMD_RET_USAGE;
+		if (cros_ec_flash_offset(dev, region, &offset, &size)) {
+			debug("%s: Could not read region info\n", __func__);
+			ret = -1;
+		} else {
+			ret = cros_ec_flash_erase(dev, offset, size);
+			if (ret) {
+				debug("%s: Could not erase region\n",
+				      __func__);
+			}
+		}
+	} else if (0 == strcmp("regioninfo", cmd)) {
+		int region = cros_ec_decode_region(argc - 2, argv + 2);
+		uint32_t offset, size;
+
+		if (region == -1)
+			return CMD_RET_USAGE;
+		ret = cros_ec_flash_offset(dev, region, &offset, &size);
+		if (ret) {
+			debug("%s: Could not read region info\n", __func__);
+		} else {
+			printf("Region: %s\n", region == EC_FLASH_REGION_RO ?
+					"RO" : "RW");
+			printf("Offset: %x\n", offset);
+			printf("Size:   %x\n", size);
+		}
+	} else if (0 == strcmp("flashinfo", cmd)) {
+		struct ec_response_flash_info p;
+
+		ret = cros_ec_read_flashinfo(dev, &p);
+		if (!ret) {
+			printf("Flash size:         %u\n", p.flash_size);
+			printf("Write block size:   %u\n", p.write_block_size);
+			printf("Erase block size:   %u\n", p.erase_block_size);
+		}
+	} else if (0 == strcmp("vbnvcontext", cmd)) {
+		uint8_t block[EC_VBNV_BLOCK_SIZE];
+		char buf[3];
+		int i, len;
+		unsigned long result;
+
+		if (argc <= 2) {
+			ret = cros_ec_read_vbnvcontext(dev, block);
+			if (!ret) {
+				printf("vbnv_block: ");
+				for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++)
+					printf("%02x", block[i]);
+				putc('\n');
+			}
+		} else {
+			/*
+			 * TODO(clchiou): Move this to a utility function as
+			 * cmd_spi might want to call it.
+			 */
+			memset(block, 0, EC_VBNV_BLOCK_SIZE);
+			len = strlen(argv[2]);
+			buf[2] = '\0';
+			for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) {
+				if (i * 2 >= len)
+					break;
+				buf[0] = argv[2][i * 2];
+				if (i * 2 + 1 >= len)
+					buf[1] = '0';
+				else
+					buf[1] = argv[2][i * 2 + 1];
+				strict_strtoul(buf, 16, &result);
+				block[i] = result;
+			}
+			ret = cros_ec_write_vbnvcontext(dev, block);
+		}
+		if (ret) {
+			debug("%s: Could not %s VbNvContext\n", __func__,
+			      argc <= 2 ?  "read" : "write");
+		}
+	} else if (0 == strcmp("test", cmd)) {
+		int result = cros_ec_test(dev);
+
+		if (result)
+			printf("Test failed with error %d\n", result);
+		else
+			puts("Test passed\n");
+	} else if (0 == strcmp("version", cmd)) {
+		struct ec_response_get_version *p;
+		char *build_string;
+
+		ret = cros_ec_read_version(dev, &p);
+		if (!ret) {
+			/* Print versions */
+			printf("RO version:    %1.*s\n",
+			       (int)sizeof(p->version_string_ro),
+			       p->version_string_ro);
+			printf("RW version:    %1.*s\n",
+			       (int)sizeof(p->version_string_rw),
+			       p->version_string_rw);
+			printf("Firmware copy: %s\n",
+			       (p->current_image <
+			       ARRAY_SIZE(ec_current_image_name) ?
+			       ec_current_image_name[p->current_image] :
+			       "?"));
+			ret = cros_ec_read_build_info(dev, &build_string);
+			if (!ret)
+				printf("Build info:    %s\n", build_string);
+		}
+	} else if (0 == strcmp("ldo", cmd)) {
+		uint8_t index, state;
+		char *endp;
+
+		if (argc < 3)
+			return CMD_RET_USAGE;
+		index = simple_strtoul(argv[2], &endp, 10);
+		if (*argv[2] == 0 || *endp != 0)
+			return CMD_RET_USAGE;
+		if (argc > 3) {
+			state = simple_strtoul(argv[3], &endp, 10);
+			if (*argv[3] == 0 || *endp != 0)
+				return CMD_RET_USAGE;
+			ret = cros_ec_set_ldo(udev, index, state);
+		} else {
+			ret = cros_ec_get_ldo(udev, index, &state);
+			if (!ret) {
+				printf("LDO%d: %s\n", index,
+				       state == EC_LDO_STATE_ON ?
+				       "on" : "off");
+			}
+		}
+
+		if (ret) {
+			debug("%s: Could not access LDO%d\n", __func__, index);
+			return ret;
+		}
+	} else {
+		return CMD_RET_USAGE;
+	}
+
+	if (ret < 0) {
+		printf("Error: CROS-EC command failed (error %d)\n", ret);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	crosec,	6,	1,	do_cros_ec,
+	"CROS-EC utility command",
+	"init                Re-init CROS-EC (done on startup automatically)\n"
+	"crosec id                  Read CROS-EC ID\n"
+	"crosec info                Read CROS-EC info\n"
+	"crosec curimage            Read CROS-EC current image\n"
+	"crosec hash                Read CROS-EC hash\n"
+	"crosec reboot [rw | ro | cold]  Reboot CROS-EC\n"
+	"crosec events              Read CROS-EC host events\n"
+	"crosec clrevents [mask]    Clear CROS-EC host events\n"
+	"crosec regioninfo <ro|rw>  Read image info\n"
+	"crosec flashinfo           Read flash info\n"
+	"crosec erase <ro|rw>       Erase EC image\n"
+	"crosec read <ro|rw> <addr> [<size>]   Read EC image\n"
+	"crosec write <ro|rw> <addr> [<size>]  Write EC image\n"
+	"crosec vbnvcontext [hexstring]        Read [write] VbNvContext from EC\n"
+	"crosec ldo <idx> [<state>] Switch/Read LDO state\n"
+	"crosec test                run tests on cros_ec\n"
+	"crosec version             Read CROS-EC version"
+);
+
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index d01a769..c5994ec 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -43,9 +43,6 @@ enum {
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Note: depends on enum ec_current_image */
-static const char * const ec_current_image_name[] = {"unknown", "RO", "RW"};
-
 void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len)
 {
 #ifdef DEBUG
@@ -1208,354 +1205,6 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,
 	return 0;
 }
 
-#ifdef CONFIG_CMD_CROS_EC
-
-/**
- * Perform a flash read or write command
- *
- * @param dev		CROS-EC device to read/write
- * @param is_write	1 do to a write, 0 to do a read
- * @param argc		Number of arguments
- * @param argv		Arguments (2 is region, 3 is address)
- * @return 0 for ok, 1 for a usage error or -ve for ec command error
- *	(negative EC_RES_...)
- */
-static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc,
-			 char * const argv[])
-{
-	uint32_t offset, size = -1U, region_size;
-	unsigned long addr;
-	char *endp;
-	int region;
-	int ret;
-
-	region = cros_ec_decode_region(argc - 2, argv + 2);
-	if (region == -1)
-		return 1;
-	if (argc < 4)
-		return 1;
-	addr = simple_strtoul(argv[3], &endp, 16);
-	if (*argv[3] == 0 || *endp != 0)
-		return 1;
-	if (argc > 4) {
-		size = simple_strtoul(argv[4], &endp, 16);
-		if (*argv[4] == 0 || *endp != 0)
-			return 1;
-	}
-
-	ret = cros_ec_flash_offset(dev, region, &offset, &region_size);
-	if (ret) {
-		debug("%s: Could not read region info\n", __func__);
-		return ret;
-	}
-	if (size == -1U)
-		size = region_size;
-
-	ret = is_write ?
-		cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) :
-		cros_ec_flash_read(dev, (uint8_t *)addr, offset, size);
-	if (ret) {
-		debug("%s: Could not %s region\n", __func__,
-		      is_write ? "write" : "read");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	struct cros_ec_dev *dev;
-	struct udevice *udev;
-	const char *cmd;
-	int ret = 0;
-
-	if (argc < 2)
-		return CMD_RET_USAGE;
-
-	cmd = argv[1];
-	if (0 == strcmp("init", cmd)) {
-		/* Remove any existing device */
-		ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
-		if (!ret)
-			device_remove(udev);
-		ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
-		if (ret) {
-			printf("Could not init cros_ec device (err %d)\n", ret);
-			return 1;
-		}
-		return 0;
-	}
-
-	ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
-	if (ret) {
-		printf("Cannot get cros-ec device (err=%d)\n", ret);
-		return 1;
-	}
-	dev = dev_get_uclass_priv(udev);
-	if (0 == strcmp("id", cmd)) {
-		char id[MSG_BYTES];
-
-		if (cros_ec_read_id(dev, id, sizeof(id))) {
-			debug("%s: Could not read KBC ID\n", __func__);
-			return 1;
-		}
-		printf("%s\n", id);
-	} else if (0 == strcmp("info", cmd)) {
-		struct ec_response_mkbp_info info;
-
-		if (cros_ec_info(dev, &info)) {
-			debug("%s: Could not read KBC info\n", __func__);
-			return 1;
-		}
-		printf("rows     = %u\n", info.rows);
-		printf("cols     = %u\n", info.cols);
-		printf("switches = %#x\n", info.switches);
-	} else if (0 == strcmp("curimage", cmd)) {
-		enum ec_current_image image;
-
-		if (cros_ec_read_current_image(dev, &image)) {
-			debug("%s: Could not read KBC image\n", __func__);
-			return 1;
-		}
-		printf("%d\n", image);
-	} else if (0 == strcmp("hash", cmd)) {
-		struct ec_response_vboot_hash hash;
-		int i;
-
-		if (cros_ec_read_hash(dev, &hash)) {
-			debug("%s: Could not read KBC hash\n", __func__);
-			return 1;
-		}
-
-		if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256)
-			printf("type:    SHA-256\n");
-		else
-			printf("type:    %d\n", hash.hash_type);
-
-		printf("offset:  0x%08x\n", hash.offset);
-		printf("size:    0x%08x\n", hash.size);
-
-		printf("digest:  ");
-		for (i = 0; i < hash.digest_size; i++)
-			printf("%02x", hash.hash_digest[i]);
-		printf("\n");
-	} else if (0 == strcmp("reboot", cmd)) {
-		int region;
-		enum ec_reboot_cmd cmd;
-
-		if (argc >= 3 && !strcmp(argv[2], "cold"))
-			cmd = EC_REBOOT_COLD;
-		else {
-			region = cros_ec_decode_region(argc - 2, argv + 2);
-			if (region == EC_FLASH_REGION_RO)
-				cmd = EC_REBOOT_JUMP_RO;
-			else if (region == EC_FLASH_REGION_RW)
-				cmd = EC_REBOOT_JUMP_RW;
-			else
-				return CMD_RET_USAGE;
-		}
-
-		if (cros_ec_reboot(dev, cmd, 0)) {
-			debug("%s: Could not reboot KBC\n", __func__);
-			return 1;
-		}
-	} else if (0 == strcmp("events", cmd)) {
-		uint32_t events;
-
-		if (cros_ec_get_host_events(dev, &events)) {
-			debug("%s: Could not read host events\n", __func__);
-			return 1;
-		}
-		printf("0x%08x\n", events);
-	} else if (0 == strcmp("clrevents", cmd)) {
-		uint32_t events = 0x7fffffff;
-
-		if (argc >= 3)
-			events = simple_strtol(argv[2], NULL, 0);
-
-		if (cros_ec_clear_host_events(dev, events)) {
-			debug("%s: Could not clear host events\n", __func__);
-			return 1;
-		}
-	} else if (0 == strcmp("read", cmd)) {
-		ret = do_read_write(dev, 0, argc, argv);
-		if (ret > 0)
-			return CMD_RET_USAGE;
-	} else if (0 == strcmp("write", cmd)) {
-		ret = do_read_write(dev, 1, argc, argv);
-		if (ret > 0)
-			return CMD_RET_USAGE;
-	} else if (0 == strcmp("erase", cmd)) {
-		int region = cros_ec_decode_region(argc - 2, argv + 2);
-		uint32_t offset, size;
-
-		if (region == -1)
-			return CMD_RET_USAGE;
-		if (cros_ec_flash_offset(dev, region, &offset, &size)) {
-			debug("%s: Could not read region info\n", __func__);
-			ret = -1;
-		} else {
-			ret = cros_ec_flash_erase(dev, offset, size);
-			if (ret) {
-				debug("%s: Could not erase region\n",
-				      __func__);
-			}
-		}
-	} else if (0 == strcmp("regioninfo", cmd)) {
-		int region = cros_ec_decode_region(argc - 2, argv + 2);
-		uint32_t offset, size;
-
-		if (region == -1)
-			return CMD_RET_USAGE;
-		ret = cros_ec_flash_offset(dev, region, &offset, &size);
-		if (ret) {
-			debug("%s: Could not read region info\n", __func__);
-		} else {
-			printf("Region: %s\n", region == EC_FLASH_REGION_RO ?
-					"RO" : "RW");
-			printf("Offset: %x\n", offset);
-			printf("Size:   %x\n", size);
-		}
-	} else if (0 == strcmp("flashinfo", cmd)) {
-		struct ec_response_flash_info p;
-
-		ret = cros_ec_read_flashinfo(dev, &p);
-		if (!ret) {
-			printf("Flash size:         %u\n", p.flash_size);
-			printf("Write block size:   %u\n", p.write_block_size);
-			printf("Erase block size:   %u\n", p.erase_block_size);
-		}
-	} else if (0 == strcmp("vbnvcontext", cmd)) {
-		uint8_t block[EC_VBNV_BLOCK_SIZE];
-		char buf[3];
-		int i, len;
-		unsigned long result;
-
-		if (argc <= 2) {
-			ret = cros_ec_read_vbnvcontext(dev, block);
-			if (!ret) {
-				printf("vbnv_block: ");
-				for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++)
-					printf("%02x", block[i]);
-				putc('\n');
-			}
-		} else {
-			/*
-			 * TODO(clchiou): Move this to a utility function as
-			 * cmd_spi might want to call it.
-			 */
-			memset(block, 0, EC_VBNV_BLOCK_SIZE);
-			len = strlen(argv[2]);
-			buf[2] = '\0';
-			for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) {
-				if (i * 2 >= len)
-					break;
-				buf[0] = argv[2][i * 2];
-				if (i * 2 + 1 >= len)
-					buf[1] = '0';
-				else
-					buf[1] = argv[2][i * 2 + 1];
-				strict_strtoul(buf, 16, &result);
-				block[i] = result;
-			}
-			ret = cros_ec_write_vbnvcontext(dev, block);
-		}
-		if (ret) {
-			debug("%s: Could not %s VbNvContext\n", __func__,
-					argc <= 2 ?  "read" : "write");
-		}
-	} else if (0 == strcmp("test", cmd)) {
-		int result = cros_ec_test(dev);
-
-		if (result)
-			printf("Test failed with error %d\n", result);
-		else
-			puts("Test passed\n");
-	} else if (0 == strcmp("version", cmd)) {
-		struct ec_response_get_version *p;
-		char *build_string;
-
-		ret = cros_ec_read_version(dev, &p);
-		if (!ret) {
-			/* Print versions */
-			printf("RO version:    %1.*s\n",
-			       (int)sizeof(p->version_string_ro),
-			       p->version_string_ro);
-			printf("RW version:    %1.*s\n",
-			       (int)sizeof(p->version_string_rw),
-			       p->version_string_rw);
-			printf("Firmware copy: %s\n",
-				(p->current_image <
-					ARRAY_SIZE(ec_current_image_name) ?
-				ec_current_image_name[p->current_image] :
-				"?"));
-			ret = cros_ec_read_build_info(dev, &build_string);
-			if (!ret)
-				printf("Build info:    %s\n", build_string);
-		}
-	} else if (0 == strcmp("ldo", cmd)) {
-		uint8_t index, state;
-		char *endp;
-
-		if (argc < 3)
-			return CMD_RET_USAGE;
-		index = simple_strtoul(argv[2], &endp, 10);
-		if (*argv[2] == 0 || *endp != 0)
-			return CMD_RET_USAGE;
-		if (argc > 3) {
-			state = simple_strtoul(argv[3], &endp, 10);
-			if (*argv[3] == 0 || *endp != 0)
-				return CMD_RET_USAGE;
-			ret = cros_ec_set_ldo(udev, index, state);
-		} else {
-			ret = cros_ec_get_ldo(udev, index, &state);
-			if (!ret) {
-				printf("LDO%d: %s\n", index,
-					state == EC_LDO_STATE_ON ?
-					"on" : "off");
-			}
-		}
-
-		if (ret) {
-			debug("%s: Could not access LDO%d\n", __func__, index);
-			return ret;
-		}
-	} else {
-		return CMD_RET_USAGE;
-	}
-
-	if (ret < 0) {
-		printf("Error: CROS-EC command failed (error %d)\n", ret);
-		ret = 1;
-	}
-
-	return ret;
-}
-
-U_BOOT_CMD(
-	crosec,	6,	1,	do_cros_ec,
-	"CROS-EC utility command",
-	"init                Re-init CROS-EC (done on startup automatically)\n"
-	"crosec id                  Read CROS-EC ID\n"
-	"crosec info                Read CROS-EC info\n"
-	"crosec curimage            Read CROS-EC current image\n"
-	"crosec hash                Read CROS-EC hash\n"
-	"crosec reboot [rw | ro | cold]  Reboot CROS-EC\n"
-	"crosec events              Read CROS-EC host events\n"
-	"crosec clrevents [mask]    Clear CROS-EC host events\n"
-	"crosec regioninfo <ro|rw>  Read image info\n"
-	"crosec flashinfo           Read flash info\n"
-	"crosec erase <ro|rw>       Erase EC image\n"
-	"crosec read <ro|rw> <addr> [<size>]   Read EC image\n"
-	"crosec write <ro|rw> <addr> [<size>]  Write EC image\n"
-	"crosec vbnvcontext [hexstring]        Read [write] VbNvContext from EC\n"
-	"crosec ldo <idx> [<state>] Switch/Read LDO state\n"
-	"crosec test                run tests on cros_ec\n"
-	"crosec version             Read CROS-EC version"
-);
-#endif
-
 UCLASS_DRIVER(cros_ec) = {
 	.id		= UCLASS_CROS_EC,
 	.name		= "cros_ec",
diff --git a/include/cros_ec.h b/include/cros_ec.h
index c4e9f64..f280c1d 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -283,6 +283,17 @@ int cros_ec_flash_read(struct cros_ec_dev *dev, uint8_t *data, uint32_t offset,
 		    uint32_t size);
 
 /**
+ * Read back flash parameters
+ *
+ * This function reads back parameters of the flash as reported by the EC
+ *
+ * @param dev  Pointer to device
+ * @param info Pointer to output flash info struct
+ */
+int cros_ec_read_flashinfo(struct cros_ec_dev *dev,
+			  struct ec_response_flash_info *info);
+
+/**
  * Write data to the flash
  *
  * Write an arbitrary amount of data to the EC flash, by repeatedly writing
-- 
2.7.4



More information about the U-Boot mailing list