[coreboot-gerrit] New patch to review for coreboot: fae6444 chromeec: provide proto v3 over i2c support

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Mar 20 16:21:13 CET 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8828

-gerrit

commit fae64448dde64915592205befa3cab420ba3d06a
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Aug 6 14:38:52 2014 -0500

    chromeec: provide proto v3 over i2c support
    
    Certain boards need to speak proto v3 over i2c. Leverage the
    transport agnostic API to share the logic with other proto v3
    impelementations.
    
    BUG=chrome-os-partner:31148
    BRANCH=None
    TEST=Built and ran on ryu. Can talk to the EC successfully.
    
    Change-Id: I1d0cd6907057af4ded3c4460193bbe1d897a1db7
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: cb9ac965ad04c9491f40fd9aa595176a28a467b3
    Original-Change-Id: Ib699120fd232392e8caa0889c2bf40f4587a8a35
    Original-Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/211139
    Original-Reviewed-by: Stefan Reinauer <reinauer at google.com>
    Original-Reviewed-by: Tom Warren <twarren at nvidia.com>
    Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
    Original-Tested-by: Furquan Shaikh <furquan at chromium.org>
---
 src/ec/google/chromeec/Kconfig  |   7 +++
 src/ec/google/chromeec/ec_i2c.c | 107 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+)

diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig
index cad1b48..bec12fb 100644
--- a/src/ec/google/chromeec/Kconfig
+++ b/src/ec/google/chromeec/Kconfig
@@ -19,6 +19,13 @@ config EC_GOOGLE_CHROMEEC_I2C_CHIP
 	hex
 	default 0x1e
 
+config EC_GOOGLE_CHROMEEC_I2C_PROTO3
+	depends on EC_GOOGLE_CHROMEEC_I2C
+	bool
+	default n
+	help
+	  Use only proto3 for i2c EC communication.
+
 config EC_GOOGLE_CHROMEEC_LPC
         depends on EC_GOOGLE_CHROMEEC && ARCH_X86  # Needs Plug-and-play.
 	def_bool y
diff --git a/src/ec/google/chromeec/ec_i2c.c b/src/ec/google/chromeec/ec_i2c.c
index 551c3b9..03e2b36 100644
--- a/src/ec/google/chromeec/ec_i2c.c
+++ b/src/ec/google/chromeec/ec_i2c.c
@@ -27,6 +27,111 @@
 #include "ec.h"
 #include "ec_commands.h"
 
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_I2C_PROTO3)
+
+#define PROTO3_FRAMING_BYTES sizeof(uint32_t)
+/* Just use the LPC host packet size to size the buffer. */
+#define PROTO3_MAX_PACKET_SIZE 268
+
+struct proto3_i2c_buf {
+	uint8_t framing_bytes[PROTO3_FRAMING_BYTES];
+	uint8_t data[PROTO3_MAX_PACKET_SIZE];
+} __attribute__((aligned(sizeof(uint32_t))));
+
+static struct proto3_i2c_buf req_buf;
+static struct proto3_i2c_buf resp_buf;
+
+enum {
+	CMD_INDEX,
+	RESP_INDEX,
+	SEGS_PER_CMD,
+};
+
+struct i2c_ec {
+	int bus;
+	struct i2c_seg segs[SEGS_PER_CMD];
+};
+
+static struct i2c_ec ec_dev = {
+	.bus = CONFIG_EC_GOOGLE_CHROMEEC_I2C_BUS,
+	.segs[CMD_INDEX] = {
+		.read = 0,
+		.chip = CONFIG_EC_GOOGLE_CHROMEEC_I2C_CHIP,
+		/* Framing byte to be transferred prior to request. */
+		.buf = &req_buf.framing_bytes[3],
+	},
+	.segs[RESP_INDEX] = {
+		.read = 1,
+		.chip = CONFIG_EC_GOOGLE_CHROMEEC_I2C_CHIP,
+		/* return code and total length before full response. */
+		.buf = &resp_buf.framing_bytes[2],
+	},
+};
+
+void *crosec_get_buffer(size_t size, int req)
+{
+	struct proto3_i2c_buf *ib;
+
+	if (size > PROTO3_MAX_PACKET_SIZE) {
+		printk(BIOS_DEBUG, "Proto v3 buffer request too large: %zu!\n",
+			size);
+		return NULL;
+	}
+
+	if (req)
+		ib = &req_buf;
+	else
+		ib = &resp_buf;
+
+	return &ib->data[0];
+}
+
+static int crosec_i2c_io(size_t req_size, size_t resp_size, void *context)
+{
+	struct i2c_ec *ec = context;
+	uint8_t ret_code;
+	size_t resp_len;
+
+	if (req_size > PROTO3_MAX_PACKET_SIZE ||
+		resp_size > PROTO3_MAX_PACKET_SIZE)
+		return -1;
+
+	/* Place the framing byte and set size accordingly. */
+	ec->segs[CMD_INDEX].len = req_size + 1;
+	ec->segs[CMD_INDEX].buf[0] = EC_COMMAND_PROTOCOL_3;
+	/* Return code and length returned prior to packet data. */
+	ec->segs[RESP_INDEX].len = resp_size + 2;
+
+	if (i2c_transfer(ec->bus, ec->segs, ARRAY_SIZE(ec->segs)) != 0) {
+		printk(BIOS_ERR, "%s: Cannot complete read from i2c-%d:%#x\n",
+		       __func__, ec->bus, ec->segs[0].chip);
+		return -1;
+	}
+
+	ret_code = ec->segs[RESP_INDEX].buf[0];
+	resp_len = ec->segs[RESP_INDEX].buf[1];
+
+	if (ret_code != 0) {
+		printk(BIOS_ERR, "EC command returned 0x%x\n", ret_code);
+		return -1;
+	}
+
+	if (resp_len > resp_size) {
+		printk(BIOS_ERR, "Response length mismatch %zu vs %zu\n",
+			resp_len, resp_size);
+		return -1;
+	}
+
+	return 0;
+}
+
+int google_chromeec_command(struct chromeec_command *cec_command)
+{
+	return crosec_command_proto(cec_command, crosec_i2c_io, &ec_dev);
+}
+
+#else /* CONFIG_EC_GOOGLE_CHROMEEC_I2C_PROTO3 */
+
 /* Command (host->device) format for I2C:
  *  uint8_t version, cmd, len, data[len], checksum;
  *
@@ -151,6 +256,8 @@ int google_chromeec_command(struct chromeec_command *cec_command)
 	return 0;
 }
 
+#endif /* CONFIG_EC_GOOGLE_CHROMEEC_I2C_PROTO3 */
+
 #ifndef __PRE_RAM__
 u8 google_chromeec_get_event(void)
 {



More information about the coreboot-gerrit mailing list