diff options
author | Philip Chen <philipchen@google.com> | 2021-06-16 16:38:44 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-06-29 01:40:44 +0000 |
commit | 6d163016d305d63a72ca3884cc9da9b618f6609d (patch) | |
tree | c601e7e0c2a7eb3ea5f1dedf44ffc155053ff1cd /common/cbi_eeprom.c | |
parent | 8442045be1484112995eccee740bcff350e7f9a8 (diff) | |
download | chrome-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.c | 77 |
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, +}; |