diff options
-rw-r--r-- | board/reef/board.c | 63 | ||||
-rw-r--r-- | board/reef/board.h | 8 | ||||
-rw-r--r-- | common/i2c.c | 161 | ||||
-rw-r--r-- | driver/accel_kionix.c | 12 | ||||
-rw-r--r-- | driver/accel_kionix.h | 10 | ||||
-rw-r--r-- | driver/accel_kx022.h | 1 | ||||
-rw-r--r-- | driver/accel_kxcj9.h | 1 | ||||
-rw-r--r-- | driver/accelgyro_bmi160.c | 16 | ||||
-rw-r--r-- | driver/accelgyro_bmi160.h | 3 | ||||
-rw-r--r-- | driver/als_opt3001.c | 12 | ||||
-rw-r--r-- | driver/als_opt3001.h | 4 | ||||
-rw-r--r-- | driver/baro_bmp280.c | 16 | ||||
-rw-r--r-- | driver/baro_bmp280.h | 5 | ||||
-rw-r--r-- | driver/battery/smart.c | 33 | ||||
-rw-r--r-- | driver/charger/bd9995x.c | 22 | ||||
-rw-r--r-- | driver/charger/bd9995x.h | 4 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.c | 12 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.h | 8 | ||||
-rw-r--r-- | driver/tcpm/ps8751.c | 12 | ||||
-rw-r--r-- | driver/tcpm/ps8751.h | 7 | ||||
-rw-r--r-- | driver/tcpm/tcpm.h | 14 | ||||
-rw-r--r-- | include/battery.h | 4 | ||||
-rw-r--r-- | include/config.h | 9 | ||||
-rw-r--r-- | include/i2c.h | 36 |
24 files changed, 469 insertions, 4 deletions
diff --git a/board/reef/board.c b/board/reef/board.c index 5b7a1f3936..bde169f3df 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -143,6 +143,69 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); +#ifdef CONFIG_CMD_I2C_STRESS_TEST +struct i2c_stress_test i2c_stress_tests[] = { +/* NPCX_I2C_PORT0_0 */ +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC + { + .port = NPCX_I2C_PORT0_0, + .addr = 0x50, + .i2c_test = &anx74xx_i2c_stress_test_dev, + }, +#endif + +/* NPCX_I2C_PORT0_1 */ +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC + { + .port = NPCX_I2C_PORT0_1, + .addr = 0x16, + .i2c_test = &ps8751_i2c_stress_test_dev, + }, +#endif + +/* NPCX_I2C_PORT1 */ +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL + { + .port = I2C_PORT_GYRO, + .addr = BMI160_ADDR0, + .i2c_test = &bmi160_i2c_stress_test_dev, + }, +#endif + +/* NPCX_I2C_PORT2 */ +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL + { + .port = I2C_PORT_BARO, + .addr = BMP280_I2C_ADDRESS1, + .i2c_test = &bmp280_i2c_stress_test_dev, + }, + { + .port = I2C_PORT_LID_ACCEL, + .addr = KX022_ADDR1, + .i2c_test = &kionix_i2c_stress_test_dev, + }, +#endif +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ALS + { + .i2c_test = &opt3001_i2c_stress_test_dev, + }, +#endif + +/* NPCX_I2C_PORT3 */ +#ifdef CONFIG_CMD_I2C_STRESS_TEST_BATTERY + { + .i2c_test = &battery_i2c_stress_test_dev, + }, +#endif +#ifdef CONFIG_CMD_I2C_STRESS_TEST_CHARGER + { + .i2c_test = &bd9995x_i2c_stress_test_dev, + }, +#endif +}; +const int i2c_test_dev_used = ARRAY_SIZE(i2c_stress_tests); +#endif /* CONFIG_CMD_I2C_STRESS_TEST */ + const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { #if IS_PROTO == 1 {NPCX_I2C_PORT0_0, 0x50, &anx74xx_tcpm_drv, TCPC_ALERT_ACTIVE_HIGH}, diff --git a/board/reef/board.h b/board/reef/board.h index 8ed35be00b..c4013270ef 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -38,7 +38,15 @@ #define BD9995X_PSYS_GAIN_SELECT \ BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_02UAW +#define CONFIG_CMD_I2C_STRESS_TEST +#define CONFIG_CMD_I2C_STRESS_TEST_ACCEL +#define CONFIG_CMD_I2C_STRESS_TEST_ALS +#define CONFIG_CMD_I2C_STRESS_TEST_BATTERY +#define CONFIG_CMD_I2C_STRESS_TEST_CHARGER +#define CONFIG_CMD_I2C_STRESS_TEST_TCPC + /* Battery */ +#define CONFIG_BATTERY_DEVICE_CHEMISTRY "LION" #define CONFIG_BATTERY_CUT_OFF #define CONFIG_BATTERY_PRESENT_CUSTOM #define CONFIG_BATTERY_REVIVE_DISCONNECT diff --git a/common/i2c.c b/common/i2c.c index 7563a3f612..996ffe3f09 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -857,3 +857,164 @@ DECLARE_CONSOLE_COMMAND(i2cxfer, command_i2cxfer, "r/r16/rlen/w/w16 port addr offset [value | len]", "Read write I2C"); #endif + +#ifdef CONFIG_CMD_I2C_STRESS_TEST +static void i2c_test_status(struct i2c_test_results *i2c_test, int test_dev) +{ + ccprintf("test_dev=%2d, ", test_dev); + ccprintf("r=%5d, rs=%5d, rf=%5d, ", + i2c_test->read_success + i2c_test->read_fail, + i2c_test->read_success, + i2c_test->read_fail); + + ccprintf("w=%5d, ws=%5d, wf=%5d\n", + i2c_test->write_success + i2c_test->write_fail, + i2c_test->write_success, + i2c_test->write_fail); + + i2c_test->read_success = 0; + i2c_test->read_fail = 0; + i2c_test->write_success = 0, + i2c_test->write_fail = 0; +} + +#define I2C_STRESS_TEST_DATA_VERIFY_RETRY_COUNT 3 +static int command_i2ctest(int argc, char **argv) +{ + char *e; + int i, j, rv, rand; + int data, data_verify; + int port, addr; + int count = 10000; + int udelay = 100; + int test_dev = i2c_test_dev_used; + struct i2c_stress_test_dev *i2c_s_test; + struct i2c_test_reg_info *reg_s_info; + struct i2c_test_results *test_s_results; + + if (argc > 1) { + count = strtoi(argv[1], &e, 0); + if (*e) + return EC_ERROR_PARAM2; + } + + if (argc > 2) { + udelay = strtoi(argv[2], &e, 0); + if (*e) + return EC_ERROR_PARAM3; + } + + if (argc > 3) { + test_dev = strtoi(argv[3], &e, 0); + if (*e || test_dev < 1 || test_dev > i2c_test_dev_used) + return EC_ERROR_PARAM4; + test_dev--; + } + + for (i = 0; i < count; i++) { + if (!(i % 1000)) + ccprintf("running test %d\n", i); + + if (argc < 4) { + rand = get_time().val; + test_dev = rand % i2c_test_dev_used; + } + + port = i2c_stress_tests[test_dev].port; + addr = i2c_stress_tests[test_dev].addr; + i2c_s_test = i2c_stress_tests[test_dev].i2c_test; + reg_s_info = &i2c_s_test->reg_info; + test_s_results = &i2c_s_test->test_results; + + rand = get_time().val; + if (rand & 0x1) { + /* read */ + rv = i2c_s_test->i2c_read ? + i2c_s_test->i2c_read(port, addr, + reg_s_info->read_reg, &data) : + i2c_s_test->i2c_read_dev( + reg_s_info->read_reg, &data); + if (rv || data != reg_s_info->read_val) + test_s_results->read_fail++; + else + test_s_results->read_success++; + } else { + /* + * Reads are more than writes in the system. + * Read and then write same value to ensure we are + * not changing any settings. + */ + + /* Read the write register */ + rv = i2c_s_test->i2c_read ? + i2c_s_test->i2c_read(port, addr, + reg_s_info->read_reg, &data) : + i2c_s_test->i2c_read_dev( + reg_s_info->read_reg, &data); + if (rv) { + /* Skip writing invalid data */ + test_s_results->read_fail++; + continue; + } else + test_s_results->read_success++; + + j = I2C_STRESS_TEST_DATA_VERIFY_RETRY_COUNT; + do { + /* Write same value back */ + rv = i2c_s_test->i2c_write ? + i2c_s_test->i2c_write(port, addr, + reg_s_info->write_reg, data) : + i2c_s_test->i2c_write_dev( + reg_s_info->write_reg, data); + i++; + if (rv) { + /* Skip reading as write failed */ + test_s_results->write_fail++; + break; + } + test_s_results->write_success++; + + /* Read back to verify the data */ + rv = i2c_s_test->i2c_read ? + i2c_s_test->i2c_read(port, addr, + reg_s_info->read_reg, &data_verify) : + i2c_s_test->i2c_read_dev( + reg_s_info->read_reg, &data_verify); + i++; + if (rv) { + /* Read failed try next time */ + test_s_results->read_fail++; + break; + } else if (!rv && data != data_verify) { + /* Either data writes/read is wrong */ + j--; + } else { + j = 0; + test_s_results->read_success++; + } + } while (j); + } + + usleep(udelay); + } + + ccprintf("\n**********final result **********\n"); + + cflush(); + if (argc > 3) { + i2c_test_status(&i2c_s_test->test_results, test_dev + 1); + } else { + for (i = 0; i < i2c_test_dev_used; i++) { + i2c_s_test = i2c_stress_tests[i].i2c_test; + i2c_test_status(&i2c_s_test->test_results, i + 1); + msleep(100); + } + } + cflush(); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(i2ctest, command_i2ctest, + "i2ctest count|udelay|dev", + "I2C stress test"); +#endif /* CONFIG_CMD_I2C_STRESS_TEST */ diff --git a/driver/accel_kionix.c b/driver/accel_kionix.c index 7600f452ee..2a9149d9a7 100644 --- a/driver/accel_kionix.c +++ b/driver/accel_kionix.c @@ -529,3 +529,15 @@ const struct accelgyro_drv kionix_accel_drv = { .set_offset = set_offset, .get_offset = get_offset, }; + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +struct i2c_stress_test_dev kionix_i2c_stress_test_dev = { + .reg_info = { + .read_reg = KX022_WHOAMI, + .read_val = KIONIX_WHO_AM_I_VAL, + .write_reg = KIONIX_ODR_REG(V(s)), + }, + .i2c_read = &raw_read8, + .i2c_write = &raw_write8, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_ACCEL */ diff --git a/driver/accel_kionix.h b/driver/accel_kionix.h index 6c71cb7918..04df63066f 100644 --- a/driver/accel_kionix.h +++ b/driver/accel_kionix.h @@ -69,4 +69,14 @@ extern const struct accelgyro_drv kionix_accel_drv; #define KIONIX_XOUT_L(v) (KX022_XOUT_L + \ (v) * (KXCJ9_XOUT_L - KX022_XOUT_L)) +#ifdef CONFIG_ACCEL_KX022 +#define KIONIX_WHO_AM_I_VAL KX022_WHO_AM_I_VAL +#elif defined(CONFIG_ACCEL_KXCJ9) +#define KIONIX_WHO_AM_I_VAL KXCJ9_WHO_AM_I_VAL +#endif + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +extern struct i2c_stress_test_dev kionix_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_ACCEL_KIONIX_H */ diff --git a/driver/accel_kx022.h b/driver/accel_kx022.h index 3ed95a30a8..d25d68b380 100644 --- a/driver/accel_kx022.h +++ b/driver/accel_kx022.h @@ -14,6 +14,7 @@ */ #define KX022_ADDR0 0x3c #define KX022_ADDR1 0x3e +#define KX022_WHO_AM_I_VAL 0x14 /* Chip-specific registers */ #define KX022_XHP_L 0x00 diff --git a/driver/accel_kxcj9.h b/driver/accel_kxcj9.h index 4436f38e8b..b3702ea541 100644 --- a/driver/accel_kxcj9.h +++ b/driver/accel_kxcj9.h @@ -16,6 +16,7 @@ */ #define KXCJ9_ADDR0 0x1c #define KXCJ9_ADDR1 0x1e +#define KXCJ9_WHO_AM_I_VAL 0x0A /* Chip-specific registers */ #define KXCJ9_XOUT_L 0x06 diff --git a/driver/accelgyro_bmi160.c b/driver/accelgyro_bmi160.c index c8a6d18bdf..2ecc27fe4c 100644 --- a/driver/accelgyro_bmi160.c +++ b/driver/accelgyro_bmi160.c @@ -139,7 +139,7 @@ static inline int spi_raw_read(const int addr, const uint8_t reg, /** * Read 8bit register from accelerometer. */ -static int raw_read8(const int port, const int addr, const uint8_t reg, +static int raw_read8(const int port, const int addr, const int reg, int *data_ptr) { int rv = -EC_ERROR_PARAM1; @@ -163,7 +163,7 @@ static int raw_read8(const int port, const int addr, const uint8_t reg, /** * Write 8bit register from accelerometer. */ -static int raw_write8(const int port, const int addr, const uint8_t reg, +static int raw_write8(const int port, const int addr, const int reg, int data) { int rv = -EC_ERROR_PARAM1; @@ -1248,3 +1248,15 @@ const struct accelgyro_drv bmi160_drv = { struct bmi160_drv_data_t g_bmi160_data = { .flags = 0, }; + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +struct i2c_stress_test_dev bmi160_i2c_stress_test_dev = { + .reg_info = { + .read_reg = BMI160_CHIP_ID, + .read_val = BMI160_CHIP_ID_MAJOR, + .write_reg = BMI160_PMU_TRIGGER, + }, + .i2c_read = &raw_read8, + .i2c_write = &raw_write8, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_ACCEL */ diff --git a/driver/accelgyro_bmi160.h b/driver/accelgyro_bmi160.h index e6e8e19e54..ec43fb4a9d 100644 --- a/driver/accelgyro_bmi160.h +++ b/driver/accelgyro_bmi160.h @@ -459,5 +459,8 @@ int raw_mag_read8(const int port, const int addr, const uint8_t reg, int raw_mag_write8(const int port, const int addr, const uint8_t reg, int data); #endif +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +extern struct i2c_stress_test_dev bmi160_i2c_stress_test_dev; +#endif #endif /* __CROS_EC_ACCELGYRO_BMI160_H */ diff --git a/driver/als_opt3001.c b/driver/als_opt3001.c index 993803bd28..bbf61a1064 100644 --- a/driver/als_opt3001.c +++ b/driver/als_opt3001.c @@ -87,3 +87,15 @@ int opt3001_read_lux(int *lux, int af) return EC_SUCCESS; } + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ALS +struct i2c_stress_test_dev opt3001_i2c_stress_test_dev = { + .reg_info = { + .read_reg = OPT3001_REG_DEV_ID, + .read_val = OPT3001_DEVICE_ID, + .write_reg = OPT3001_REG_INT_LIMIT_LSB, + }, + .i2c_read_dev = &opt3001_i2c_read, + .i2c_write_dev = &opt3001_i2c_write, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_ALS */ diff --git a/driver/als_opt3001.h b/driver/als_opt3001.h index 3e21ba7db8..366e957995 100644 --- a/driver/als_opt3001.h +++ b/driver/als_opt3001.h @@ -29,4 +29,8 @@ int opt3001_init(void); int opt3001_read_lux(int *lux, int af); +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ALS +extern struct i2c_stress_test_dev opt3001_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_ALS_OPT3001_H */ diff --git a/driver/baro_bmp280.c b/driver/baro_bmp280.c index 6e394dbf72..3a3f3e3b6d 100644 --- a/driver/baro_bmp280.c +++ b/driver/baro_bmp280.c @@ -68,7 +68,7 @@ static const uint16_t standby_durn[] = {1, 63, 125, 250, 500, 1000, 2000, 4000}; -static inline int raw_read8(const int port, const int addr, const uint8_t reg, +static inline int raw_read8(const int port, const int addr, const int reg, int *data_ptr) { return i2c_read8(port, addr, reg, data_ptr); @@ -92,7 +92,7 @@ static inline int raw_read_n(const int port, const int addr, const uint8_t reg, /* * Write 8bit register from accelerometer. */ -static inline int raw_write8(const int port, const int addr, const uint8_t reg, +static inline int raw_write8(const int port, const int addr, const int reg, int data) { return i2c_write8(port, addr, reg, data); @@ -405,3 +405,15 @@ const struct accelgyro_drv bmp280_drv = { .set_data_rate = bmp280_set_data_rate, .get_data_rate = bmp280_get_data_rate, }; + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +struct i2c_stress_test_dev bmp280_i2c_stress_test_dev = { + .reg_info = { + .read_reg = BMP280_CHIP_ID_REG, + .read_val = BMP280_CHIP_ID, + .write_reg = BMP280_CONFIG_REG, + }, + .i2c_read = &raw_read8, + .i2c_write = &raw_write8, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_ACCEL */ diff --git a/driver/baro_bmp280.h b/driver/baro_bmp280.h index 1af1aa2125..cd4605ed1a 100644 --- a/driver/baro_bmp280.h +++ b/driver/baro_bmp280.h @@ -205,4 +205,9 @@ struct bmp280_drv_data_t { extern const struct accelgyro_drv bmp280_drv; extern struct bmp280_drv_data_t bmp280_drv_data; + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +extern struct i2c_stress_test_dev bmp280_i2c_stress_test_dev; +#endif + #endif diff --git a/driver/battery/smart.c b/driver/battery/smart.c index ff2da13863..9e7e9f3ec6 100644 --- a/driver/battery/smart.c +++ b/driver/battery/smart.c @@ -475,3 +475,36 @@ DECLARE_HOST_COMMAND(EC_CMD_SB_WRITE_BLOCK, host_command_sb_write_block, EC_VER_MASK(0)); #endif + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_BATTERY +test_mockable int sb_i2c_test_read(int cmd, int *param) +{ + char chemistry[sizeof(CONFIG_BATTERY_DEVICE_CHEMISTRY) + 1]; + int rv; + + if (cmd == SB_DEVICE_CHEMISTRY) { + rv = battery_device_chemistry(chemistry, + sizeof(CONFIG_BATTERY_DEVICE_CHEMISTRY)); + if (rv) + return rv; + if (strcasecmp(chemistry, CONFIG_BATTERY_DEVICE_CHEMISTRY)) + return EC_ERROR_UNKNOWN; + + *param = EC_SUCCESS; + return EC_SUCCESS; + } + + + return sb_read(cmd, param); +} + +struct i2c_stress_test_dev battery_i2c_stress_test_dev = { + .reg_info = { + .read_reg = SB_DEVICE_CHEMISTRY, + .read_val = EC_SUCCESS, + .write_reg = SB_AT_RATE, + }, + .i2c_read_dev = &sb_i2c_test_read, + .i2c_write_dev = &sb_write, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_BATTERY */ diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c index cbc8d04132..0dd5da99de 100644 --- a/driver/charger/bd9995x.c +++ b/driver/charger/bd9995x.c @@ -1231,3 +1231,25 @@ DECLARE_CONSOLE_COMMAND(amonbmon, console_command_amon_bmon, "amonbmon [a|b]", "Get charger AMON/BMON voltage diff, current"); #endif /* CONFIG_CMD_CHARGER_ADC_AMON_BMON */ + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_CHARGER +static int bd9995x_i2c_read(const int reg, int *data) +{ + return ch_raw_read16(reg, data, BD9995X_EXTENDED_COMMAND); +} + +static int bd9995x_i2c_write(const int reg, int data) +{ + return ch_raw_write16(reg, data, BD9995X_EXTENDED_COMMAND); +} + +struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev = { + .reg_info = { + .read_reg = BD9995X_CMD_CHIP_ID, + .read_val = BD9995X_CHIP_ID, + .write_reg = BD9995X_CMD_ITRICH_SET, + }, + .i2c_read_dev = &bd9995x_i2c_read, + .i2c_write_dev = &bd9995x_i2c_write, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_CHARGER */ diff --git a/driver/charger/bd9995x.h b/driver/charger/bd9995x.h index 91a0ac1bbd..baef184d09 100644 --- a/driver/charger/bd9995x.h +++ b/driver/charger/bd9995x.h @@ -359,4 +359,8 @@ void bd9995x_vbus_interrupt(enum gpio_signal signal); /* Read temperature measurement value (in Celsius) */ int bd9995x_get_battery_temp(int *temp_ptr); +#ifdef CONFIG_CMD_I2C_STRESS_TEST_CHARGER +extern struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_BD9995X_H */ diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c index 302be88030..689d6d1799 100644 --- a/driver/tcpm/anx74xx.c +++ b/driver/tcpm/anx74xx.c @@ -882,3 +882,15 @@ const struct tcpm_drv anx74xx_tcpm_drv = { .tcpc_discharge_vbus = &anx74xx_tcpc_discharge_vbus, #endif }; + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC +struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev = { + .reg_info = { + .read_reg = ANX74XX_REG_VENDOR_ID_L, + .read_val = ANX74XX_VENDOR_ID & 0xFF, + .write_reg = ANX74XX_REG_CC_SOFTWARE_CTRL, + }, + .i2c_read = &tcpc_i2c_read, + .i2c_write = &tcpc_i2c_write, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */ diff --git a/driver/tcpm/anx74xx.h b/driver/tcpm/anx74xx.h index de8d2b7fab..76bb44067e 100644 --- a/driver/tcpm/anx74xx.h +++ b/driver/tcpm/anx74xx.h @@ -13,6 +13,10 @@ #define ANX74XX_REG_IRQ_POL_LOW 0x00 #define ANX74XX_REG_IRQ_POL_HIGH 0x02 +#define ANX74XX_REG_VENDOR_ID_L 0x00 +#define ANX74XX_REG_VENDOR_ID_H 0x01 +#define ANX74XX_VENDOR_ID 0xAAAA + /* ANX F/W version:0x50:0x44 which contains otp firmware version */ #define ANX74XX_REG_FW_VERSION 0x44 @@ -162,4 +166,8 @@ void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq); void anx74xx_tcpc_clear_hpd_status(int port); int anx74xx_tcpc_get_fw_version(int port, int *version); +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC +extern struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_USB_PD_TCPM_ANX74XX_H */ diff --git a/driver/tcpm/ps8751.c b/driver/tcpm/ps8751.c index b9419a4696..f889f17134 100644 --- a/driver/tcpm/ps8751.c +++ b/driver/tcpm/ps8751.c @@ -67,3 +67,15 @@ int ps8751_tcpc_get_fw_version(int port, int *version) return tcpc_read(port, PS8751_REG_VERSION, version); } #endif + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC +struct i2c_stress_test_dev ps8751_i2c_stress_test_dev = { + .reg_info = { + .read_reg = PS8751_REG_VENDOR_ID_L, + .read_val = PS8751_VENDOR_ID & 0xFF, + .write_reg = PS8751_REG_CTRL_1, + }, + .i2c_read = &tcpc_i2c_read, + .i2c_write = &tcpc_i2c_write, +}; +#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */ diff --git a/driver/tcpm/ps8751.h b/driver/tcpm/ps8751.h index e0abb491ba..71325a7d4b 100644 --- a/driver/tcpm/ps8751.h +++ b/driver/tcpm/ps8751.h @@ -13,11 +13,18 @@ #define PS8751_PRODUCT_ID 0x8751 #define PS8751_REG_VERSION 0x90 +#define PS8751_REG_VENDOR_ID_L 0x00 +#define PS8751_REG_VENDOR_ID_H 0x01 #define PS8751_REG_CTRL_1 0xD0 #define PS8751_REG_CTRL_1_HPD (1 << 0) #define PS8751_REG_CTRL_1_IRQ (1 << 1) void ps8751_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq); int ps8751_tcpc_get_fw_version(int port, int *version); + +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC +extern struct i2c_stress_test_dev ps8751_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_USB_PD_TCPM_PS8751_H */ diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h index 2e24049246..7903cccffd 100644 --- a/driver/tcpm/tcpm.h +++ b/driver/tcpm/tcpm.h @@ -130,6 +130,20 @@ static inline void tcpc_discharge_vbus(int port, int enable) tcpc_config[port].drv->tcpc_discharge_vbus(port, enable); } +#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC +static inline int tcpc_i2c_read(const int port, const int addr, + const int reg, int *data) +{ + return tcpc_read(port, reg, data); +} + +static inline int tcpc_i2c_write(const int port, const int addr, + const int reg, int data) +{ + return tcpc_write(port, reg, data); +} +#endif + #else /** diff --git a/include/battery.h b/include/battery.h index e79ddd3adf..4f729895b9 100644 --- a/include/battery.h +++ b/include/battery.h @@ -333,4 +333,8 @@ void print_battery_debug(void); */ enum battery_disconnect_state battery_get_disconnect_state(void); +#ifdef CONFIG_CMD_I2C_STRESS_TEST_BATTERY +extern struct i2c_stress_test_dev battery_i2c_stress_test_dev; +#endif + #endif /* __CROS_EC_BATTERY_H */ diff --git a/include/config.h b/include/config.h index 5ec402d8a6..66732dd198 100644 --- a/include/config.h +++ b/include/config.h @@ -207,6 +207,9 @@ */ #undef CONFIG_BATTERY_SMART +/* Chemistry of the battery device */ +#undef CONFIG_BATTERY_DEVICE_CHEMISTRY + /* * Critical battery shutdown timeout (seconds) * @@ -592,6 +595,12 @@ #undef CONFIG_CMD_HOSTCMD #undef CONFIG_CMD_I2C_PROTECT #define CONFIG_CMD_I2C_SCAN +#undef CONFIG_CMD_I2C_STRESS_TEST +#undef CONFIG_CMD_I2C_STRESS_TEST_ACCEL +#undef CONFIG_CMD_I2C_STRESS_TEST_ALS +#undef CONFIG_CMD_I2C_STRESS_TEST_BATTERY +#undef CONFIG_CMD_I2C_STRESS_TEST_CHARGER +#undef CONFIG_CMD_I2C_STRESS_TEST_TCPC #define CONFIG_CMD_I2C_XFER #undef CONFIG_CMD_I2CWEDGE #define CONFIG_CMD_IDLE_STATS diff --git a/include/i2c.h b/include/i2c.h index d3329df64a..ddd3dd3c7f 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -40,6 +40,42 @@ struct i2c_port_t { extern const struct i2c_port_t i2c_ports[]; extern const unsigned int i2c_ports_used; +#ifdef CONFIG_CMD_I2C_STRESS_TEST +struct i2c_test_reg_info { + int read_reg; /* Read register (WHO_AM_I, DEV_ID, MAN_ID) */ + int read_val; /* Expected val (WHO_AM_I, DEV_ID, MAN_ID) */ + int write_reg; /* Read/Write reg which doesn't impact the system */ +}; + +struct i2c_test_results { + int read_success; /* Successful read count */ + int read_fail; /* Read fail count */ + int write_success; /* Successful write count */ + int write_fail; /* Write fail count */ +}; + +/* Data structure to define I2C test configuration. */ +struct i2c_stress_test_dev { + struct i2c_test_reg_info reg_info; + struct i2c_test_results test_results; + int (*i2c_read)(const int port, const int addr, + const int reg, int *data); + int (*i2c_write)(const int port, const int addr, + const int reg, int data); + int (*i2c_read_dev)(const int reg, int *data); + int (*i2c_write_dev)(const int reg, int data); +}; + +struct i2c_stress_test { + int port; + int addr; + struct i2c_stress_test_dev *i2c_test; +}; + +extern struct i2c_stress_test i2c_stress_tests[]; +extern const int i2c_test_dev_used; +#endif + /* Flags for i2c_xfer() */ #define I2C_XFER_START (1 << 0) /* Start smbus session from idle state */ #define I2C_XFER_STOP (1 << 1) /* Terminate smbus session with stop bit */ |