summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2022-01-05 16:50:39 +0100
committerCommit Bot <commit-bot@chromium.org>2022-01-14 23:06:14 +0000
commite5e5f8843baeac7e5aec82d3fba7d2739f669f11 (patch)
tree5ac39185d7e5ce2623fa84bf365a3cbc78966e3f
parent73bf71c5681f27da09b99cd6327c5f1157a7031f (diff)
downloadchrome-ec-e5e5f8843baeac7e5aec82d3fba7d2739f669f11.tar.gz
zephyr: emul: Fix TCPCI alert on power status change
Fix TCPCI emulator to generate alert when power status change while connecting or disconnecting TCPCI emulator partners. Now setting POWER_STATUS, FAULT_STATUS, EXT_STATUS or ALERT_EXT register using tcpci_emul_set_reg() will also set corresponding bit in ALERT register. BUG=none BRANCH=none TEST=make configure --test zephyr/test/drivers Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: I79a61866fad69253ced9c468d301988e270cc793 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3368262 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org> Tested-by: Tomasz Michalec <tmichalec@google.com> Commit-Queue: Tomasz Michalec <tmichalec@google.com>
-rw-r--r--zephyr/emul/tcpc/emul_tcpci.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/zephyr/emul/tcpc/emul_tcpci.c b/zephyr/emul/tcpc/emul_tcpci.c
index 660f62ead0..18249bed55 100644
--- a/zephyr/emul/tcpc/emul_tcpci.c
+++ b/zephyr/emul/tcpc/emul_tcpci.c
@@ -104,12 +104,35 @@ static int tcpci_emul_reg_bytes(int reg)
int tcpci_emul_set_reg(const struct emul *emul, int reg, uint16_t val)
{
struct tcpci_emul_data *data = emul->data;
+ uint16_t update_alert = 0;
+ uint16_t alert;
int byte;
if (reg < 0 || reg > TCPCI_EMUL_REG_COUNT) {
return -EINVAL;
}
+ /* Changing some registers has impact on alert register */
+ switch (reg) {
+ case TCPC_REG_POWER_STATUS:
+ update_alert = TCPC_REG_ALERT_POWER_STATUS;
+ break;
+ case TCPC_REG_FAULT_STATUS:
+ update_alert = TCPC_REG_ALERT_FAULT;
+ break;
+ case TCPC_REG_EXT_STATUS:
+ update_alert = TCPC_REG_ALERT_EXT_STATUS;
+ break;
+ case TCPC_REG_ALERT_EXT:
+ update_alert = TCPC_REG_ALERT_ALERT_EXT;
+ break;
+ }
+
+ if (update_alert != 0) {
+ tcpci_emul_get_reg(emul, TCPC_REG_ALERT, &alert);
+ tcpci_emul_set_reg(emul, TCPC_REG_ALERT, alert | update_alert);
+ }
+
for (byte = tcpci_emul_reg_bytes(reg); byte > 0; byte--) {
data->reg[reg] = val & 0xff;
val >>= 8;
@@ -179,7 +202,7 @@ static bool tcpci_emul_check_int(const struct emul *emul)
return true;
}
- if (alert & alert_mask & TCPC_REG_POWER_STATUS &&
+ if (alert & alert_mask & TCPC_REG_ALERT_POWER_STATUS &&
data->reg[TCPC_REG_POWER_STATUS] &
data->reg[TCPC_REG_POWER_STATUS_MASK]) {
return true;
@@ -475,8 +498,10 @@ int tcpci_emul_disconnect_partner(const struct emul *emul)
/* Clear VBUS present in case if source partner is disconnected */
tcpci_emul_get_reg(emul, TCPC_REG_POWER_STATUS, &power_status);
- tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS,
- power_status & ~TCPC_REG_POWER_STATUS_VBUS_PRES);
+ if (power_status & TCPC_REG_POWER_STATUS_VBUS_PRES) {
+ power_status &= ~TCPC_REG_POWER_STATUS_VBUS_PRES;
+ tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, power_status);
+ }
return 0;
}
@@ -674,11 +699,11 @@ static int tcpci_emul_reset(const struct emul *emul)
*/
static int tcpci_emul_set_i2c_interface_err(const struct emul *emul)
{
- struct tcpci_emul_data *data = emul->data;
+ uint16_t fault_status;
- data->reg[TCPC_REG_FAULT_STATUS] |=
- TCPC_REG_FAULT_STATUS_I2C_INTERFACE_ERR;
- data->reg[TCPC_REG_ALERT + 1] |= TCPC_REG_ALERT_FAULT >> 8;
+ tcpci_emul_get_reg(emul, TCPC_REG_FAULT_STATUS, &fault_status);
+ fault_status |= TCPC_REG_FAULT_STATUS_I2C_INTERFACE_ERR;
+ tcpci_emul_set_reg(emul, TCPC_REG_FAULT_STATUS, fault_status);
return tcpci_emul_alert_changed(emul);
}