summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbe Levkoy <alevkoy@chromium.org>2021-10-12 16:56:07 -0600
committerCommit Bot <commit-bot@chromium.org>2021-10-18 16:44:14 +0000
commit5afc756fc190224e533ed90c4e3cf574fad6af33 (patch)
tree0187efd4935d2450dbcdf63283ae9eb01df0effb
parentb7f5f40c7d183e4c79451106c8b434ddf3265db3 (diff)
downloadchrome-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.c32
-rw-r--r--zephyr/include/emul/emul_syv682x.h11
-rw-r--r--zephyr/test/drivers/src/ppc.c35
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, &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, &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, &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)