diff options
author | Abe Levkoy <alevkoy@chromium.org> | 2021-10-12 16:56:07 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-10-18 16:44:14 +0000 |
commit | 5afc756fc190224e533ed90c4e3cf574fad6af33 (patch) | |
tree | 0187efd4935d2450dbcdf63283ae9eb01df0effb | |
parent | b7f5f40c7d183e4c79451106c8b434ddf3265db3 (diff) | |
download | chrome-ec-5afc756fc190224e533ed90c4e3cf574fad6af33.tar.gz |
zephyr test: SYV682 VCONN_OC interrupt
Simulate VCONN OC and verify that the driver handles it as expected.
Increase syv682x.c line coverage 65.4% -> 68.8%.
BUG=b:190519131
TEST=zmake configure --test zephyr/test/drivers
BRANCH=none
Signed-off-by: Abe Levkoy <alevkoy@chromium.org>
Change-Id: Ifa9ff4129ef0f158e2f59314dbf62ee53b6180e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3219870
Reviewed-by: Yuval Peress <peress@google.com>
-rw-r--r-- | zephyr/emul/emul_syv682x.c | 32 | ||||
-rw-r--r-- | zephyr/include/emul/emul_syv682x.h | 11 | ||||
-rw-r--r-- | zephyr/test/drivers/src/ppc.c | 35 |
3 files changed, 75 insertions, 3 deletions
diff --git a/zephyr/emul/emul_syv682x.c b/zephyr/emul/emul_syv682x.c index 2148851b56..2bc18b7089 100644 --- a/zephyr/emul/emul_syv682x.c +++ b/zephyr/emul/emul_syv682x.c @@ -82,6 +82,26 @@ void syv682x_emul_set_status(struct i2c_emul *emul, uint8_t val) */ } +void syv682x_emul_set_control_4(struct i2c_emul *emul, uint8_t val) +{ + struct syv682x_emul_data *data; + uint8_t val_interrupt = val & SYV682X_CONTROL_4_INT_MASK; + + data = CONTAINER_OF(emul, struct syv682x_emul_data, emul); + data->control_4_cond = val_interrupt; + /* Only update the interrupting bits. */ + data->reg[SYV682X_CONTROL_4_REG] &= ~SYV682X_CONTROL_4_INT_MASK; + data->reg[SYV682X_CONTROL_4_REG] |= val_interrupt; + + /* + * Note: The description of CONTROL_4 suggests that setting VCONN_OC + * will turn off the VCONN channel. The "VCONN Channel Over Current + * Response" plot shows that VCONN the device will merely throttle VCONN + * current. The latter behavior is observed in practice, and this + * emulator does not currently model it. + */ +} + int syv682x_emul_get_reg(struct i2c_emul *emul, int reg, uint8_t *val) { struct syv682x_emul_data *data; @@ -142,6 +162,10 @@ static int syv682x_emul_transfer(struct i2c_emul *emul, struct i2c_msg *msgs, SYV682X_STATUS_OVP)) val |= SYV682X_CONTROL_1_PWR_ENB; break; + case SYV682X_CONTROL_4_REG: + /* Interrupt bits are read-only. */ + val &= ~SYV682X_CONTROL_4_INT_MASK; + break; default: break; } @@ -167,14 +191,16 @@ static int syv682x_emul_transfer(struct i2c_emul *emul, struct i2c_msg *msgs, switch (reg) { /* - * These registers are clear-on-read (if the underlying - * condition has cleared). + * STATUS and the interrupt bits of CONTROL_4 are clear-on-read + * (if the underlying condition has cleared). */ case SYV682X_STATUS_REG: syv682x_emul_set_reg(emul, reg, data->status_cond); break; case SYV682X_CONTROL_4_REG: - syv682x_emul_set_reg(emul, reg, data->control_4_cond); + syv682x_emul_set_reg(emul, reg, + (*buf & ~SYV682X_CONTROL_4_INT_MASK) | + data->control_4_cond); break; default: break; diff --git a/zephyr/include/emul/emul_syv682x.h b/zephyr/include/emul/emul_syv682x.h index aa0d8840f7..46580e8257 100644 --- a/zephyr/include/emul/emul_syv682x.h +++ b/zephyr/include/emul/emul_syv682x.h @@ -119,6 +119,17 @@ struct i2c_emul *syv682x_emul_get(int ord); void syv682x_emul_set_status(struct i2c_emul *emul, uint8_t val); /** + * @brief Set the underlying interrupt conditions affecting the control 4 + * register + * + * @param emul SYV682x emulator + * @param val A control 4 register value corresponding to the underlying + * conditions; only the bits in SYV682X_CONTROL_4_INT_MASK have an + * effect. + */ +void syv682x_emul_set_control_4(struct i2c_emul *emul, uint8_t val); + +/** * @brief Set value of a register of SYV682x * * @param emul SYV682x emulator diff --git a/zephyr/test/drivers/src/ppc.c b/zephyr/test/drivers/src/ppc.c index 7f736c4938..82b0aeb6c9 100644 --- a/zephyr/test/drivers/src/ppc.c +++ b/zephyr/test/drivers/src/ppc.c @@ -121,6 +121,41 @@ static void test_ppc_syv682x_interrupt(void) SYV682X_CONTROL_1_PWR_ENB, "Power path enabled after HV_OC handled 3 times"); syv682x_emul_set_status(emul, 0); + + /* + * A VCONN OC event less than 100 ms should not cause the driver to turn + * VCONN off. + */ + ppc_set_vconn(syv682x_port, true); + syv682x_emul_set_control_4(emul, SYV682X_CONTROL_4_VCONN_OCP); + syv682x_interrupt(syv682x_port); + msleep(1); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), + "Reading CONTROL_4 failed"); + zassert_true(reg & + (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2), + "VCONN disabled after initial VCONN OC"); + msleep(50); + syv682x_interrupt(syv682x_port); + msleep(1); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), + "Reading CONTROL_4 failed"); + zassert_true(reg & + (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2), + "VCONN disabled after short VCONN OC"); + /* + * But if the event keeps going for over 100 ms continuously, the driver + * should turn VCONN off. + */ + msleep(60); + syv682x_interrupt(syv682x_port); + msleep(1); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), + "Reading CONTROL_4 failed"); + zassert_false(reg & + (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2), + "VCONN enabled after long VCONN OC"); + syv682x_emul_set_control_4(emul, 0x0); } static void test_ppc_syv682x(void) |