summaryrefslogtreecommitdiff
path: root/zephyr
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr')
-rw-r--r--zephyr/test/drivers/include/stubs.h7
-rw-r--r--zephyr/test/drivers/prj.conf3
-rw-r--r--zephyr/test/drivers/src/ps8xxx.c299
-rw-r--r--zephyr/test/drivers/src/stubs.c16
4 files changed, 317 insertions, 8 deletions
diff --git a/zephyr/test/drivers/include/stubs.h b/zephyr/test/drivers/include/stubs.h
index f942cd086a..3101b95e1e 100644
--- a/zephyr/test/drivers/include/stubs.h
+++ b/zephyr/test/drivers/include/stubs.h
@@ -11,3 +11,10 @@ enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT };
extern struct usb_mux usbc1_virtual_usb_mux;
void set_mock_power_state(enum power_state state);
+
+/**
+ * @brief Set product ID that should be returned by board_get_ps8xxx_product_id
+ *
+ * @param product_id ID of PS8xxx product which is emulated
+ */
+void board_set_ps8xxx_product_id(uint16_t product_id);
diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf
index cad89e716c..e5dceeec85 100644
--- a/zephyr/test/drivers/prj.conf
+++ b/zephyr/test/drivers/prj.conf
@@ -83,6 +83,9 @@ CONFIG_PLATFORM_EC_USBC_RETIMER_INTEL_BB=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_MUX=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8805=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8805_FORCE_DID=y
+CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8815=y
+CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8815_FORCE_DID=y
+CONFIG_PLATFORM_EC_USB_PD_TCPM_MULTI_PS8XXX=y
CONFIG_ESPI=y
CONFIG_ESPI_EMUL=y
diff --git a/zephyr/test/drivers/src/ps8xxx.c b/zephyr/test/drivers/src/ps8xxx.c
index 87be4f3357..24093f6c6e 100644
--- a/zephyr/test/drivers/src/ps8xxx.c
+++ b/zephyr/test/drivers/src/ps8xxx.c
@@ -92,6 +92,31 @@ static void test_ps8805_init(void)
PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK, NULL);
}
+/** Test PS8815 init */
+static void test_ps8815_init(void)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+ const struct emul *tcpci_emul = ps8xxx_emul_get_tcpci(ps8xxx_emul);
+ struct i2c_emul *p1_i2c_emul =
+ ps8xxx_emul_get_i2c_emul(ps8xxx_emul, PS8XXX_EMUL_PORT_1);
+
+ /* Set arbitrary FW reg value != 0 for this test */
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_FW_REV, 0x31);
+ /* Set correct power status for rest of the test */
+ tcpci_emul_set_reg(tcpci_emul, TCPC_REG_POWER_STATUS, 0x0);
+
+ /* Test fail on reading HW revision register */
+ i2c_common_emul_set_read_fail_reg(p1_i2c_emul,
+ PS8815_P1_REG_HW_REVISION);
+ zassert_equal(EC_ERROR_INVAL, ps8xxx_tcpm_drv.init(USBC_PORT_C1),
+ NULL);
+ i2c_common_emul_set_read_fail_reg(p1_i2c_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Test successful init */
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+}
+
/** Test PS8xxx release */
static void test_ps8xxx_release(void)
{
@@ -116,6 +141,119 @@ static void test_ps8xxx_release(void)
"release on FW reg read fail should wait for chip");
}
+/**
+ * Check if PS8815 set_cc write correct value to ROLE_CTRL register and if
+ * PS8815 specific workaround is applied to RP_DETECT_CONTROL.
+ */
+static void check_ps8815_set_cc(enum tcpc_rp_value rp, enum tcpc_cc_pull cc,
+ uint16_t rp_detect_ctrl, const char *test_case)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+ const struct emul *tcpci_emul = ps8xxx_emul_get_tcpci(ps8xxx_emul);
+ uint16_t reg_val, exp_role_ctrl;
+
+ /* Clear RP detect register to see if it is set after test */
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_RP_DETECT_CONTROL, 0);
+
+ exp_role_ctrl = TCPC_REG_ROLE_CTRL_SET(TYPEC_NO_DRP, rp, cc, cc);
+
+ zassert_equal(EC_SUCCESS,
+ ps8xxx_tcpm_drv.select_rp_value(USBC_PORT_C1, rp),
+ "Failed to set RP for case: %s", test_case);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.set_cc(USBC_PORT_C1, cc),
+ "Failed to set CC for case: %s", test_case);
+
+ zassert_ok(tcpci_emul_get_reg(tcpci_emul, TCPC_REG_ROLE_CTRL, &reg_val),
+ "Failed tcpci_emul_get_reg() for case: %s", test_case);
+ zassert_equal(exp_role_ctrl, reg_val,
+ "0x%x != (role_ctrl = 0x%x) for case: %s", exp_role_ctrl,
+ reg_val, test_case);
+ zassert_ok(tcpci_emul_get_reg(tcpci_emul, PS8XXX_REG_RP_DETECT_CONTROL,
+ &reg_val),
+ "Failed tcpci_emul_get_reg() for case: %s", test_case);
+ zassert_equal(rp_detect_ctrl, reg_val,
+ "0x%x != (rp detect = 0x%x) for case: %s", rp_detect_ctrl,
+ reg_val, test_case);
+}
+
+/** Test PS8815 set cc and device specific workarounds */
+static void test_ps8815_set_cc(void)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+ const struct emul *tcpci_emul = ps8xxx_emul_get_tcpci(ps8xxx_emul);
+
+ /* Set firmware version <= 0x10 to set "disable rp detect" workaround */
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_FW_REV, 0x8);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, RP_DETECT_DISABLE,
+ "fw rev 0x8 \"disable rp detect\" workaround");
+
+ /* First call to set_cc should disarm workaround */
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, 0,
+ "second call without workaround");
+
+ /* drp_toggle should rearm "disable rp detect" workaround */
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.drp_toggle(USBC_PORT_C1),
+ NULL);
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, RP_DETECT_DISABLE,
+ "drp_toggle rearm workaround");
+
+ /*
+ * Set firmware version <= 0x10 to set "disable rp detect" workaround
+ * again
+ */
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_FW_REV, 0xa);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+
+ /* CC RD shouldn't trigger "disable rp detect" workaround */
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RD, 0,
+ "CC RD not trigger workaround");
+
+ /*
+ * Set firmware version > 0x10 to unset "disable rp detect"
+ * workaround
+ */
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_FW_REV, 0x12);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+
+ /* Firmware > 0x10 shouldn't trigger "disable rp detect" workaround */
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, 0,
+ "fw rev > 0x10 not trigger workaround");
+
+ /*
+ * Set hw revision 0x0a00 to enable workaround for b/171430855 (delay
+ * 1 ms on role control reg update)
+ */
+ ps8xxx_emul_set_hw_rev(ps8xxx_emul, 0x0a00);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+
+ /*
+ * TODO(b/203858808): Find if it is possible to detect additional 1 ms
+ * delay
+ */
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, 0,
+ "delay on HW rev 0x0a00");
+
+ /*
+ * Set hw revision 0x0a01 to enable workaround for b/171430855 (delay
+ * 1 ms on role control reg update)
+ */
+ ps8xxx_emul_set_hw_rev(ps8xxx_emul, 0x0a01);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, 0,
+ "delay on HW rev 0x0a01");
+
+ /*
+ * Set other hw revision to disable workaround for b/171430855 (delay
+ * 1 ms on role control reg update)
+ */
+ ps8xxx_emul_set_hw_rev(ps8xxx_emul, 0x0a02);
+ zassert_equal(EC_SUCCESS, ps8xxx_tcpm_drv.init(USBC_PORT_C1), NULL);
+ check_ps8815_set_cc(TYPEC_RP_1A5, TYPEC_CC_RP, 0,
+ "no delay on other HW rev");
+}
+
/** Test PS8xxx set vconn */
static void test_ps8xxx_set_vconn(void)
{
@@ -366,6 +504,11 @@ static void test_ps8805_get_chip_info(void)
test_ps8xxx_get_chip_info(PS8805_PRODUCT_ID);
}
+static void test_ps8815_get_chip_info(void)
+{
+ test_ps8xxx_get_chip_info(PS8815_PRODUCT_ID);
+}
+
/** Test PS8805 get chip info and indirectly ps8805_make_device_id */
static void test_ps8805_get_chip_info_fix_dev_id(void)
{
@@ -453,6 +596,97 @@ static void test_ps8805_get_chip_info_fix_dev_id(void)
}
}
+/** Test PS8815 get chip info and indirectly ps8815_make_device_id */
+static void test_ps8815_get_chip_info_fix_dev_id(void)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+ const struct emul *tcpci_emul = ps8xxx_emul_get_tcpci(ps8xxx_emul);
+ struct i2c_emul *p1_i2c_emul =
+ ps8xxx_emul_get_i2c_emul(ps8xxx_emul, PS8XXX_EMUL_PORT_1);
+ struct ec_response_pd_chip_info_v1 info;
+ uint16_t vendor, product, device_id, fw_rev;
+ uint16_t hw_rev;
+
+ struct {
+ uint16_t exp_dev_id;
+ uint16_t hw_rev;
+ } test_param[] = {
+ /* Test A0 HW revision */
+ {
+ .exp_dev_id = 0x1,
+ .hw_rev = 0x0a00,
+ },
+ /* Test A1 HW revision */
+ {
+ .exp_dev_id = 0x2,
+ .hw_rev = 0x0a01,
+ },
+ /* Test A2 HW revision */
+ {
+ .exp_dev_id = 0x3,
+ .hw_rev = 0x0a02,
+ },
+ };
+
+ /* Setup chip info */
+ vendor = PS8XXX_VENDOR_ID;
+ product = PS8815_PRODUCT_ID;
+ /* Arbitrary revision */
+ fw_rev = 0x32;
+ tcpci_emul_set_reg(tcpci_emul, TCPC_REG_VENDOR_ID, vendor);
+ tcpci_emul_set_reg(tcpci_emul, TCPC_REG_PRODUCT_ID, product);
+ tcpci_emul_set_reg(tcpci_emul, PS8XXX_REG_FW_REV, fw_rev);
+
+ /* Set device id which requires fixing */
+ device_id = 0x1;
+ tcpci_emul_set_reg(tcpci_emul, TCPC_REG_BCD_DEV, device_id);
+
+ /* Test error on fixing device id because of fail hw revision read */
+ i2c_common_emul_set_read_fail_reg(p1_i2c_emul,
+ PS8815_P1_REG_HW_REVISION);
+ zassert_equal(EC_ERROR_INVAL,
+ ps8xxx_tcpm_drv.get_chip_info(USBC_PORT_C1, 1, &info),
+ NULL);
+ i2c_common_emul_set_read_fail_reg(p1_i2c_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Set wrong hw revision */
+ hw_rev = 0x32;
+ ps8xxx_emul_set_hw_rev(ps8xxx_emul, hw_rev);
+
+ /* Test error on fixing device id */
+ zassert_equal(EC_ERROR_UNKNOWN,
+ ps8xxx_tcpm_drv.get_chip_info(USBC_PORT_C1, 1, &info),
+ NULL);
+
+ /* Test fixing device id for specific HW revisions */
+ for (int i = 0; i < ARRAY_SIZE(test_param); i++) {
+ ps8xxx_emul_set_hw_rev(ps8xxx_emul, test_param[i].hw_rev);
+
+ /* Test correct device id after fixing */
+ zassert_equal(EC_SUCCESS,
+ ps8xxx_tcpm_drv.get_chip_info(USBC_PORT_C1, 1,
+ &info),
+ "Failed to get chip info in test case %d (hw_rev 0x%x)",
+ i, test_param[i].hw_rev);
+ zassert_equal(vendor, info.vendor_id,
+ "0x%x != (vendor = 0x%x) in test case %d (hw_rev 0x%x)",
+ vendor, info.vendor_id, i, test_param[i].hw_rev);
+ zassert_equal(product, info.product_id,
+ "0x%x != (product = 0x%x) in test case %d (hw_rev 0x%x)",
+ product, info.product_id,
+ i, test_param[i].hw_rev);
+ zassert_equal(test_param[i].exp_dev_id, info.device_id,
+ "0x%x != (device = 0x%x) in test case %d (hw_rev 0x%x)",
+ test_param[i].exp_dev_id, info.device_id,
+ i, test_param[i].hw_rev);
+ zassert_equal(fw_rev, info.fw_version_number,
+ "0x%x != (FW rev = 0x%x) in test case %d (hw_rev 0x%x)",
+ fw_rev, info.fw_version_number,
+ i, test_param[i].hw_rev);
+ }
+}
+
/** Test PS8805 get/set gpio */
static void test_ps8805_gpio(void)
{
@@ -613,28 +847,77 @@ static void setup_no_fail_all(void)
}
}
+/**
+ * Setup PS8xxx emulator to mimic PS8805 and setup no fail for all I2C devices
+ * associated with PS8xxx emulator
+ */
+static void setup_ps8805(void)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+
+ board_set_ps8xxx_product_id(PS8805_PRODUCT_ID);
+ ps8xxx_emul_set_product_id(ps8xxx_emul, PS8805_PRODUCT_ID);
+ setup_no_fail_all();
+}
+
+/**
+ * Setup PS8xxx emulator to mimic PS8815 and setup no fail for all I2C devices
+ * associated with PS8xxx emulator
+ */
+static void setup_ps8815(void)
+{
+ const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL);
+
+ board_set_ps8xxx_product_id(PS8815_PRODUCT_ID);
+ ps8xxx_emul_set_product_id(ps8xxx_emul, PS8815_PRODUCT_ID);
+ setup_no_fail_all();
+}
+
void test_suite_ps8xxx(void)
{
ztest_test_suite(ps8805,
ztest_unit_test_setup_teardown(test_ps8xxx_init_fail,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps8805_init,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps8xxx_release,
setup_no_fail_all, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps8xxx_set_vconn,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps8xxx_transmit,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps88x5_drp_toggle,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(
test_ps8805_get_chip_info,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(
test_ps8805_get_chip_info_fix_dev_id,
- setup_no_fail_all, unit_test_noop),
+ setup_ps8805, unit_test_noop),
ztest_unit_test_setup_teardown(test_ps8805_gpio,
- setup_no_fail_all, unit_test_noop));
+ setup_ps8805, unit_test_noop));
ztest_run_test_suite(ps8805);
+
+ ztest_test_suite(ps8815,
+ ztest_unit_test_setup_teardown(test_ps8xxx_init_fail,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps8815_init,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps8xxx_release,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps8815_set_cc,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps8xxx_set_vconn,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps8xxx_transmit,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(test_ps88x5_drp_toggle,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(
+ test_ps8815_get_chip_info,
+ setup_ps8815, unit_test_noop),
+ ztest_unit_test_setup_teardown(
+ test_ps8815_get_chip_info_fix_dev_id,
+ setup_ps8815, unit_test_noop));
+ ztest_run_test_suite(ps8815);
}
diff --git a/zephyr/test/drivers/src/stubs.c b/zephyr/test/drivers/src/stubs.c
index 9418207349..a8a478a86f 100644
--- a/zephyr/test/drivers/src/stubs.c
+++ b/zephyr/test/drivers/src/stubs.c
@@ -139,6 +139,22 @@ struct tcpc_config_t tcpc_config[] = {
BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT);
+static uint16_t ps8xxx_product_id = PS8805_PRODUCT_ID;
+
+uint16_t board_get_ps8xxx_product_id(int port)
+{
+ if (port != USBC_PORT_C1) {
+ return 0;
+ }
+
+ return ps8xxx_product_id;
+}
+
+void board_set_ps8xxx_product_id(uint16_t product_id)
+{
+ ps8xxx_product_id = product_id;
+}
+
int board_is_sourcing_vbus(int port)
{
return 0;