summaryrefslogtreecommitdiff
path: root/common/cbi_eeprom.c
diff options
context:
space:
mode:
authorPhilip Chen <philipchen@google.com>2021-06-16 16:38:44 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-29 01:40:44 +0000
commit6d163016d305d63a72ca3884cc9da9b618f6609d (patch)
treec601e7e0c2a7eb3ea5f1dedf44ffc155053ff1cd /common/cbi_eeprom.c
parent8442045be1484112995eccee740bcff350e7f9a8 (diff)
downloadchrome-ec-6d163016d305d63a72ca3884cc9da9b618f6609d.tar.gz
cbi: Separate CBI EEPROM driver from CBI protocol
Factor out the physical storage driver (cbi_eeprom.c) from the CBI data/protocol layer (cbi.c), setting up the groundwork to support more options of CBI sources. BRANCH=None BUG=b:186264627 TEST=make buildall -j Change-Id: Ic30a6f789970dd6723cf70d4e852ddb7161f796f Signed-off-by: Philip Chen <philipchen@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2965848 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Philip Chen <philipchen@chromium.org> Tested-by: Philip Chen <philipchen@chromium.org>
Diffstat (limited to 'common/cbi_eeprom.c')
-rw-r--r--common/cbi_eeprom.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/common/cbi_eeprom.c b/common/cbi_eeprom.c
new file mode 100644
index 0000000000..ce6dd589a6
--- /dev/null
+++ b/common/cbi_eeprom.c
@@ -0,0 +1,77 @@
+/* Copyright 2021 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.
+ */
+
+/* Support Cros Board Info EEPROM */
+
+#include "cbi_eeprom.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "gpio.h"
+#include "i2c.h"
+#include "timer.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, "CBI " format, ## args)
+
+/*
+ * We allow EEPROMs with page size of 8 or 16. Use 8 to be the most compatible.
+ * This causes a little more overhead for writes, but we are not writing to the
+ * EEPROM outside of the factory process.
+ */
+#define EEPROM_PAGE_WRITE_SIZE 8
+#define EEPROM_PAGE_WRITE_MS 5
+#define EC_ERROR_CBI_CACHE_INVALID EC_ERROR_INTERNAL_FIRST
+
+static int eeprom_read(uint8_t offset, uint8_t *data, int len)
+{
+ return i2c_read_block(I2C_PORT_EEPROM, I2C_ADDR_EEPROM_FLAGS,
+ offset, data, len);
+}
+
+static int eeprom_is_write_protected(void)
+{
+ if (IS_ENABLED(CONFIG_BYPASS_CBI_EEPROM_WP_CHECK))
+ return 0;
+#if defined(CONFIG_WP_ACTIVE_HIGH)
+ return gpio_get_level(GPIO_WP);
+#else
+ return !gpio_get_level(GPIO_WP_L);
+#endif
+}
+
+static int eeprom_write(uint8_t *cbi)
+{
+ uint8_t *p = cbi;
+ int rest = ((struct cbi_header *)p)->total_size;
+
+ while (rest > 0) {
+ int size = MIN(EEPROM_PAGE_WRITE_SIZE, rest);
+ int rv;
+
+ rv = i2c_write_block(I2C_PORT_EEPROM, I2C_ADDR_EEPROM_FLAGS,
+ p - cbi, p, size);
+ if (rv) {
+ CPRINTS("Failed to write for %d", rv);
+ return rv;
+ }
+ /* Wait for internal write cycle completion */
+ msleep(EEPROM_PAGE_WRITE_MS);
+ p += size;
+ rest -= size;
+ }
+
+ return EC_SUCCESS;
+}
+
+const struct cbi_storage_driver eeprom_drv = {
+ .store = eeprom_write,
+ .load = eeprom_read,
+ .is_protected = eeprom_is_write_protected,
+};
+
+const struct cbi_storage_config_t cbi_config = {
+ .storage_type = CBI_STORAGE_TYPE_EEPROM,
+ .drv = &eeprom_drv,
+};