summaryrefslogtreecommitdiff
path: root/common/mock/tcpc_mock.c
blob: 7097837268143f8e687753436665251d98adebe7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* 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
};