summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadhurima Paruchuri <mparuchuri@google.com>2023-03-15 18:54:35 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-12 12:23:47 +0000
commitca4eb6b6aea1c24c01923bb38a67065960d15ad4 (patch)
tree8c813d15a194ad527b016a21e9e8cd0635e2c1da
parent48cde011ac52a82e5c34d8b50a17c1ae63deaa45 (diff)
downloadchrome-ec-ca4eb6b6aea1c24c01923bb38a67065960d15ad4.tar.gz
retimer: Add emulator and unit tests for ANX7452 retimer driver
BUG=b:267589042 BRANCH=none TEST=./twister -s drivers/drivers.anx7452 -c --coverage Change-Id: I7b4dcef7e667cd69ecb39f6dda7a6c8570177f40 Signed-off-by: Madhurima Paruchuri <mparuchuri@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4303379 Reviewed-by: Fabio Baltieri <fabiobaltieri@google.com>
-rw-r--r--zephyr/emul/CMakeLists.txt1
-rw-r--r--zephyr/emul/Kconfig11
-rw-r--r--zephyr/emul/emul_anx7452.c262
-rw-r--r--zephyr/include/emul/emul_anx7452.h81
-rw-r--r--zephyr/test/drivers/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/Kconfig6
-rw-r--r--zephyr/test/drivers/anx7452/CMakeLists.txt6
-rw-r--r--zephyr/test/drivers/anx7452/prj.conf3
-rw-r--r--zephyr/test/drivers/anx7452/src/anx7452.c288
-rw-r--r--zephyr/test/drivers/anx7452/usbc.dts32
-rw-r--r--zephyr/test/drivers/testcase.yaml9
11 files changed, 700 insertions, 0 deletions
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt
index 523e1e98b0..58eef44627 100644
--- a/zephyr/emul/CMakeLists.txt
+++ b/zephyr/emul/CMakeLists.txt
@@ -7,6 +7,7 @@ add_subdirectory("tcpc")
cros_ec_library_include_directories(include)
+zephyr_library_sources_ifdef(CONFIG_EMUL_ANX7452 emul_anx7452.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BB_RETIMER emul_bb_retimer.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BC12_DETECT_PI3USB9201 emul_pi3usb9201.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BMA255 emul_bma255.c)
diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig
index b160e430b2..ecdbfb426c 100644
--- a/zephyr/emul/Kconfig
+++ b/zephyr/emul/Kconfig
@@ -190,6 +190,17 @@ config EMUL_PCT2075
Enable the PCT2075 temperature sensor emulator. It uses emulated I2C bus.
Emulator API is available in zephyr/include/emul/emul_pct2075.h.
+config EMUL_ANX7452
+ bool "ANX7452 retimer emulator"
+ default y
+ depends on ZTEST && DT_HAS_ANALOGIX_ANX7452_ENABLED
+ select EMUL_COMMON_I2C
+ help
+ Enable the ANX7452(Analogix) retimer emulator. This driver use
+ emulated I2C bus. It is used to test anx7452 driver. It supports
+ reads and writes to all emulator registers. Emulators API is
+ available in zephyr/include/emul/emul_anx7452.h
+
config EMUL_PS8743
bool "PS8743 emulator"
default y
diff --git a/zephyr/emul/emul_anx7452.c b/zephyr/emul/emul_anx7452.c
new file mode 100644
index 0000000000..f9854d4081
--- /dev/null
+++ b/zephyr/emul/emul_anx7452.c
@@ -0,0 +1,262 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "driver/retimer/anx7452.h"
+#include "emul/emul_anx7452.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_stub_device.h"
+
+#include <zephyr/device.h>
+#include <zephyr/drivers/emul.h>
+#include <zephyr/drivers/i2c.h>
+#include <zephyr/drivers/i2c_emul.h>
+#include <zephyr/logging/log.h>
+
+#define DT_DRV_COMPAT analogix_anx7452
+
+#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
+LOG_MODULE_REGISTER(emul_anx7452);
+
+/** Run-time data used by the emulator */
+struct anx7452_emul_data {
+ /** Common I2C data */
+ struct i2c_common_emul_data top_data;
+ struct i2c_common_emul_data ctltop_data;
+
+ /** Configuration information */
+ const struct anx7452_emul_cfg *cfg;
+
+ /** Current state of all emulated ANX7452 retimer registers */
+ uint8_t top_reg;
+
+ uint8_t ctltop_cfg0_reg;
+
+ uint8_t ctltop_cfg1_reg;
+
+ uint8_t ctltop_cfg2_reg;
+};
+
+/** Constant configuration of the emulator */
+struct anx7452_emul_cfg {
+ const struct i2c_common_emul_cfg top_cfg;
+ const struct i2c_common_emul_cfg ctltop_cfg;
+};
+
+/* Workhorse for mapping i2c reg to internal emulator data access */
+static uint8_t *anx7452_emul_get_reg_ptr(struct anx7452_emul_data *data,
+ int reg)
+{
+ switch (reg) {
+ case ANX7452_TOP_STATUS_REG:
+ return &(data->top_reg);
+ case ANX7452_CTLTOP_CFG0_REG:
+ return &(data->ctltop_cfg0_reg);
+ case ANX7452_CTLTOP_CFG1_REG:
+ return &(data->ctltop_cfg1_reg);
+ case ANX7452_CTLTOP_CFG2_REG:
+ return &(data->ctltop_cfg2_reg);
+ default:
+ __ASSERT(false, "Unimplemented Register Access Error on 0x%x",
+ reg);
+ /* Statement never reached, required for compiler warnings */
+ return NULL;
+ }
+}
+
+/** Check description in emul_anx7452.h */
+void anx7452_emul_set_reg(const struct emul *emul, int reg, uint8_t val)
+{
+ struct anx7452_emul_data *data = emul->data;
+
+ uint8_t *reg_to_write = anx7452_emul_get_reg_ptr(data, reg);
+ *reg_to_write = val;
+}
+
+/** Check description in emul_anx7452.h */
+uint8_t anx7452_emul_get_reg(const struct emul *emul, int reg)
+{
+ struct anx7452_emul_data *data = emul->data;
+ uint8_t *reg_to_read = anx7452_emul_get_reg_ptr(data, reg);
+
+ return *reg_to_read;
+}
+
+/** Check description in emul_anx7452.h */
+void anx7452_emul_reset(const struct emul *emul)
+{
+ struct anx7452_emul_data *data;
+
+ data = emul->data;
+
+ data->top_reg = 0xFF;
+
+ data->ctltop_cfg0_reg = 0x00;
+
+ data->ctltop_cfg1_reg = 0x00;
+
+ data->ctltop_cfg2_reg = 0x00;
+}
+
+static int anx7452_emul_write_byte(const struct emul *emul, int reg,
+ uint8_t val, int bytes)
+{
+ struct anx7452_emul_data *data = emul->data;
+
+ uint8_t *reg_to_write = anx7452_emul_get_reg_ptr(data, reg);
+ *reg_to_write = val;
+
+ return 0;
+}
+
+static int anx7452_emul_read_byte(const struct emul *emul, int reg,
+ uint8_t *val, int bytes)
+{
+ struct anx7452_emul_data *data = emul->data;
+ uint8_t *reg_to_read = anx7452_emul_get_reg_ptr(data, reg);
+
+ *val = *reg_to_read;
+
+ return 0;
+}
+
+/**
+ * Emulate an I2C transfer for ANX7452
+ *
+ * This handles simple reads and writes
+ *
+ * @param emul I2C emulation information
+ * @param msgs List of messages to process
+ * @param num_msgs Number of messages to process
+ * @param addr Address of the I2C target device
+ *
+ * @retval 0 If successful
+ * @retval -EIO General input / output error
+ */
+static int anx7452_emul_transfer(const struct emul *emul, struct i2c_msg *msgs,
+ int num_msgs, int addr)
+{
+ const struct anx7452_emul_cfg *cfg;
+ struct anx7452_emul_data *data;
+ struct i2c_common_emul_data *common_data;
+
+ data = emul->data;
+ cfg = emul->cfg;
+
+ if (addr == cfg->top_cfg.addr) {
+ const struct i2c_common_emul_cfg *common_cfg = &cfg->top_cfg;
+
+ common_data = &data->top_data;
+ return i2c_common_emul_transfer_workhorse(
+ emul, common_data, common_cfg, msgs, num_msgs, addr);
+ } else if (addr == cfg->ctltop_cfg.addr) {
+ const struct i2c_common_emul_cfg *common_cfg = &cfg->ctltop_cfg;
+
+ common_data = &data->ctltop_data;
+ return i2c_common_emul_transfer_workhorse(
+ emul, common_data, common_cfg, msgs, num_msgs, addr);
+ }
+
+ LOG_ERR("Cannot map address %02x", addr);
+ return -EIO;
+}
+
+/* Device instantiation */
+
+static struct i2c_emul_api anx7452_emul_api = {
+ .transfer = anx7452_emul_transfer,
+};
+
+/* Device instantiation */
+
+/**
+ * @brief Set up a new ANX7452 retimer emulator
+ *
+ * This should be called for each ANX7452 retimer device that needs to be
+ * emulated. It registers it with the I2C emulation controller.
+ *
+ * @param emul Emulation information
+ * @param parent Device to emulate
+ *
+ * @return 0 indicating success (always)
+ */
+static int anx7452_emul_init(const struct emul *emul,
+ const struct device *parent)
+{
+ const struct anx7452_emul_cfg *cfg;
+ struct anx7452_emul_data *data;
+ int ret = 0;
+
+ data = emul->data;
+ cfg = emul->cfg;
+
+ data->top_data.emul.api = &anx7452_emul_api;
+ data->top_data.emul.addr = cfg->top_cfg.addr;
+ data->top_data.emul.target = emul;
+ data->top_data.i2c = parent;
+ data->top_data.cfg = &cfg->top_cfg;
+ i2c_common_emul_init(&data->top_data);
+
+ data->ctltop_data.emul.api = &anx7452_emul_api;
+ data->ctltop_data.emul.addr = cfg->ctltop_cfg.addr;
+ data->ctltop_data.emul.target = emul;
+ data->ctltop_data.i2c = parent;
+ data->ctltop_data.cfg = &cfg->ctltop_cfg;
+ i2c_common_emul_init(&data->ctltop_data);
+
+ ret |= i2c_emul_register(parent, &data->top_data.emul);
+ ret |= i2c_emul_register(parent, &data->ctltop_data.emul);
+
+ anx7452_emul_reset(emul);
+
+ return ret;
+}
+
+#define ANX7452_EMUL(n) \
+ static struct anx7452_emul_data anx7452_emul_data_##n = { \
+ .top_data = { \
+ .write_byte = anx7452_emul_write_byte, \
+ .read_byte = anx7452_emul_read_byte, \
+ }, \
+ .ctltop_data = { \
+ .write_byte = anx7452_emul_write_byte, \
+ .read_byte = anx7452_emul_read_byte, \
+ }, \
+ }; \
+ static const struct anx7452_emul_cfg anx7452_emul_cfg_##n = { \
+ .top_cfg = { \
+ .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \
+ .data = &anx7452_emul_data_##n.top_data, \
+ .addr = DT_INST_REG_ADDR(n), \
+ }, \
+ .ctltop_cfg = { \
+ .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \
+ .data = &anx7452_emul_data_##n.ctltop_data, \
+ .addr = ANX7452_I2C_ADDR_CTLTOP_FLAGS, \
+ }, \
+ }; \
+ EMUL_DT_INST_DEFINE(n, anx7452_emul_init, &anx7452_emul_data_##n, \
+ &anx7452_emul_cfg_##n, &anx7452_emul_api, NULL)
+
+DT_INST_FOREACH_STATUS_OKAY(ANX7452_EMUL);
+
+DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE);
+
+struct i2c_common_emul_data *
+emul_anx7452_get_i2c_common_data(const struct emul *emul,
+ enum anx7452_emul_port port)
+{
+ struct anx7452_emul_data *data;
+
+ data = emul->data;
+
+ switch (port) {
+ case TOP_EMUL_PORT:
+ return &data->top_data;
+ case CTLTOP_EMUL_PORT:
+ return &data->ctltop_data;
+ default:
+ return NULL;
+ }
+}
diff --git a/zephyr/include/emul/emul_anx7452.h b/zephyr/include/emul/emul_anx7452.h
new file mode 100644
index 0000000000..455958f664
--- /dev/null
+++ b/zephyr/include/emul/emul_anx7452.h
@@ -0,0 +1,81 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for ANX7452 retimer emulator
+ */
+
+#ifndef __EMUL_ANX7452_H
+#define __EMUL_ANX7452_H
+
+#include <zephyr/drivers/emul.h>
+#include <zephyr/drivers/i2c.h>
+#include <zephyr/drivers/i2c_emul.h>
+
+/** Types of "hidden" I2C devices */
+enum anx7452_emul_port {
+ TOP_EMUL_PORT,
+ CTLTOP_EMUL_PORT,
+};
+
+/**
+ * @brief ANX7452 retimer emulator backend API
+ * @defgroup anx7452_emul ANX7452 retimer emulator
+ * @{
+ *
+ * ANX7452 retimer emulator supports access to all its registers using I2C
+ * messages. Application may alter emulator state:
+ *
+ * - call @ref anx7452_emul_set_reg and @ref anx7452_emul_get_reg to set and get
+ * value of ANX7452 retimers registers
+ * - call anx7452_emul_set_err_* to change emulator behaviour on inadvisable
+ * driver behaviour
+ * - call functions from emul_common_i2c.h to setup custom handlers for I2C
+ * messages
+ */
+
+/**
+ * @brief Set value of given register of ANX7452 retimer
+ *
+ * @param emul Pointer to ANX7452 retimer emulator
+ * @param reg Register address which value will be changed
+ * @param val New value of the register
+ */
+void anx7452_emul_set_reg(const struct emul *emul, int reg, uint8_t val);
+
+/**
+ * @brief Get value of given register of ANX7452 retimer
+ *
+ * @param emul Pointer to ANX7452 retimer emulator
+ * @param reg Register address
+ *
+ * @return Value of the register
+ */
+uint8_t anx7452_emul_get_reg(const struct emul *emul, int reg);
+
+/**
+ * @brief Reset the anx7452 emulator
+ *
+ * @param emul The emulator to reset
+ */
+void anx7452_emul_reset(const struct emul *emul);
+
+/**
+ * @brief Returns pointer to i2c_common_emul_data for given emul
+ *
+ * @param emul Pointer to anx7452 retimer emulator
+ * @return Pointer to i2c_common_emul_data for emul argument
+ */
+struct i2c_common_emul_data *
+emul_anx7452_get_i2c_common_data(const struct emul *emul,
+ enum anx7452_emul_port port);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_ANX7452 */
diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt
index 2d7fc8a56b..2b2688ce4d 100644
--- a/zephyr/test/drivers/CMakeLists.txt
+++ b/zephyr/test/drivers/CMakeLists.txt
@@ -73,6 +73,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_LED_COMMON led_common)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PS8XXX ps8xxx)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_GPIO_UNHOOK gpio_unhook)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_HOST_COMMAND_MEMORY_DUMP host_command_memory_dump)
+add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ANX7452 anx7452)
get_target_property(TEST_SOURCES_NEW app SOURCES)
diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig
index 256e086bd4..726859068f 100644
--- a/zephyr/test/drivers/Kconfig
+++ b/zephyr/test/drivers/Kconfig
@@ -236,4 +236,10 @@ config LINK_TEST_SUITE_LED_COMMON
config LINK_TEST_SUITE_HOST_COMMAND_MEMORY_DUMP
bool "Link and test memory dump host commands tests"
+config LINK_TEST_SUITE_ANX7452
+ bool "Link and test the anx7452 tests"
+ help
+ Include the test suite of ANX7452 retimer in the binary. The tests
+ use I2C emulation.
+
source "Kconfig.zephyr"
diff --git a/zephyr/test/drivers/anx7452/CMakeLists.txt b/zephyr/test/drivers/anx7452/CMakeLists.txt
new file mode 100644
index 0000000000..a61fa0a1c6
--- /dev/null
+++ b/zephyr/test/drivers/anx7452/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Add source files
+target_sources(app PRIVATE src/anx7452.c)
diff --git a/zephyr/test/drivers/anx7452/prj.conf b/zephyr/test/drivers/anx7452/prj.conf
new file mode 100644
index 0000000000..96bb372274
--- /dev/null
+++ b/zephyr/test/drivers/anx7452/prj.conf
@@ -0,0 +1,3 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
diff --git a/zephyr/test/drivers/anx7452/src/anx7452.c b/zephyr/test/drivers/anx7452/src/anx7452.c
new file mode 100644
index 0000000000..f456dea845
--- /dev/null
+++ b/zephyr/test/drivers/anx7452/src/anx7452.c
@@ -0,0 +1,288 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "chipset.h"
+#include "common.h"
+#include "console.h"
+#include "driver/retimer/anx7452.h"
+#include "driver/retimer/anx7452_public.h"
+#include "emul/emul_anx7452.h"
+#include "emul/emul_common_i2c.h"
+#include "i2c.h"
+#include "test/drivers/stubs.h"
+#include "test/drivers/test_mocks.h"
+#include "test/drivers/test_state.h"
+#include "timer.h"
+#include "usb_mux.h"
+
+#include <zephyr/device.h>
+#include <zephyr/devicetree.h>
+#include <zephyr/drivers/emul.h>
+#include <zephyr/drivers/gpio.h>
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/fff.h>
+#include <zephyr/kernel.h>
+#include <zephyr/ztest.h>
+
+#define GPIO_USB_C1_USB_EN_PATH NAMED_GPIOS_GPIO_NODE(usb_c1_ls_en)
+#define GPIO_USB_C1_USB_EN_PORT DT_GPIO_PIN(GPIO_USB_C1_USB_EN_PATH, gpios)
+#define GPIO_USB_C1_DP_EN_PATH NAMED_GPIOS_GPIO_NODE(usb_c1_rt_rst_odl)
+#define GPIO_USB_C1_DP_EN_PORT DT_GPIO_PIN(GPIO_USB_C1_DP_EN_PATH, gpios)
+
+#define ANX7452_NODE DT_NODELABEL(usb_c1_anx7452_emul)
+#define EMUL EMUL_DT_GET(ANX7452_NODE)
+#define COMMON_DATA(port) emul_anx7452_get_i2c_common_data(EMUL, port)
+
+ZTEST(anx7452, test_anx7452_init)
+{
+ const struct device *gpio_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_USB_EN_PATH, gpios));
+
+ zassert_not_null(gpio_dev, "Cannot get GPIO device");
+
+ /* Test successful init */
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_TOP_STATUS_REG), 0xFF,
+ NULL);
+ zassert_equal(
+ EC_SUCCESS,
+ anx7452_usb_retimer_driver.init(usb_muxes[USBC_PORT_C1].mux),
+ NULL);
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_TOP_STATUS_REG),
+ ANX7452_TOP_REG_EN, NULL);
+ zassert_equal(1,
+ gpio_emul_output_get(gpio_dev, GPIO_USB_C1_USB_EN_PORT),
+ NULL);
+
+ /* Setup emulator fail on write */
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ ANX7452_TOP_STATUS_REG);
+ /* With reg read fail, init should fail and pins should be unset */
+ zassert_equal(
+ EC_ERROR_INVAL,
+ anx7452_usb_retimer_driver.init(usb_muxes[USBC_PORT_C1].mux),
+ NULL);
+ zassert_equal(1,
+ gpio_emul_output_get(gpio_dev, GPIO_USB_C1_USB_EN_PORT),
+ NULL);
+
+ /* Do not fail on write */
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ /* Setup emulator fail on read */
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ ANX7452_TOP_STATUS_REG);
+ /* With reg read fail, init should fail and pins should be unset */
+ zassert_equal(
+ EC_ERROR_TIMEOUT,
+ anx7452_usb_retimer_driver.init(usb_muxes[USBC_PORT_C1].mux),
+ NULL);
+ zassert_equal(1,
+ gpio_emul_output_get(gpio_dev, GPIO_USB_C1_USB_EN_PORT),
+ NULL);
+
+ /* Do not fail on read */
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ /* Setup emulator fail on read */
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ ANX7452_TOP_STATUS_REG);
+ const uint32_t start_ms = k_uptime_get();
+ /* With reg read fail, init should fail and pins should be unset */
+ zassert_equal(
+ EC_ERROR_TIMEOUT,
+ anx7452_usb_retimer_driver.init(usb_muxes[USBC_PORT_C1].mux),
+ NULL);
+ const uint32_t end_ms = k_uptime_get();
+ /* With timeout caused by read fail, the time took should be greater
+ * than or equal to configured timeout value
+ */
+ zassert_true((end_ms - start_ms) >= ANX7452_I2C_WAKE_TIMEOUT_MS, NULL);
+ zassert_equal(1,
+ gpio_emul_output_get(gpio_dev, GPIO_USB_C1_USB_EN_PORT),
+ NULL);
+}
+
+ZTEST(anx7452, test_anx7452_get)
+{
+ mux_state_t mux_state = 0;
+
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+
+ anx7452_emul_set_reg(EMUL, ANX7452_TOP_STATUS_REG,
+ ANX7452_TOP_REG_EN | ANX7452_TOP_FLIP_INFO);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+ zassert_equal(mux_state, USB_PD_MUX_POLARITY_INVERTED);
+
+ anx7452_emul_set_reg(EMUL, ANX7452_TOP_STATUS_REG,
+ ANX7452_TOP_REG_EN | ANX7452_TOP_DP_INFO);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+ zassert_equal(mux_state, USB_PD_MUX_DP_ENABLED);
+
+ anx7452_emul_set_reg(EMUL, ANX7452_TOP_STATUS_REG,
+ ANX7452_TOP_REG_EN | ANX7452_TOP_TBT_INFO);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+ zassert_equal(mux_state, USB_PD_MUX_TBT_COMPAT_ENABLED);
+
+ anx7452_emul_set_reg(EMUL, ANX7452_TOP_STATUS_REG,
+ ANX7452_TOP_REG_EN | ANX7452_TOP_USB3_INFO);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+ zassert_equal(mux_state, USB_PD_MUX_USB_ENABLED);
+
+ anx7452_emul_set_reg(EMUL, ANX7452_TOP_STATUS_REG,
+ ANX7452_TOP_REG_EN | ANX7452_TOP_USB4_INFO);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+ zassert_equal(mux_state, USB_PD_MUX_USB4_ENABLED);
+
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ ANX7452_TOP_STATUS_REG);
+ zassert_equal(EC_ERROR_INVAL,
+ anx7452_usb_retimer_driver.get(
+ usb_muxes[USBC_PORT_C1].mux, &mux_state));
+}
+
+ZTEST(anx7452, test_anx7452_set)
+{
+ mux_state_t mux_state = 0;
+ bool ack_required;
+
+ zassert_equal(EC_SUCCESS, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+ zassert_equal(ack_required, false);
+
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG0_REG), 0);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ USB_PD_MUX_POLARITY_INVERTED, &ack_required));
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG0_REG),
+ ANX7452_CTLTOP_CFG0_FLIP_EN);
+
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ USB_PD_MUX_USB_ENABLED, &ack_required));
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG0_REG),
+ ANX7452_CTLTOP_CFG0_USB3_EN);
+
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG1_REG), 0);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ USB_PD_MUX_DP_ENABLED, &ack_required));
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG1_REG),
+ ANX7452_CTLTOP_CFG1_DP_EN);
+
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG2_REG), 0);
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ USB_PD_MUX_USB4_ENABLED, &ack_required));
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG2_REG),
+ ANX7452_CTLTOP_CFG2_USB4_EN);
+
+ zassert_equal(EC_SUCCESS,
+ anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ USB_PD_MUX_TBT_COMPAT_ENABLED, &ack_required));
+ zassert_equal(anx7452_emul_get_reg(EMUL, ANX7452_CTLTOP_CFG2_REG),
+ ANX7452_CTLTOP_CFG2_TBT_EN);
+
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG0_REG);
+ zassert_equal(EC_ERROR_INVAL, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG1_REG);
+ zassert_equal(EC_ERROR_INVAL, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG2_REG);
+ zassert_equal(EC_ERROR_INVAL, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG0_REG);
+ zassert_equal(EC_ERROR_TIMEOUT, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG1_REG);
+ zassert_equal(EC_ERROR_TIMEOUT, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ ANX7452_CTLTOP_CFG2_REG);
+ zassert_equal(EC_ERROR_TIMEOUT, anx7452_usb_retimer_driver.set(
+ usb_muxes[USBC_PORT_C1].mux,
+ mux_state, &ack_required));
+}
+
+static inline void reset_anx7452_state(void)
+{
+ i2c_common_emul_set_write_func(COMMON_DATA(TOP_EMUL_PORT), NULL, NULL);
+ i2c_common_emul_set_read_func(COMMON_DATA(TOP_EMUL_PORT), NULL, NULL);
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(TOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ i2c_common_emul_set_write_func(COMMON_DATA(CTLTOP_EMUL_PORT), NULL,
+ NULL);
+ i2c_common_emul_set_read_func(COMMON_DATA(CTLTOP_EMUL_PORT), NULL,
+ NULL);
+ i2c_common_emul_set_write_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_read_fail_reg(COMMON_DATA(CTLTOP_EMUL_PORT),
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ anx7452_emul_reset(EMUL);
+}
+
+static void anx7452_before(void *state)
+{
+ ARG_UNUSED(state);
+ reset_anx7452_state();
+}
+
+static void anx7452_after(void *state)
+{
+ ARG_UNUSED(state);
+ reset_anx7452_state();
+}
+
+ZTEST_SUITE(anx7452, drivers_predicate_post_main, NULL, anx7452_before,
+ anx7452_after, NULL);
diff --git a/zephyr/test/drivers/anx7452/usbc.dts b/zephyr/test/drivers/anx7452/usbc.dts
new file mode 100644
index 0000000000..3441cf842f
--- /dev/null
+++ b/zephyr/test/drivers/anx7452/usbc.dts
@@ -0,0 +1,32 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <dt-bindings/usb_pd_tcpm.h>
+
+/ {
+ usbc {
+ port1@1 {
+ compatible = "named-usbc-port";
+ reg = <1>;
+ usb-mux-chain-1 {
+ compatible = "cros-ec,usb-mux-chain";
+ usb-muxes = <&usb_c1_anx7452_emul>;
+ };
+ };
+ };
+
+};
+&i2c3 {
+ status = "okay";
+
+ /delete-node/ bbretimer@42;
+
+ usb_c1_anx7452_emul: anx7452@10 {
+ compatible = "analogix,anx7452";
+ reg = <0x10>;
+ usb-en-pin = <&usb_c1_ls_en>;
+ dp-en-pin = <&usb_c1_rt_rst_odl>;
+ };
+};
diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml
index d4c6fc7e75..dbae8be1e2 100644
--- a/zephyr/test/drivers/testcase.yaml
+++ b/zephyr/test/drivers/testcase.yaml
@@ -462,3 +462,12 @@ tests:
- CONFIG_LINK_TEST_SUITE_HOST_COMMAND_MEMORY_DUMP=y
- CONFIG_PLATFORM_EC_HOST_COMMAND_MEMORY_DUMP=y
- CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y
+ drivers.anx7452:
+ extra_conf_files:
+ - prj.conf
+ - anx7452/prj.conf
+ extra_dtc_overlay_files:
+ - boards/native_posix.overlay
+ - anx7452/usbc.dts
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_ANX7452=y