/* Copyright 2019 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* Mock for the TCPC interface */ #include "common.h" #include "console.h" #include "memory.h" #include "mock/tcpc_mock.h" #include "test_util.h" #include "tests/enum_strings.h" #include "timer.h" #include "usb_pd_tcpm.h" #ifndef CONFIG_COMMON_RUNTIME #define cprints(format, args...) #endif #ifndef TEST_BUILD #error "Mocks should only be in the test build." #endif /* Public API for controlling/inspecting this mock */ struct mock_tcpc_ctrl mock_tcpc; void mock_tcpc_reset(void) { /* Reset all control values to 0. See also build assert below */ memset(&mock_tcpc, 0, sizeof(mock_tcpc)); /* Reset all last viewed variables to -1 to make them invalid */ memset(&mock_tcpc.last, 0xff, sizeof(mock_tcpc.last)); } BUILD_ASSERT(TYPEC_CC_VOLT_OPEN == 0, "Ensure Open is 0-value for memset"); static int mock_init(int port) { return EC_SUCCESS; } static int mock_release(int port) { return EC_SUCCESS; } static int mock_get_cc(int port, enum tcpc_cc_voltage_status *cc1, enum tcpc_cc_voltage_status *cc2) { *cc1 = mock_tcpc.cc1; *cc2 = mock_tcpc.cc2; return EC_SUCCESS; } static bool mock_check_vbus_level(int port, enum vbus_level level) { if (level == VBUS_PRESENT) return mock_tcpc.vbus_level; else if (level == VBUS_SAFE0V || level == VBUS_REMOVED) return !mock_tcpc.vbus_level; /* * Unknown vbus_level was added, force a failure. * Note that TCPC drivers and pd_check_vbus_level() implementations * should be carefully checked on new level additions in case they * need updated. */ ccprints("[TCPC] Unhandled Vbus check %d", level); TEST_ASSERT(0); } static int mock_select_rp_value(int port, int rp) { mock_tcpc.last.rp = rp; if (!mock_tcpc.should_print_call) return EC_SUCCESS; ccprints("[TCPC] Setting TCPM-side Rp to %s", from_tcpc_rp_value(rp)); return EC_SUCCESS; } static int mock_set_cc(int port, int pull) { mock_tcpc.last.cc = pull; if (mock_tcpc.callbacks.set_cc) mock_tcpc.callbacks.set_cc(port, pull); if (!mock_tcpc.should_print_call) return EC_SUCCESS; ccprints("[TCPC] Setting TCPM-side CC to %s", from_tcpc_cc_pull(pull)); return EC_SUCCESS; } static int mock_set_polarity(int port, enum tcpc_cc_polarity polarity) { mock_tcpc.last.polarity = polarity; if (!mock_tcpc.should_print_call) return EC_SUCCESS; ccprints("[TCPC] Setting TCPM-side polarity to %s", from_tcpc_cc_polarity(polarity)); return EC_SUCCESS; } static int mock_set_vconn(int port, int enable) { return EC_SUCCESS; } static int mock_set_msg_header(int port, int power_role, int data_role) { ++mock_tcpc.num_calls_to_set_header; mock_tcpc.last.power_role = power_role; mock_tcpc.last.data_role = data_role; if (!mock_tcpc.should_print_call) return EC_SUCCESS; ccprints("[TCPC] Setting TCPM-side header to %s %s", from_pd_power_role(power_role), from_pd_data_role(data_role)); return EC_SUCCESS; } static int mock_set_rx_enable(int port, int enable) { return EC_SUCCESS; } static int mock_get_message_raw(int port, uint32_t *payload, int *head) { return EC_SUCCESS; } static int mock_transmit(int port, enum tcpci_msg_type type, uint16_t header, const uint32_t *data) { return EC_SUCCESS; } void mock_tcpc_alert(int port) { } void mock_tcpc_discharge_vbus(int port, int enable) { } __maybe_unused static int mock_drp_toggle(int port) { /* Only set the time the first time this is called. */ if (mock_tcpc.first_call_to_enable_auto_toggle == 0) mock_tcpc.first_call_to_enable_auto_toggle = get_time().val; if (!mock_tcpc.should_print_call) return EC_SUCCESS; ccprints("[TCPC] Enabling Auto Toggle"); return EC_SUCCESS; } static int mock_get_chip_info(int port, int live, struct ec_response_pd_chip_info_v1 *info) { return EC_SUCCESS; } __maybe_unused static int mock_set_snk_ctrl(int port, int enable) { return EC_SUCCESS; } __maybe_unused static int mock_set_src_ctrl(int port, int enable) { return EC_SUCCESS; } __maybe_unused static int mock_enter_low_power_mode(int port) { return EC_SUCCESS; } int mock_set_frs_enable(int port, int enable) { return EC_SUCCESS; } const struct tcpm_drv mock_tcpc_driver = { .init = &mock_init, .release = &mock_release, .get_cc = &mock_get_cc, .check_vbus_level = &mock_check_vbus_level, .select_rp_value = &mock_select_rp_value, .set_cc = &mock_set_cc, .set_polarity = &mock_set_polarity, .set_vconn = &mock_set_vconn, .set_msg_header = &mock_set_msg_header, .set_rx_enable = &mock_set_rx_enable, .get_message_raw = &mock_get_message_raw, .transmit = &mock_transmit, .tcpc_alert = &mock_tcpc_alert, .tcpc_discharge_vbus = &mock_tcpc_discharge_vbus, #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE .drp_toggle = &mock_drp_toggle, #endif .get_chip_info = &mock_get_chip_info, #ifdef CONFIG_USB_PD_PPC .set_snk_ctrl = &mock_set_snk_ctrl, .set_src_ctrl = &mock_set_src_ctrl, #endif #ifdef CONFIG_USB_PD_TCPC_LOW_POWER .enter_low_power_mode = &mock_enter_low_power_mode, #endif #ifdef CONFIG_USB_PD_FRS_TCPC .set_frs_enable = &mock_set_frs_enable, #endif };