diff options
author | Tomasz Michalec <tm@semihalf.com> | 2022-01-05 16:50:39 +0100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-01-14 23:06:14 +0000 |
commit | e5e5f8843baeac7e5aec82d3fba7d2739f669f11 (patch) | |
tree | 5ac39185d7e5ce2623fa84bf365a3cbc78966e3f | |
parent | 73bf71c5681f27da09b99cd6327c5f1157a7031f (diff) | |
download | chrome-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.c | 39 |
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); } |