diff options
-rw-r--r-- | chip/ish/i2c.c | 5 | ||||
-rw-r--r-- | common/i2c_master.c | 9 | ||||
-rw-r--r-- | include/i2c.h | 10 |
3 files changed, 19 insertions, 5 deletions
diff --git a/chip/ish/i2c.c b/chip/ish/i2c.c index 405e63935e..b4cc32f0ad 100644 --- a/chip/ish/i2c.c +++ b/chip/ish/i2c.c @@ -306,10 +306,9 @@ int chip_i2c_xfer(const int port, const uint16_t slave_addr_flags, return EC_ERROR_INVAL; /* Check for reserved I2C addresses, pg. 74 in DW_apb_i2c.pdf - * Address cannot be any of the reserved address locations: - * 0x00 to 0x07 or 0x78 to 0x7f. + * Address cannot be any of the reserved address locations */ - if (addr <= 0x07 || (addr >= 0x78 && addr <= 0x7F)) + if (addr < I2C_FIRST_VALID_ADDR || addr > I2C_LAST_VALID_ADDR) return EC_ERROR_INVAL; /* assume that if both out_size and in_size are not zero, diff --git a/common/i2c_master.c b/common/i2c_master.c index 5975570fdb..d5eeaab04b 100644 --- a/common/i2c_master.c +++ b/common/i2c_master.c @@ -1029,8 +1029,13 @@ static void scan_bus(int port, const char *desc) (level & I2C_LINE_SCL_HIGH) ? 1 : 0); goto scan_bus_exit; } - - for (addr_flags = 0; addr_flags <= 0xEF; ++addr_flags) { + /* + * Only scan in the valid client device address range, otherwise some + * client devices stretch the clock in weird ways that prevent the + * discovery of other devices. + */ + for (addr_flags = I2C_FIRST_VALID_ADDR; + addr_flags <= I2C_LAST_VALID_ADDR; ++addr_flags) { watchdog_reload(); /* Otherwise a full scan trips watchdog */ ccputs("."); diff --git a/include/i2c.h b/include/i2c.h index ccb65fc7a0..ed041b2876 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -43,6 +43,16 @@ #define I2C_IS_BIG_ENDIAN(addr_flags) ((addr_flags) & I2C_FLAG_BIG_ENDIAN) /* + * All 7-bit addresses in the following formats + * 0000 XXX + * 1111 XXX + * are reserved for various purposes. Valid 7-bit client adderesses start at + * 0x08 and end at 0x77 inclusive. + */ +#define I2C_FIRST_VALID_ADDR 0x08 +#define I2C_LAST_VALID_ADDR 0x77 + +/* * Max data size for a version 3 request/response packet. This is * big enough for EC_CMD_GET_VERSION plus header info. */ |