summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-10-03 18:28:57 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-01-18 05:09:29 -0800
commit6e3e0f87b1384b7adaece5d37887b96b0fdf89dd (patch)
treeb00fd662834f3b50ddb9437e29e1d40afa96ff75
parenta0f25e398ec74b455953833a5e73bd0e8f71feed (diff)
downloadchrome-ec-6e3e0f87b1384b7adaece5d37887b96b0fdf89dd.tar.gz
CBI: Read board info from EEPROM
This patch adds Cros Board Info APIs. It reads board info from EEPROM. This patch sets CONFIG_CBI for Fizz to make it use CBI. BUG=b:70294260 BRANCH=none TEST=Read data from EEPROM. Change-Id: I7eb4323188817d46b0450f1d65ac34d1b7e4e220 Reviewed-on: https://chromium-review.googlesource.com/707741 Commit-Ready: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/fizz/board.c5
-rw-r--r--board/fizz/board.h4
-rw-r--r--common/build.mk1
-rw-r--r--common/cbi.c127
-rw-r--r--include/config.h6
-rw-r--r--include/cros_board_info.h60
6 files changed, 203 insertions, 0 deletions
diff --git a/board/fizz/board.c b/board/fizz/board.c
index 2089777a01..9756aa05c0 100644
--- a/board/fizz/board.c
+++ b/board/fizz/board.c
@@ -17,6 +17,7 @@
#include "charger.h"
#include "chipset.h"
#include "console.h"
+#include "cros_board_info.h"
#include "driver/pmic_tps650x30.h"
#include "driver/temp_sensor/tmp432.h"
#include "driver/tcpm/ps8xxx.h"
@@ -449,6 +450,10 @@ DECLARE_HOOK(HOOK_AC_CHANGE, board_extpower, HOOK_PRIO_DEFAULT);
/* Initialize board. */
static void board_init(void)
{
+ uint32_t version;
+ if (cbi_get_board_version(&version) == EC_SUCCESS)
+ CPRINTS("Board Version: 0x%04x", version);
+
/* Provide AC status to the PCH */
board_extpower();
diff --git a/board/fizz/board.h b/board/fizz/board.h
index 9409cfffb3..67b7d20aad 100644
--- a/board/fizz/board.h
+++ b/board/fizz/board.h
@@ -18,6 +18,9 @@
/* EC */
#define CONFIG_ADC
#define CONFIG_BOARD_VERSION
+#define CONFIG_BOARD_SPECIFIC_VERSION
+#define CONFIG_CRC8
+#define CONFIG_CROS_BOARD_INFO
#define CONFIG_DEDICATED_RECOVERY_BUTTON
#define CONFIG_EMULATED_SYSRQ
#define CONFIG_LED_COMMON
@@ -130,6 +133,7 @@
/* I2C addresses */
#define I2C_ADDR_TCPC0 0x16
+#define I2C_ADDR_EEPROM 0xa0
/* Verify and jump to RW image on boot */
#define CONFIG_VBOOT_EFS
diff --git a/common/build.mk b/common/build.mk
index 589c71bf3c..7b70378541 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -26,6 +26,7 @@ common-$(CONFIG_BLUETOOTH_LE)+=bluetooth_le.o
common-$(CONFIG_BLUETOOTH_LE_STACK)+=btle_hci_controller.o btle_ll.o
common-$(CONFIG_CAPSENSE)+=capsense.o
common-$(CONFIG_CASE_CLOSED_DEBUG_V1)+=ccd_config.o
+common-$(CONFIG_CROS_BOARD_INFO)+=cbi.o
common-$(CONFIG_CHARGE_MANAGER)+=charge_manager.o
common-$(CONFIG_CHARGE_RAMP_HW)+=charge_ramp.o
common-$(CONFIG_CHARGE_RAMP_SW)+=charge_ramp.o charge_ramp_sw.o
diff --git a/common/cbi.c b/common/cbi.c
new file mode 100644
index 0000000000..dce8475d81
--- /dev/null
+++ b/common/cbi.c
@@ -0,0 +1,127 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Cros Board Info
+ */
+
+#include "common.h"
+#include "console.h"
+#include "crc8.h"
+#include "cros_board_info.h"
+#include "i2c.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, "CBI " format, ## args)
+
+static struct board_info bi;
+/* TODO: Init it to -1. On error (I2C or bad contents), retry a read and set it
+ * to enum ec_error_list if it still fails. The successive calls can be
+ * immediately returned with the cached error code. This will avoid attempting
+ * reads doomed to fail. */
+static int initialized;
+
+static uint8_t cbi_crc8(const struct board_info *bi)
+{
+ return crc8((uint8_t *)&bi->head.crc + 1, bi->head.total_size - 4);
+}
+
+/*
+ * Get board information from EEPROM
+ */
+static int read_board_info(void)
+{
+ uint8_t buf[256];
+ uint8_t offset;
+
+ if (initialized)
+ return EC_SUCCESS;
+
+ CPRINTS("Reading board info");
+
+ /* Read header */
+ offset = 0;
+ if (i2c_xfer(I2C_PORT_EEPROM, I2C_ADDR_EEPROM,
+ &offset, 1, buf, sizeof(bi.head), I2C_XFER_SINGLE)) {
+ CPRINTS("Failed to read header");
+ return EC_ERROR_INVAL;
+ }
+ memcpy(&bi.head, buf, sizeof(bi.head));
+
+ /* Check magic */
+ if (memcmp(bi.head.magic, cbi_magic, sizeof(bi.head.magic))) {
+ CPRINTS("Bad magic");
+ return EC_ERROR_INVAL;
+ }
+
+ /* check version */
+ if (bi.head.major_version > CBI_VERSION_MAJOR) {
+ CPRINTS("Version mismatch");
+ return EC_ERROR_INVAL;
+ }
+
+ /* Check the data size. It's expected to support up to 64k but our
+ * buffer has practical limitation. */
+ if (bi.head.total_size < sizeof(bi) ||
+ bi.head.total_size > sizeof(buf)) {
+ CPRINTS("Bad size: %d", bi.head.total_size);
+ return EC_ERROR_OVERFLOW;
+ }
+
+ /* Read the rest */
+ offset = sizeof(bi.head);
+ if (i2c_xfer(I2C_PORT_EEPROM, I2C_ADDR_EEPROM, &offset, 1,
+ buf + sizeof(bi.head),
+ bi.head.total_size - sizeof(bi.head),
+ I2C_XFER_SINGLE)) {
+ CPRINTS("Failed to read body");
+ return EC_ERROR_INVAL;
+ }
+
+ /* Check CRC. This supports new fields unknown to this parser. */
+ if (cbi_crc8((struct board_info *)&buf) != bi.head.crc) {
+ CPRINTS("Bad CRC");
+ return EC_ERROR_INVAL;
+ }
+
+ /* Save only the data we understand. */
+ memcpy(&bi.head + 1, &buf[sizeof(bi.head)],
+ sizeof(bi) - sizeof(bi.head));
+ /* If we're handling previous version, clear all new fields */
+
+ initialized = 1;
+
+ return EC_SUCCESS;
+}
+
+int cbi_get_board_version(uint32_t *version)
+{
+ if (read_board_info())
+ return EC_ERROR_UNKNOWN;
+ *version = bi.version;
+ return EC_SUCCESS;
+}
+
+int cbi_get_sku_id(uint32_t *sku_id)
+{
+ if (read_board_info())
+ return EC_ERROR_UNKNOWN;
+ *sku_id = bi.sku_id;
+ return EC_SUCCESS;
+}
+
+int cbi_get_oem_id(uint32_t *oem_id)
+{
+ if (read_board_info())
+ return EC_ERROR_UNKNOWN;
+ *oem_id = bi.oem_id;
+ return EC_SUCCESS;
+}
+
+int board_get_version(void)
+{
+ uint32_t version;
+ if (cbi_get_board_version(&version))
+ return -1;
+ return version;
+}
diff --git a/include/config.h b/include/config.h
index 5126164767..cb2dc59f81 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3118,6 +3118,12 @@
*/
#undef CONFIG_BOARD_ID_SUPPORT
+/*
+ * Define this to enable Cros Board Info support. I2C_EEPROM_PORT and
+ * I2C_EEPROM_ADDR must be defined as well.
+ */
+#undef CONFIG_CROS_BOARD_INFO
+
/*****************************************************************************/
/*
* Include board and core configs, since those hold the CONFIG_ constants for a
diff --git a/include/cros_board_info.h b/include/cros_board_info.h
new file mode 100644
index 0000000000..8d140f1d25
--- /dev/null
+++ b/include/cros_board_info.h
@@ -0,0 +1,60 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Cros Board Info
+ */
+#ifndef __CROS_EC_CROS_BOARD_INFO_H
+#define __CROS_EC_CROS_BOARD_INFO_H
+
+#include "common.h"
+
+#define CBI_VERSION_MAJOR 0
+#define CBI_VERSION_MINOR 0
+static const uint8_t cbi_magic[] = { 0x43, 0x42, 0x49 }; /* 'C' 'B' 'I' */
+
+struct cbi_header {
+ uint8_t magic[3];
+ /* CRC of 'struct board_info' excluding magic and crc */
+ uint8_t crc;
+ /* Data format version. Parsers are expected to process data as long
+ * as major version is equal or younger. */
+ union {
+ struct {
+ uint8_t minor_version;
+ uint8_t major_version;
+ };
+ uint16_t version;
+ };
+ /* Total size of data. It can be larger than sizeof(struct board_info)
+ * if future versions add additional fields. */
+ uint16_t total_size;
+} __attribute__((packed));
+
+struct board_info {
+ struct cbi_header head;
+ /* Board version */
+ union {
+ struct {
+ uint8_t minor_version;
+ uint8_t major_version;
+ };
+ uint16_t version;
+ };
+ /* OEM ID */
+ uint8_t oem_id;
+ /* SKU ID */
+ uint8_t sku_id;
+} __attribute__((packed));
+
+/**
+ * Board info accessors
+ *
+ * @param version/sku_id/oem_id [OUT] Data read from EEPROM
+ * @return EC_SUCCESS on success or EC_ERROR_* otherwise.
+ */
+int cbi_get_board_version(uint32_t *version);
+int cbi_get_sku_id(uint32_t *sku_id);
+int cbi_get_oem_id(uint32_t *oem_id);
+
+#endif /* __CROS_EC_CROS_BOARD_INFO_H */