diff options
author | Madhurima Paruchuri <mparuchuri@google.com> | 2023-03-15 18:54:35 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-12 12:23:47 +0000 |
commit | ca4eb6b6aea1c24c01923bb38a67065960d15ad4 (patch) | |
tree | 8c813d15a194ad527b016a21e9e8cd0635e2c1da | |
parent | 48cde011ac52a82e5c34d8b50a17c1ae63deaa45 (diff) | |
download | chrome-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.txt | 1 | ||||
-rw-r--r-- | zephyr/emul/Kconfig | 11 | ||||
-rw-r--r-- | zephyr/emul/emul_anx7452.c | 262 | ||||
-rw-r--r-- | zephyr/include/emul/emul_anx7452.h | 81 | ||||
-rw-r--r-- | zephyr/test/drivers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/test/drivers/Kconfig | 6 | ||||
-rw-r--r-- | zephyr/test/drivers/anx7452/CMakeLists.txt | 6 | ||||
-rw-r--r-- | zephyr/test/drivers/anx7452/prj.conf | 3 | ||||
-rw-r--r-- | zephyr/test/drivers/anx7452/src/anx7452.c | 288 | ||||
-rw-r--r-- | zephyr/test/drivers/anx7452/usbc.dts | 32 | ||||
-rw-r--r-- | zephyr/test/drivers/testcase.yaml | 9 |
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 |