History

Merge tag 'tag-chrome-platform-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Tzung-Bi Shih: "cros_ec_proto: - Leverage Kunit and add Kunit test cases - Clean-ups - Fix typo cros_ec_commands: - Fix typo - Fix compile errors cros_kbd_led_backlight: - Support OF match - Support EC PWM backend cros_ec: - Always expose the last resume result to fix sleep hang detection on ARM-based chromebooks wilco_ec: - Fix typo cros_ec_typec: - Clean-ups - Use Type-C framework utilities to manage altmode structs" * tag 'tag-chrome-platform-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: (59 commits) platform/chrome: cros_kunit_util: add default value for `msg->result` platform/chrome: merge Kunit utils and test cases platform/chrome: cros_kbd_led_backlight: fix build warning platform/chrome: cros_ec_proto: add Kunit test for cros_ec_cmd() platform/chrome: cros_ec_proto: add Kunit tests for get_sensor_count platform/chrome: cros_ec_proto: add Kunit tests for check_features platform/chrome: cros_ec_proto: add Kunit tests for get_host_event platform/chrome: cros_ec_proto: add Kunit tests for get_next_event platform/chrome: cros_ec_proto: add Kunit test for cros_ec_map_error() platform/chrome: cros_ec_proto: add Kunit tests for cmd_xfer_status platform/chrome: cros_ec_proto: return -EPROTO if empty payload platform/chrome: cros_ec_proto: add Kunit test for empty payload platform/chrome: cros_ec_proto: return -EAGAIN when retries timed out platform/chrome: cros_ec_proto: change Kunit expectation when timed out platform/chrome: cros_ec_proto: separate cros_ec_wait_until_complete() platform/chrome: cros_ec_proto: separate cros_ec_xfer_command() platform/chrome: cros_ec_proto: add Kunit tests for cros_ec_send_command() platform/chrome: cros_ec_proto: add Kunit tests for cros_ec_cmd_xfer() platform/chrome: cros_ec_proto: add "cros_ec_" prefix to send_command() platform/chrome: cros_ec_typec: Register port altmodes ...

Linus Torvalds committed 4 years ago

Commit 5bb3bf22 parents da8d07a afef1e118 files · +3490 −335Browse files

Unified · Split

18 files
  1. Documentation/devicetree/bindings/chrome/google,cros-kbd-led-backlight.yaml +35 −0
  2. Documentation/devicetree/bindings/mfd/google,cros-ec.yaml +3 −0
  3. drivers/mfd/cros_ec_dev.c +2 −2
  4. drivers/platform/chrome/Kconfig +10 −1
  5. drivers/platform/chrome/Makefile +5 −0
  6. drivers/platform/chrome/cros_ec.c +4 −7
  7. drivers/platform/chrome/cros_ec_proto.c +248 −225
  8. drivers/platform/chrome/cros_ec_proto_test.c +2753 −0
  9. drivers/platform/chrome/cros_ec_trace.h +4 −4
  10. drivers/platform/chrome/cros_ec_typec.c +60 −33
  11. drivers/platform/chrome/cros_kbd_led_backlight.c +174 −22
  12. drivers/platform/chrome/cros_kunit_util.c +130 −0
  13. drivers/platform/chrome/cros_kunit_util.h +48 −0
  14. drivers/platform/chrome/cros_usbpd_notify.c +2 −2
  15. drivers/platform/chrome/wilco_ec/event.c +1 −1
  16. drivers/regulator/cros-ec-regulator.c +3 −33
  17. include/linux/platform_data/cros_ec_commands.h +3 −3
  18. include/linux/platform_data/cros_ec_proto.h +5 −2
Documentation/devicetree/bindings/chrome/google,cros-kbd-led-backlight.yaml+35−0
@@ -0,0 +1,35 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/chrome/google,cros-kbd-led-backlight.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: ChromeOS keyboard backlight LED driver.
8
9maintainers:
10 - Tzung-Bi Shih <tzungbi@kernel.org>
11
12properties:
13 compatible:
14 const: google,cros-kbd-led-backlight
15
16required:
17 - compatible
18
19additionalProperties: false
20
21examples:
22 - |
23 spi0 {
24 #address-cells = <1>;
25 #size-cells = <0>;
26
27 cros_ec: ec@0 {
28 compatible = "google,cros-ec-spi";
29 reg = <0>;
30
31 kbd-led-backlight {
32 compatible = "google,cros-kbd-led-backlight";
33 };
34 };
35 };
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml+3−0
@@ -90,6 +90,9 @@ properties: · 89 unmodified lines
90 pwm:90 pwm:
91 $ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"91 $ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
92 92
93 kbd-led-backlight:
94 $ref: "/schemas/chrome/google,cros-kbd-led-backlight.yaml#"
95
93 keyboard-controller:96 keyboard-controller:
94 $ref: "/schemas/input/google,cros-ec-keyb.yaml#"97 $ref: "/schemas/input/google,cros-ec-keyb.yaml#"
95 98
drivers/mfd/cros_ec_dev.c+2−2
@@ -250,8 +250,8 @@ static int ec_device_probe(struct platform_device *pdev) · 249 unmodified lines
250 * The PCHG device cannot be detected by sending EC_FEATURE_GET_CMD, but250 * The PCHG device cannot be detected by sending EC_FEATURE_GET_CMD, but
251 * it can be detected by querying the number of peripheral chargers.251 * it can be detected by querying the number of peripheral chargers.
252 */252 */
253 retval = cros_ec_command(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,253 retval = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
254 &pchg_count, sizeof(pchg_count));254 &pchg_count, sizeof(pchg_count));
255 if (retval >= 0 && pchg_count.port_count) {255 if (retval >= 0 && pchg_count.port_count) {
256 retval = mfd_add_hotplug_devices(ec->dev,256 retval = mfd_add_hotplug_devices(ec->dev,
257 cros_ec_pchg_cells,257 cros_ec_pchg_cells,
drivers/platform/chrome/Kconfig+10−1
@@ -139,7 +139,7 @@ config CROS_EC_PROTO · 138 unmodified lines
139 139
140config CROS_KBD_LED_BACKLIGHT140config CROS_KBD_LED_BACKLIGHT
141 tristate "Backlight LED support for Chrome OS keyboards"141 tristate "Backlight LED support for Chrome OS keyboards"
142 depends on LEDS_CLASS && ACPI142 depends on LEDS_CLASS && (ACPI || CROS_EC)
143 help143 help
144 This option enables support for the keyboard backlight LEDs on144 This option enables support for the keyboard backlight LEDs on
145 select Chrome OS systems.145 select Chrome OS systems.
@@ -267,4 +267,13 @@ config CHROMEOS_PRIVACY_SCREEN · 121 unmodified lines
267 267
268source "drivers/platform/chrome/wilco_ec/Kconfig"268source "drivers/platform/chrome/wilco_ec/Kconfig"
269 269
270# Kunit test cases
271config CROS_KUNIT
272 tristate "Kunit tests for ChromeOS" if !KUNIT_ALL_TESTS
273 depends on KUNIT && CROS_EC
274 default KUNIT_ALL_TESTS
275 select CROS_EC_PROTO
276 help
277 ChromeOS Kunit tests.
278
270endif # CHROMEOS_PLATFORMS279endif # CHROMEOS_PLATFORMS
drivers/platform/chrome/Makefile+5−0
@@ -30,3 +30,8 @@ obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o · 29 unmodified lines
30obj-$(CONFIG_CROS_USBPD_NOTIFY) += cros_usbpd_notify.o30obj-$(CONFIG_CROS_USBPD_NOTIFY) += cros_usbpd_notify.o
31 31
32obj-$(CONFIG_WILCO_EC) += wilco_ec/32obj-$(CONFIG_WILCO_EC) += wilco_ec/
33
34# Kunit test cases
35obj-$(CONFIG_CROS_KUNIT) += cros_kunit.o
36cros_kunit-objs := cros_kunit_util.o
37cros_kunit-objs += cros_ec_proto_test.o
drivers/platform/chrome/cros_ec.c+4−7
@@ -19,9 +19,6 @@ · 18 unmodified lines
19 19
20#include "cros_ec.h"20#include "cros_ec.h"
21 21
22#define CROS_EC_DEV_EC_INDEX 0
23#define CROS_EC_DEV_PD_INDEX 1
24
25static struct cros_ec_platform ec_p = {22static struct cros_ec_platform ec_p = {
26 .ec_name = CROS_EC_DEV_NAME,23 .ec_name = CROS_EC_DEV_NAME,
27 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_EC_INDEX),24 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_EC_INDEX),
@@ -135,16 +132,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) · 107 unmodified lines
135 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;132 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
136 133
137 ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);134 ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);
138 135 /* Report failure to transition to system wide suspend with a warning. */
139 /* For now, report failure to transition to S0ix with a warning. */
140 if (ret >= 0 && ec_dev->host_sleep_v1 &&136 if (ret >= 0 && ec_dev->host_sleep_v1 &&
141 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) {137 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME ||
138 sleep_event == HOST_SLEEP_EVENT_S3_RESUME)) {
142 ec_dev->last_resume_result =139 ec_dev->last_resume_result =
143 buf.u.resp1.resume_response.sleep_transitions;140 buf.u.resp1.resume_response.sleep_transitions;
144 141
145 WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &142 WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
146 EC_HOST_RESUME_SLEEP_TIMEOUT,143 EC_HOST_RESUME_SLEEP_TIMEOUT,
147 "EC detected sleep transition timeout. Total slp_s0 transitions: %d",144 "EC detected sleep transition timeout. Total sleep transitions: %d",
148 buf.u.resp1.resume_response.sleep_transitions &145 buf.u.resp1.resume_response.sleep_transitions &
149 EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);146 EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
150 }147 }
drivers/platform/chrome/cros_ec_proto.c+248−225
@@ -52,8 +52,8 @@ static int cros_ec_map_error(uint32_t result) · 51 unmodified lines
52 return ret;52 return ret;
53}53}
54 54
55static int prepare_packet(struct cros_ec_device *ec_dev,55static int prepare_tx(struct cros_ec_device *ec_dev,
56 struct cros_ec_command *msg)56 struct cros_ec_command *msg)
57{57{
58 struct ec_host_request *request;58 struct ec_host_request *request;
59 u8 *out;59 u8 *out;
@@ -85,8 +85,29 @@ static int prepare_packet(struct cros_ec_device *ec_dev, · 25 unmodified lines
85 return sizeof(*request) + msg->outsize;85 return sizeof(*request) + msg->outsize;
86}86}
87 87
88static int send_command(struct cros_ec_device *ec_dev,88static int prepare_tx_legacy(struct cros_ec_device *ec_dev,
89 struct cros_ec_command *msg)89 struct cros_ec_command *msg)
90{
91 u8 *out;
92 u8 csum;
93 int i;
94
95 if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
96 return -EINVAL;
97
98 out = ec_dev->dout;
99 out[0] = EC_CMD_VERSION0 + msg->version;
100 out[1] = msg->command;
101 out[2] = msg->outsize;
102 csum = out[0] + out[1] + out[2];
103 for (i = 0; i < msg->outsize; i++)
104 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
105 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
106
107 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
108}
109
110static int cros_ec_xfer_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
90{111{
91 int ret;112 int ret;
92 int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);113 int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
@@ -102,57 +123,68 @@ static int send_command(struct cros_ec_device *ec_dev, · 9 unmodified lines
102 * the EC is trying to use protocol v2, on an underlying123 * the EC is trying to use protocol v2, on an underlying
103 * communication mechanism that does not support v2.124 * communication mechanism that does not support v2.
104 */125 */
105 dev_err_once(ec_dev->dev,126 dev_err_once(ec_dev->dev, "missing EC transfer API, cannot send command\n");
106 "missing EC transfer API, cannot send command\n");
107 return -EIO;127 return -EIO;
108 }128 }
109 129
110 trace_cros_ec_request_start(msg);130 trace_cros_ec_request_start(msg);
111 ret = (*xfer_fxn)(ec_dev, msg);131 ret = (*xfer_fxn)(ec_dev, msg);
112 trace_cros_ec_request_done(msg, ret);132 trace_cros_ec_request_done(msg, ret);
113 if (msg->result == EC_RES_IN_PROGRESS) {
114 int i;
115 struct cros_ec_command *status_msg;
116 struct ec_response_get_comms_status *status;
117 133
118 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),134 return ret;
119 GFP_KERNEL);135}
120 if (!status_msg)
121 return -ENOMEM;
122 136
123 status_msg->version = 0;137static int cros_ec_wait_until_complete(struct cros_ec_device *ec_dev, uint32_t *result)
124 status_msg->command = EC_CMD_GET_COMMS_STATUS;138{
125 status_msg->insize = sizeof(*status);139 struct {
126 status_msg->outsize = 0;140 struct cros_ec_command msg;
141 struct ec_response_get_comms_status status;
142 } __packed buf;
143 struct cros_ec_command *msg = &buf.msg;
144 struct ec_response_get_comms_status *status = &buf.status;
145 int ret = 0, i;
127 146
128 /*147 msg->version = 0;
129 * Query the EC's status until it's no longer busy or148 msg->command = EC_CMD_GET_COMMS_STATUS;
130 * we encounter an error.149 msg->insize = sizeof(*status);
131 */150 msg->outsize = 0;
132 for (i = 0; i < EC_COMMAND_RETRIES; i++) {151
133 usleep_range(10000, 11000);152 /* Query the EC's status until it's no longer busy or we encounter an error. */
134 153 for (i = 0; i < EC_COMMAND_RETRIES; ++i) {
135 trace_cros_ec_request_start(status_msg);154 usleep_range(10000, 11000);
136 ret = (*xfer_fxn)(ec_dev, status_msg);155
137 trace_cros_ec_request_done(status_msg, ret);156 ret = cros_ec_xfer_command(ec_dev, msg);
138 if (ret == -EAGAIN)157 if (ret == -EAGAIN)
139 continue;158 continue;
140 if (ret < 0)159 if (ret < 0)
141 break;160 return ret;
142 161
143 msg->result = status_msg->result;162 *result = msg->result;
144 if (status_msg->result != EC_RES_SUCCESS)163 if (msg->result != EC_RES_SUCCESS)
145 break;164 return ret;
146 165
147 status = (struct ec_response_get_comms_status *)166 if (ret == 0) {
148 status_msg->data;167 ret = -EPROTO;
149 if (!(status->flags & EC_COMMS_STATUS_PROCESSING))168 break;
150 break;
151 }169 }
152 170
153 kfree(status_msg);171 if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
172 return ret;
154 }173 }
155 174
175 if (i >= EC_COMMAND_RETRIES)
176 ret = -EAGAIN;
177
178 return ret;
179}
180
181static int cros_ec_send_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
182{
183 int ret = cros_ec_xfer_command(ec_dev, msg);
184
185 if (msg->result == EC_RES_IN_PROGRESS)
186 ret = cros_ec_wait_until_complete(ec_dev, &msg->result);
187
156 return ret;188 return ret;
157}189}
158 190
@@ -161,35 +193,18 @@ static int send_command(struct cros_ec_device *ec_dev, · 2 unmodified lines
161 * @ec_dev: Device to register.193 * @ec_dev: Device to register.
162 * @msg: Message to write.194 * @msg: Message to write.
163 *195 *
164 * This is intended to be used by all ChromeOS EC drivers, but at present196 * This is used by all ChromeOS EC drivers to prepare the outgoing message
165 * only SPI uses it. Once LPC uses the same protocol it can start using it.197 * according to different protocol versions.
166 * I2C could use it now, with a refactor of the existing code.
167 *198 *
168 * Return: number of prepared bytes on success or negative error code.199 * Return: number of prepared bytes on success or negative error code.
169 */200 */
170int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,201int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
171 struct cros_ec_command *msg)202 struct cros_ec_command *msg)
172{203{
173 u8 *out;
174 u8 csum;
175 int i;
176
177 if (ec_dev->proto_version > 2)204 if (ec_dev->proto_version > 2)
178 return prepare_packet(ec_dev, msg);205 return prepare_tx(ec_dev, msg);
179
180 if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
181 return -EINVAL;
182 206
183 out = ec_dev->dout;207 return prepare_tx_legacy(ec_dev, msg);
184 out[0] = EC_CMD_VERSION0 + msg->version;
185 out[1] = msg->command;
186 out[2] = msg->outsize;
187 csum = out[0] + out[1] + out[2];
188 for (i = 0; i < msg->outsize; i++)
189 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
190 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
191
192 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
193}208}
194EXPORT_SYMBOL(cros_ec_prepare_tx);209EXPORT_SYMBOL(cros_ec_prepare_tx);
195 210
@@ -199,9 +214,12 @@ EXPORT_SYMBOL(cros_ec_prepare_tx); · 3 unmodified lines
199 * @msg: Message to check.214 * @msg: Message to check.
200 *215 *
201 * This is used by ChromeOS EC drivers to check the ec_msg->result for216 * This is used by ChromeOS EC drivers to check the ec_msg->result for
202 * errors and to warn about them.217 * EC_RES_IN_PROGRESS and to warn about them.
203 *218 *
204 * Return: 0 on success or negative error code.219 * The function should not check for furthermore error codes. Otherwise,
220 * it would break the ABI.
221 *
222 * Return: -EAGAIN if ec_msg->result == EC_RES_IN_PROGRESS. Otherwise, 0.
205 */223 */
206int cros_ec_check_result(struct cros_ec_device *ec_dev,224int cros_ec_check_result(struct cros_ec_device *ec_dev,
207 struct cros_ec_command *msg)225 struct cros_ec_command *msg)
@@ -228,59 +246,66 @@ EXPORT_SYMBOL(cros_ec_check_result); · 20 unmodified lines
228 *246 *
229 * @ec_dev: EC device to call247 * @ec_dev: EC device to call
230 * @msg: message structure to use248 * @msg: message structure to use
231 * @mask: result when function returns >=0.249 * @mask: result when function returns 0.
232 *250 *
233 * LOCKING:251 * LOCKING:
234 * the caller has ec_dev->lock mutex, or the caller knows there is252 * the caller has ec_dev->lock mutex, or the caller knows there is
235 * no other command in progress.253 * no other command in progress.
236 */254 */
237static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,255static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev, uint32_t *mask)
238 struct cros_ec_command *msg,
239 uint32_t *mask)
240{256{
257 struct cros_ec_command *msg;
241 struct ec_response_host_event_mask *r;258 struct ec_response_host_event_mask *r;
242 int ret;259 int ret, mapped;
260
261 msg = kzalloc(sizeof(*msg) + sizeof(*r), GFP_KERNEL);
262 if (!msg)
263 return -ENOMEM;
243 264
244 msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;265 msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
245 msg->version = 0;
246 msg->outsize = 0;
247 msg->insize = sizeof(*r);266 msg->insize = sizeof(*r);
248 267
249 ret = send_command(ec_dev, msg);268 ret = cros_ec_send_command(ec_dev, msg);
250 if (ret >= 0) {269 if (ret < 0)
251 if (msg->result == EC_RES_INVALID_COMMAND)270 goto exit;
252 return -EOPNOTSUPP;271
253 if (msg->result != EC_RES_SUCCESS)272 mapped = cros_ec_map_error(msg->result);
254 return -EPROTO;273 if (mapped) {
274 ret = mapped;
275 goto exit;
255 }276 }
256 if (ret > 0) {277
257 r = (struct ec_response_host_event_mask *)msg->data;278 if (ret == 0) {
258 *mask = r->mask;279 ret = -EPROTO;
280 goto exit;
259 }281 }
260 282
283 r = (struct ec_response_host_event_mask *)msg->data;
284 *mask = r->mask;
285 ret = 0;
286exit:
287 kfree(msg);
261 return ret;288 return ret;
262}289}
263 290
264static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,291static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx)
265 int devidx,
266 struct cros_ec_command *msg)
267{292{
268 /*293 struct cros_ec_command *msg;
269 * Try using v3+ to query for supported protocols. If this294 struct ec_response_get_protocol_info *info;
270 * command fails, fall back to v2. Returns the highest protocol295 int ret, mapped;
271 * supported by the EC.
272 * Also sets the max request/response/passthru size.
273 */
274 int ret;
275 296
276 if (!ec_dev->pkt_xfer)297 ec_dev->proto_version = 3;
277 return -EPROTONOSUPPORT;298 if (devidx > 0)
299 ec_dev->max_passthru = 0;
300
301 msg = kzalloc(sizeof(*msg) + sizeof(*info), GFP_KERNEL);
302 if (!msg)
303 return -ENOMEM;
278 304
279 memset(msg, 0, sizeof(*msg));
280 msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;305 msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
281 msg->insize = sizeof(struct ec_response_get_protocol_info);306 msg->insize = sizeof(*info);
282 307
283 ret = send_command(ec_dev, msg);308 ret = cros_ec_send_command(ec_dev, msg);
284 /*309 /*
285 * Send command once again when timeout occurred.310 * Send command once again when timeout occurred.
286 * Fingerprint MCU (FPMCU) is restarted during system boot which311 * Fingerprint MCU (FPMCU) is restarted during system boot which
@@ -289,68 +314,115 @@ static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev, · 2 unmodified lines
289 * attempt because we waited at least EC_MSG_DEADLINE_MS.314 * attempt because we waited at least EC_MSG_DEADLINE_MS.
290 */315 */
291 if (ret == -ETIMEDOUT)316 if (ret == -ETIMEDOUT)
292 ret = send_command(ec_dev, msg);317 ret = cros_ec_send_command(ec_dev, msg);
293 318
294 if (ret < 0) {319 if (ret < 0) {
295 dev_dbg(ec_dev->dev,320 dev_dbg(ec_dev->dev,
296 "failed to check for EC[%d] protocol version: %d\n",321 "failed to check for EC[%d] protocol version: %d\n",
297 devidx, ret);322 devidx, ret);
298 return ret;323 goto exit;
299 }324 }
300 325
301 if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)326 mapped = cros_ec_map_error(msg->result);
302 return -ENODEV;327 if (mapped) {
303 else if (msg->result != EC_RES_SUCCESS)328 ret = mapped;
304 return msg->result;329 goto exit;
330 }
305 331
306 return 0;332 if (ret == 0) {
333 ret = -EPROTO;
334 goto exit;
335 }
336
337 info = (struct ec_response_get_protocol_info *)msg->data;
338
339 switch (devidx) {
340 case CROS_EC_DEV_EC_INDEX:
341 ec_dev->max_request = info->max_request_packet_size -
342 sizeof(struct ec_host_request);
343 ec_dev->max_response = info->max_response_packet_size -
344 sizeof(struct ec_host_response);
345 ec_dev->proto_version = min(EC_HOST_REQUEST_VERSION,
346 fls(info->protocol_versions) - 1);
347 ec_dev->din_size = info->max_response_packet_size + EC_MAX_RESPONSE_OVERHEAD;
348 ec_dev->dout_size = info->max_request_packet_size + EC_MAX_REQUEST_OVERHEAD;
349
350 dev_dbg(ec_dev->dev, "using proto v%u\n", ec_dev->proto_version);
351 break;
352 case CROS_EC_DEV_PD_INDEX:
353 ec_dev->max_passthru = info->max_request_packet_size -
354 sizeof(struct ec_host_request);
355
356 dev_dbg(ec_dev->dev, "found PD chip\n");
357 break;
358 default:
359 dev_dbg(ec_dev->dev, "unknown passthru index: %d\n", devidx);
360 break;
361 }
362
363 ret = 0;
364exit:
365 kfree(msg);
366 return ret;
307}367}
308 368
309static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)369static int cros_ec_get_proto_info_legacy(struct cros_ec_device *ec_dev)
310{370{
311 struct cros_ec_command *msg;371 struct cros_ec_command *msg;
312 struct ec_params_hello *hello_params;372 struct ec_params_hello *params;
313 struct ec_response_hello *hello_response;373 struct ec_response_hello *response;
314 int ret;374 int ret, mapped;
315 int len = max(sizeof(*hello_params), sizeof(*hello_response));375
376 ec_dev->proto_version = 2;
316 377
317 msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);378 msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*response)), GFP_KERNEL);
318 if (!msg)379 if (!msg)
319 return -ENOMEM;380 return -ENOMEM;
320 381
321 msg->version = 0;
322 msg->command = EC_CMD_HELLO;382 msg->command = EC_CMD_HELLO;
323 hello_params = (struct ec_params_hello *)msg->data;383 msg->insize = sizeof(*response);
324 msg->outsize = sizeof(*hello_params);384 msg->outsize = sizeof(*params);
325 hello_response = (struct ec_response_hello *)msg->data;
326 msg->insize = sizeof(*hello_response);
327
328 hello_params->in_data = 0xa0b0c0d0;
329 385
330 ret = send_command(ec_dev, msg);386 params = (struct ec_params_hello *)msg->data;
387 params->in_data = 0xa0b0c0d0;
331 388
389 ret = cros_ec_send_command(ec_dev, msg);
332 if (ret < 0) {390 if (ret < 0) {
333 dev_dbg(ec_dev->dev,391 dev_dbg(ec_dev->dev, "EC failed to respond to v2 hello: %d\n", ret);
334 "EC failed to respond to v2 hello: %d\n",
335 ret);
336 goto exit;392 goto exit;
337 } else if (msg->result != EC_RES_SUCCESS) {393 }
338 dev_err(ec_dev->dev,394
339 "EC responded to v2 hello with error: %d\n",395 mapped = cros_ec_map_error(msg->result);
340 msg->result);396 if (mapped) {
341 ret = msg->result;397 ret = mapped;
398 dev_err(ec_dev->dev, "EC responded to v2 hello with error: %d\n", msg->result);
399 goto exit;
400 }
401
402 if (ret == 0) {
403 ret = -EPROTO;
342 goto exit;404 goto exit;
343 } else if (hello_response->out_data != 0xa1b2c3d4) {405 }
406
407 response = (struct ec_response_hello *)msg->data;
408 if (response->out_data != 0xa1b2c3d4) {
344 dev_err(ec_dev->dev,409 dev_err(ec_dev->dev,
345 "EC responded to v2 hello with bad result: %u\n",410 "EC responded to v2 hello with bad result: %u\n",
346 hello_response->out_data);411 response->out_data);
347 ret = -EBADMSG;412 ret = -EBADMSG;
348 goto exit;413 goto exit;
349 }414 }
350 415
351 ret = 0;416 ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
417 ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
418 ec_dev->max_passthru = 0;
419 ec_dev->pkt_xfer = NULL;
420 ec_dev->din_size = EC_PROTO2_MSG_BYTES;
421 ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
352 422
353 exit:423 dev_dbg(ec_dev->dev, "falling back to proto v2\n");
424 ret = 0;
425exit:
354 kfree(msg);426 kfree(msg);
355 return ret;427 return ret;
356}428}
@@ -371,13 +443,12 @@ static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev) · 14 unmodified lines
371 * the caller has ec_dev->lock mutex or the caller knows there is443 * the caller has ec_dev->lock mutex or the caller knows there is
372 * no other command in progress.444 * no other command in progress.
373 */445 */
374static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,446static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, u16 cmd, u32 *mask)
375 u16 cmd, u32 *mask)
376{447{
377 struct ec_params_get_cmd_versions *pver;448 struct ec_params_get_cmd_versions *pver;
378 struct ec_response_get_cmd_versions *rver;449 struct ec_response_get_cmd_versions *rver;
379 struct cros_ec_command *msg;450 struct cros_ec_command *msg;
380 int ret;451 int ret, mapped;
381 452
382 msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),453 msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
383 GFP_KERNEL);454 GFP_KERNEL);
@@ -392,14 +463,26 @@ static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, · 8 unmodified lines
392 pver = (struct ec_params_get_cmd_versions *)msg->data;463 pver = (struct ec_params_get_cmd_versions *)msg->data;
393 pver->cmd = cmd;464 pver->cmd = cmd;
394 465
395 ret = send_command(ec_dev, msg);466 ret = cros_ec_send_command(ec_dev, msg);
396 if (ret > 0) {467 if (ret < 0)
397 rver = (struct ec_response_get_cmd_versions *)msg->data;468 goto exit;
398 *mask = rver->version_mask;469
470 mapped = cros_ec_map_error(msg->result);
471 if (mapped) {
472 ret = mapped;
473 goto exit;
399 }474 }
400 475
401 kfree(msg);476 if (ret == 0) {
477 ret = -EPROTO;
478 goto exit;
479 }
402 480
481 rver = (struct ec_response_get_cmd_versions *)msg->data;
482 *mask = rver->version_mask;
483 ret = 0;
484exit:
485 kfree(msg);
403 return ret;486 return ret;
404}487}
405 488
@@ -413,71 +496,17 @@ static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, · 7 unmodified lines
413int cros_ec_query_all(struct cros_ec_device *ec_dev)496int cros_ec_query_all(struct cros_ec_device *ec_dev)
414{497{
415 struct device *dev = ec_dev->dev;498 struct device *dev = ec_dev->dev;
416 struct cros_ec_command *proto_msg;499 u32 ver_mask;
417 struct ec_response_get_protocol_info *proto_info;
418 u32 ver_mask = 0;
419 int ret;500 int ret;
420 501
421 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
422 GFP_KERNEL);
423 if (!proto_msg)
424 return -ENOMEM;
425
426 /* First try sending with proto v3. */502 /* First try sending with proto v3. */
427 ec_dev->proto_version = 3;503 if (!cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_EC_INDEX)) {
428 ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);504 /* Check for PD. */
429 505 cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_PD_INDEX);
430 if (ret == 0) {
431 proto_info = (struct ec_response_get_protocol_info *)
432 proto_msg->data;
433 ec_dev->max_request = proto_info->max_request_packet_size -
434 sizeof(struct ec_host_request);
435 ec_dev->max_response = proto_info->max_response_packet_size -
436 sizeof(struct ec_host_response);
437 ec_dev->proto_version =
438 min(EC_HOST_REQUEST_VERSION,
439 fls(proto_info->protocol_versions) - 1);
440 dev_dbg(ec_dev->dev,
441 "using proto v%u\n",
442 ec_dev->proto_version);
443
444 ec_dev->din_size = ec_dev->max_response +
445 sizeof(struct ec_host_response) +
446 EC_MAX_RESPONSE_OVERHEAD;
447 ec_dev->dout_size = ec_dev->max_request +
448 sizeof(struct ec_host_request) +
449 EC_MAX_REQUEST_OVERHEAD;
450
451 /*
452 * Check for PD
453 */
454 ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
455
456 if (ret) {
457 dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
458 ec_dev->max_passthru = 0;
459 } else {
460 dev_dbg(ec_dev->dev, "found PD chip\n");
461 ec_dev->max_passthru =
462 proto_info->max_request_packet_size -
463 sizeof(struct ec_host_request);
464 }
465 } else {506 } else {
466 /* Try querying with a v2 hello message. */507 /* Try querying with a v2 hello message. */
467 ec_dev->proto_version = 2;508 ret = cros_ec_get_proto_info_legacy(ec_dev);
468 ret = cros_ec_host_command_proto_query_v2(ec_dev);509 if (ret) {
469
470 if (ret == 0) {
471 /* V2 hello succeeded. */
472 dev_dbg(ec_dev->dev, "falling back to proto v2\n");
473
474 ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
475 ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
476 ec_dev->max_passthru = 0;
477 ec_dev->pkt_xfer = NULL;
478 ec_dev->din_size = EC_PROTO2_MSG_BYTES;
479 ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
480 } else {
481 /*510 /*
482 * It's possible for a test to occur too early when511 * It's possible for a test to occur too early when
483 * the EC isn't listening. If this happens, we'll512 * the EC isn't listening. If this happens, we'll
@@ -485,7 +514,7 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 1 unmodified line
485 */514 */
486 ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;515 ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
487 dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);516 dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
488 goto exit;517 return ret;
489 }518 }
490 }519 }
491 520
@@ -506,26 +535,21 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 14 unmodified lines
506 }535 }
507 536
508 /* Probe if MKBP event is supported */537 /* Probe if MKBP event is supported */
509 ret = cros_ec_get_host_command_version_mask(ec_dev,538 ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_GET_NEXT_EVENT, &ver_mask);
510 EC_CMD_GET_NEXT_EVENT,539 if (ret < 0 || ver_mask == 0) {
511 &ver_mask);
512 if (ret < 0 || ver_mask == 0)
513 ec_dev->mkbp_event_supported = 0;540 ec_dev->mkbp_event_supported = 0;
514 else541 } else {
515 ec_dev->mkbp_event_supported = fls(ver_mask);542 ec_dev->mkbp_event_supported = fls(ver_mask);
516 543
517 dev_dbg(ec_dev->dev, "MKBP support version %u\n",544 dev_dbg(ec_dev->dev, "MKBP support version %u\n", ec_dev->mkbp_event_supported - 1);
518 ec_dev->mkbp_event_supported - 1);545 }
519 546
520 /* Probe if host sleep v1 is supported for S0ix failure detection. */547 /* Probe if host sleep v1 is supported for S0ix failure detection. */
521 ret = cros_ec_get_host_command_version_mask(ec_dev,548 ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_HOST_SLEEP_EVENT, &ver_mask);
522 EC_CMD_HOST_SLEEP_EVENT,549 ec_dev->host_sleep_v1 = (ret == 0 && (ver_mask & EC_VER_MASK(1)));
523 &ver_mask);
524 ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1)));
525 550
526 /* Get host event wake mask. */551 /* Get host event wake mask. */
527 ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,552 ret = cros_ec_get_host_event_wake_mask(ec_dev, &ec_dev->host_event_wake_mask);
528 &ec_dev->host_event_wake_mask);
529 if (ret < 0) {553 if (ret < 0) {
530 /*554 /*
531 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,555 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,
@@ -556,7 +580,6 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 24 unmodified lines
556 ret = 0;580 ret = 0;
557 581
558exit:582exit:
559 kfree(proto_msg);
560 return ret;583 return ret;
561}584}
562EXPORT_SYMBOL(cros_ec_query_all);585EXPORT_SYMBOL(cros_ec_query_all);
@@ -601,7 +624,7 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) · 38 unmodified lines
601 msg->insize = ec_dev->max_response;624 msg->insize = ec_dev->max_response;
602 }625 }
603 626
604 if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {627 if (msg->command < EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX)) {
605 if (msg->outsize > ec_dev->max_request) {628 if (msg->outsize > ec_dev->max_request) {
606 dev_err(ec_dev->dev,629 dev_err(ec_dev->dev,
607 "request of size %u is too big (max: %u)\n",630 "request of size %u is too big (max: %u)\n",
@@ -621,7 +644,7 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) · 13 unmodified lines
621 }644 }
622 }645 }
623 646
624 ret = send_command(ec_dev, msg);647 ret = cros_ec_send_command(ec_dev, msg);
625 mutex_unlock(&ec_dev->lock);648 mutex_unlock(&ec_dev->lock);
626 649
627 return ret;650 return ret;
@@ -852,8 +875,8 @@ bool cros_ec_check_features(struct cros_ec_dev *ec, int feature) · 224 unmodified lines
852 875
853 if (features->flags[0] == -1U && features->flags[1] == -1U) {876 if (features->flags[0] == -1U && features->flags[1] == -1U) {
854 /* features bitmap not read yet */877 /* features bitmap not read yet */
855 ret = cros_ec_command(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,878 ret = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
856 NULL, 0, features, sizeof(*features));879 NULL, 0, features, sizeof(*features));
857 if (ret < 0) {880 if (ret < 0) {
858 dev_warn(ec->dev, "cannot get EC features: %d\n", ret);881 dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
859 memset(features, 0, sizeof(*features));882 memset(features, 0, sizeof(*features));
@@ -934,7 +957,7 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) · 74 unmodified lines
934EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);957EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);
935 958
936/**959/**
937 * cros_ec_command - Send a command to the EC.960 * cros_ec_cmd - Send a command to the EC.
938 *961 *
939 * @ec_dev: EC device962 * @ec_dev: EC device
940 * @version: EC command version963 * @version: EC command version
@@ -946,13 +969,13 @@ EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count); · 5 unmodified lines
946 *969 *
947 * Return: >= 0 on success, negative error number on failure.970 * Return: >= 0 on success, negative error number on failure.
948 */971 */
949int cros_ec_command(struct cros_ec_device *ec_dev,972int cros_ec_cmd(struct cros_ec_device *ec_dev,
950 unsigned int version,973 unsigned int version,
951 int command,974 int command,
952 void *outdata,975 void *outdata,
953 int outsize,976 size_t outsize,
954 void *indata,977 void *indata,
955 int insize)978 size_t insize)
956{979{
957 struct cros_ec_command *msg;980 struct cros_ec_command *msg;
958 int ret;981 int ret;
@@ -979,4 +1002,4 @@ error: · 20 unmodified lines
979 kfree(msg);1002 kfree(msg);
980 return ret;1003 return ret;
981}1004}
982EXPORT_SYMBOL_GPL(cros_ec_command);1005EXPORT_SYMBOL_GPL(cros_ec_cmd);
drivers/platform/chrome/cros_ec_proto_test.c+2753−0
@@ -0,0 +1,2753 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Kunit tests for ChromeOS Embedded Controller protocol.
4 */
5
6#include <kunit/test.h>
7
8#include <asm-generic/unaligned.h>
9#include <linux/platform_data/cros_ec_commands.h>
10#include <linux/platform_data/cros_ec_proto.h>
11
12#include "cros_ec.h"
13#include "cros_kunit_util.h"
14
15#define BUFSIZE 512
16
17struct cros_ec_proto_test_priv {
18 struct cros_ec_device ec_dev;
19 u8 dout[BUFSIZE];
20 u8 din[BUFSIZE];
21 struct cros_ec_command *msg;
22 u8 _msg[BUFSIZE];
23};
24
25static void cros_ec_proto_test_prepare_tx_legacy_normal(struct kunit *test)
26{
27 struct cros_ec_proto_test_priv *priv = test->priv;
28 struct cros_ec_device *ec_dev = &priv->ec_dev;
29 struct cros_ec_command *msg = priv->msg;
30 int ret, i;
31 u8 csum;
32
33 ec_dev->proto_version = 2;
34
35 msg->command = EC_CMD_HELLO;
36 msg->outsize = EC_PROTO2_MAX_PARAM_SIZE;
37 msg->data[0] = 0xde;
38 msg->data[1] = 0xad;
39 msg->data[2] = 0xbe;
40 msg->data[3] = 0xef;
41
42 ret = cros_ec_prepare_tx(ec_dev, msg);
43
44 KUNIT_EXPECT_EQ(test, ret, EC_MSG_TX_PROTO_BYTES + EC_PROTO2_MAX_PARAM_SIZE);
45 KUNIT_EXPECT_EQ(test, ec_dev->dout[0], EC_CMD_VERSION0);
46 KUNIT_EXPECT_EQ(test, ec_dev->dout[1], EC_CMD_HELLO);
47 KUNIT_EXPECT_EQ(test, ec_dev->dout[2], EC_PROTO2_MAX_PARAM_SIZE);
48 KUNIT_EXPECT_EQ(test, EC_MSG_TX_HEADER_BYTES, 3);
49 KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 0], 0xde);
50 KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 1], 0xad);
51 KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 2], 0xbe);
52 KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 3], 0xef);
53 for (i = 4; i < EC_PROTO2_MAX_PARAM_SIZE; ++i)
54 KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + i], 0);
55
56 csum = EC_CMD_VERSION0;
57 csum += EC_CMD_HELLO;
58 csum += EC_PROTO2_MAX_PARAM_SIZE;
59 csum += 0xde;
60 csum += 0xad;
61 csum += 0xbe;
62 csum += 0xef;
63 KUNIT_EXPECT_EQ(test,
64 ec_dev->dout[EC_MSG_TX_HEADER_BYTES + EC_PROTO2_MAX_PARAM_SIZE],
65 csum);
66}
67
68static void cros_ec_proto_test_prepare_tx_legacy_bad_msg_outsize(struct kunit *test)
69{
70 struct cros_ec_proto_test_priv *priv = test->priv;
71 struct cros_ec_device *ec_dev = &priv->ec_dev;
72 struct cros_ec_command *msg = priv->msg;
73 int ret;
74
75 ec_dev->proto_version = 2;
76
77 msg->outsize = EC_PROTO2_MAX_PARAM_SIZE + 1;
78
79 ret = cros_ec_prepare_tx(ec_dev, msg);
80 KUNIT_EXPECT_EQ(test, ret, -EINVAL);
81}
82
83static void cros_ec_proto_test_prepare_tx_normal(struct kunit *test)
84{
85 struct cros_ec_proto_test_priv *priv = test->priv;
86 struct cros_ec_device *ec_dev = &priv->ec_dev;
87 struct cros_ec_command *msg = priv->msg;
88 struct ec_host_request *request = (struct ec_host_request *)ec_dev->dout;
89 int ret, i;
90 u8 csum;
91
92 msg->command = EC_CMD_HELLO;
93 msg->outsize = 0x88;
94 msg->data[0] = 0xde;
95 msg->data[1] = 0xad;
96 msg->data[2] = 0xbe;
97 msg->data[3] = 0xef;
98
99 ret = cros_ec_prepare_tx(ec_dev, msg);
100
101 KUNIT_EXPECT_EQ(test, ret, sizeof(*request) + 0x88);
102
103 KUNIT_EXPECT_EQ(test, request->struct_version, EC_HOST_REQUEST_VERSION);
104 KUNIT_EXPECT_EQ(test, request->command, EC_CMD_HELLO);
105 KUNIT_EXPECT_EQ(test, request->command_version, 0);
106 KUNIT_EXPECT_EQ(test, request->data_len, 0x88);
107 KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 0], 0xde);
108 KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 1], 0xad);
109 KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 2], 0xbe);
110 KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 3], 0xef);
111 for (i = 4; i < 0x88; ++i)
112 KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + i], 0);
113
114 csum = EC_HOST_REQUEST_VERSION;
115 csum += EC_CMD_HELLO;
116 csum += 0x88;
117 csum += 0xde;
118 csum += 0xad;
119 csum += 0xbe;
120 csum += 0xef;
121 KUNIT_EXPECT_EQ(test, request->checksum, (u8)-csum);
122}
123
124static void cros_ec_proto_test_prepare_tx_bad_msg_outsize(struct kunit *test)
125{
126 struct cros_ec_proto_test_priv *priv = test->priv;
127 struct cros_ec_device *ec_dev = &priv->ec_dev;
128 struct cros_ec_command *msg = priv->msg;
129 int ret;
130
131 msg->outsize = ec_dev->dout_size - sizeof(struct ec_host_request) + 1;
132
133 ret = cros_ec_prepare_tx(ec_dev, msg);
134 KUNIT_EXPECT_EQ(test, ret, -EINVAL);
135}
136
137static void cros_ec_proto_test_check_result(struct kunit *test)
138{
139 struct cros_ec_proto_test_priv *priv = test->priv;
140 struct cros_ec_device *ec_dev = &priv->ec_dev;
141 struct cros_ec_command *msg = priv->msg;
142 int ret, i;
143 static enum ec_status status[] = {
144 EC_RES_SUCCESS,
145 EC_RES_INVALID_COMMAND,
146 EC_RES_ERROR,
147 EC_RES_INVALID_PARAM,
148 EC_RES_ACCESS_DENIED,
149 EC_RES_INVALID_RESPONSE,
150 EC_RES_INVALID_VERSION,
151 EC_RES_INVALID_CHECKSUM,
152 EC_RES_UNAVAILABLE,
153 EC_RES_TIMEOUT,
154 EC_RES_OVERFLOW,
155 EC_RES_INVALID_HEADER,
156 EC_RES_REQUEST_TRUNCATED,
157 EC_RES_RESPONSE_TOO_BIG,
158 EC_RES_BUS_ERROR,
159 EC_RES_BUSY,
160 EC_RES_INVALID_HEADER_VERSION,
161 EC_RES_INVALID_HEADER_CRC,
162 EC_RES_INVALID_DATA_CRC,
163 EC_RES_DUP_UNAVAILABLE,
164 };
165
166 for (i = 0; i < ARRAY_SIZE(status); ++i) {
167 msg->result = status[i];
168 ret = cros_ec_check_result(ec_dev, msg);
169 KUNIT_EXPECT_EQ(test, ret, 0);
170 }
171
172 msg->result = EC_RES_IN_PROGRESS;
173 ret = cros_ec_check_result(ec_dev, msg);
174 KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
175}
176
177static void cros_ec_proto_test_query_all_pretest(struct kunit *test)
178{
179 struct cros_ec_proto_test_priv *priv = test->priv;
180 struct cros_ec_device *ec_dev = &priv->ec_dev;
181
182 /*
183 * cros_ec_query_all() will free din and dout and allocate them again to fit the usage by
184 * calling devm_kfree() and devm_kzalloc(). Set them to NULL as they aren't managed by
185 * ec_dev->dev but allocated statically in struct cros_ec_proto_test_priv
186 * (see cros_ec_proto_test_init()).
187 */
188 ec_dev->din = NULL;
189 ec_dev->dout = NULL;
190}
191
192static void cros_ec_proto_test_query_all_normal(struct kunit *test)
193{
194 struct cros_ec_proto_test_priv *priv = test->priv;
195 struct cros_ec_device *ec_dev = &priv->ec_dev;
196 struct ec_xfer_mock *mock;
197 int ret;
198
199 /* For cros_ec_get_proto_info() without passthru. */
200 {
201 struct ec_response_get_protocol_info *data;
202
203 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
204 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
205
206 data = (struct ec_response_get_protocol_info *)mock->o_data;
207 data->protocol_versions = BIT(3) | BIT(2);
208 data->max_request_packet_size = 0xbe;
209 data->max_response_packet_size = 0xef;
210 }
211
212 /* For cros_ec_get_proto_info() with passthru. */
213 {
214 struct ec_response_get_protocol_info *data;
215
216 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
217 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
218
219 data = (struct ec_response_get_protocol_info *)mock->o_data;
220 data->max_request_packet_size = 0xbf;
221 }
222
223 /* For cros_ec_get_host_command_version_mask() for MKBP. */
224 {
225 struct ec_response_get_cmd_versions *data;
226
227 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
228 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
229
230 data = (struct ec_response_get_cmd_versions *)mock->o_data;
231 data->version_mask = BIT(6) | BIT(5);
232 }
233
234 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
235 {
236 struct ec_response_get_cmd_versions *data;
237
238 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
239 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
240
241 data = (struct ec_response_get_cmd_versions *)mock->o_data;
242 data->version_mask = BIT(1);
243 }
244
245 /* For cros_ec_get_host_event_wake_mask(). */
246 {
247 struct ec_response_host_event_mask *data;
248
249 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
250 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
251
252 data = (struct ec_response_host_event_mask *)mock->o_data;
253 data->mask = 0xbeef;
254 }
255
256 cros_ec_proto_test_query_all_pretest(test);
257 ret = cros_ec_query_all(ec_dev);
258 KUNIT_EXPECT_EQ(test, ret, 0);
259
260 /* For cros_ec_get_proto_info() without passthru. */
261 {
262 mock = cros_kunit_ec_xfer_mock_next();
263 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
264
265 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
266 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
267 KUNIT_EXPECT_EQ(test, mock->msg.insize,
268 sizeof(struct ec_response_get_protocol_info));
269 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
270
271 KUNIT_EXPECT_EQ(test, ec_dev->max_request, 0xbe - sizeof(struct ec_host_request));
272 KUNIT_EXPECT_EQ(test, ec_dev->max_response, 0xef - sizeof(struct ec_host_response));
273 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 3);
274 KUNIT_EXPECT_EQ(test, ec_dev->din_size, 0xef + EC_MAX_RESPONSE_OVERHEAD);
275 KUNIT_EXPECT_EQ(test, ec_dev->dout_size, 0xbe + EC_MAX_REQUEST_OVERHEAD);
276 }
277
278 /* For cros_ec_get_proto_info() with passthru. */
279 {
280 mock = cros_kunit_ec_xfer_mock_next();
281 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
282
283 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
284 KUNIT_EXPECT_EQ(test, mock->msg.command,
285 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
286 EC_CMD_GET_PROTOCOL_INFO);
287 KUNIT_EXPECT_EQ(test, mock->msg.insize,
288 sizeof(struct ec_response_get_protocol_info));
289 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
290
291 KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0xbf - sizeof(struct ec_host_request));
292 }
293
294 /* For cros_ec_get_host_command_version_mask() for MKBP. */
295 {
296 struct ec_params_get_cmd_versions *data;
297
298 mock = cros_kunit_ec_xfer_mock_next();
299 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
300
301 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
302 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
303 KUNIT_EXPECT_EQ(test, mock->msg.insize,
304 sizeof(struct ec_response_get_cmd_versions));
305 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
306
307 data = (struct ec_params_get_cmd_versions *)mock->i_data;
308 KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
309
310 KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 7);
311 }
312
313 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
314 {
315 struct ec_params_get_cmd_versions *data;
316
317 mock = cros_kunit_ec_xfer_mock_next();
318 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
319
320 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
321 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
322 KUNIT_EXPECT_EQ(test, mock->msg.insize,
323 sizeof(struct ec_response_get_cmd_versions));
324 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
325
326 data = (struct ec_params_get_cmd_versions *)mock->i_data;
327 KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_HOST_SLEEP_EVENT);
328
329 KUNIT_EXPECT_TRUE(test, ec_dev->host_sleep_v1);
330 }
331
332 /* For cros_ec_get_host_event_wake_mask(). */
333 {
334 mock = cros_kunit_ec_xfer_mock_next();
335 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
336
337 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
338 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
339 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
340 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
341
342 KUNIT_EXPECT_EQ(test, ec_dev->host_event_wake_mask, 0xbeef);
343 }
344}
345
346static void cros_ec_proto_test_query_all_no_pd_return_error(struct kunit *test)
347{
348 struct cros_ec_proto_test_priv *priv = test->priv;
349 struct cros_ec_device *ec_dev = &priv->ec_dev;
350 struct ec_xfer_mock *mock;
351 int ret;
352
353 /* Set some garbage bytes. */
354 ec_dev->max_passthru = 0xbf;
355
356 /* For cros_ec_get_proto_info() without passthru. */
357 {
358 struct ec_response_get_protocol_info *data;
359
360 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
361 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
362
363 /*
364 * Although it doesn't check the value, provides valid sizes so that
365 * cros_ec_query_all() allocates din and dout correctly.
366 */
367 data = (struct ec_response_get_protocol_info *)mock->o_data;
368 data->max_request_packet_size = 0xbe;
369 data->max_response_packet_size = 0xef;
370 }
371
372 /* For cros_ec_get_proto_info() with passthru. */
373 {
374 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
375 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
376 }
377
378 cros_ec_proto_test_query_all_pretest(test);
379 ret = cros_ec_query_all(ec_dev);
380 KUNIT_EXPECT_EQ(test, ret, 0);
381
382 /* For cros_ec_get_proto_info() without passthru. */
383 {
384 mock = cros_kunit_ec_xfer_mock_next();
385 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
386
387 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
388 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
389 KUNIT_EXPECT_EQ(test, mock->msg.insize,
390 sizeof(struct ec_response_get_protocol_info));
391 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
392 }
393
394 /* For cros_ec_get_proto_info() with passthru. */
395 {
396 mock = cros_kunit_ec_xfer_mock_next();
397 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
398
399 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
400 KUNIT_EXPECT_EQ(test, mock->msg.command,
401 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
402 EC_CMD_GET_PROTOCOL_INFO);
403 KUNIT_EXPECT_EQ(test, mock->msg.insize,
404 sizeof(struct ec_response_get_protocol_info));
405 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
406
407 KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
408 }
409}
410
411static void cros_ec_proto_test_query_all_no_pd_return0(struct kunit *test)
412{
413 struct cros_ec_proto_test_priv *priv = test->priv;
414 struct cros_ec_device *ec_dev = &priv->ec_dev;
415 struct ec_xfer_mock *mock;
416 int ret;
417
418 /* Set some garbage bytes. */
419 ec_dev->max_passthru = 0xbf;
420
421 /* For cros_ec_get_proto_info() without passthru. */
422 {
423 struct ec_response_get_protocol_info *data;
424
425 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
426 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
427
428 /*
429 * Although it doesn't check the value, provides valid sizes so that
430 * cros_ec_query_all() allocates din and dout correctly.
431 */
432 data = (struct ec_response_get_protocol_info *)mock->o_data;
433 data->max_request_packet_size = 0xbe;
434 data->max_response_packet_size = 0xef;
435 }
436
437 /* For cros_ec_get_proto_info() with passthru. */
438 {
439 mock = cros_kunit_ec_xfer_mock_add(test, 0);
440 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
441 }
442
443 cros_ec_proto_test_query_all_pretest(test);
444 ret = cros_ec_query_all(ec_dev);
445 KUNIT_EXPECT_EQ(test, ret, 0);
446
447 /* For cros_ec_get_proto_info() without passthru. */
448 {
449 mock = cros_kunit_ec_xfer_mock_next();
450 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
451
452 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
453 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
454 KUNIT_EXPECT_EQ(test, mock->msg.insize,
455 sizeof(struct ec_response_get_protocol_info));
456 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
457 }
458
459 /* For cros_ec_get_proto_info() with passthru. */
460 {
461 mock = cros_kunit_ec_xfer_mock_next();
462 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
463
464 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
465 KUNIT_EXPECT_EQ(test, mock->msg.command,
466 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
467 EC_CMD_GET_PROTOCOL_INFO);
468 KUNIT_EXPECT_EQ(test, mock->msg.insize,
469 sizeof(struct ec_response_get_protocol_info));
470 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
471
472 KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
473 }
474}
475
476static void cros_ec_proto_test_query_all_legacy_normal_v3_return_error(struct kunit *test)
477{
478 struct cros_ec_proto_test_priv *priv = test->priv;
479 struct cros_ec_device *ec_dev = &priv->ec_dev;
480 struct ec_xfer_mock *mock;
481 int ret;
482
483 /* For cros_ec_get_proto_info() without passthru. */
484 {
485 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
486 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
487 }
488
489 /* For cros_ec_get_proto_info_legacy(). */
490 {
491 struct ec_response_hello *data;
492
493 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
494 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
495
496 data = (struct ec_response_hello *)mock->o_data;
497 data->out_data = 0xa1b2c3d4;
498 }
499
500 cros_ec_proto_test_query_all_pretest(test);
501 ret = cros_ec_query_all(ec_dev);
502 KUNIT_EXPECT_EQ(test, ret, 0);
503
504 /* For cros_ec_get_proto_info() without passthru. */
505 {
506 mock = cros_kunit_ec_xfer_mock_next();
507 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
508
509 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
510 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
511 KUNIT_EXPECT_EQ(test, mock->msg.insize,
512 sizeof(struct ec_response_get_protocol_info));
513 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
514 }
515
516 /* For cros_ec_get_proto_info_legacy(). */
517 {
518 struct ec_params_hello *data;
519
520 mock = cros_kunit_ec_xfer_mock_next();
521 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
522
523 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
524 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
525 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
526 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
527
528 data = (struct ec_params_hello *)mock->i_data;
529 KUNIT_EXPECT_EQ(test, data->in_data, 0xa0b0c0d0);
530
531 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 2);
532 KUNIT_EXPECT_EQ(test, ec_dev->max_request, EC_PROTO2_MAX_PARAM_SIZE);
533 KUNIT_EXPECT_EQ(test, ec_dev->max_response, EC_PROTO2_MAX_PARAM_SIZE);
534 KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
535 KUNIT_EXPECT_PTR_EQ(test, ec_dev->pkt_xfer, NULL);
536 KUNIT_EXPECT_EQ(test, ec_dev->din_size, EC_PROTO2_MSG_BYTES);
537 KUNIT_EXPECT_EQ(test, ec_dev->dout_size, EC_PROTO2_MSG_BYTES);
538 }
539}
540
541static void cros_ec_proto_test_query_all_legacy_normal_v3_return0(struct kunit *test)
542{
543 struct cros_ec_proto_test_priv *priv = test->priv;
544 struct cros_ec_device *ec_dev = &priv->ec_dev;
545 struct ec_xfer_mock *mock;
546 int ret;
547
548 /* For cros_ec_get_proto_info() without passthru. */
549 {
550 mock = cros_kunit_ec_xfer_mock_add(test, 0);
551 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
552 }
553
554 /* For cros_ec_get_proto_info_legacy(). */
555 {
556 struct ec_response_hello *data;
557
558 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
559 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
560
561 data = (struct ec_response_hello *)mock->o_data;
562 data->out_data = 0xa1b2c3d4;
563 }
564
565 cros_ec_proto_test_query_all_pretest(test);
566 ret = cros_ec_query_all(ec_dev);
567 KUNIT_EXPECT_EQ(test, ret, 0);
568
569 /* For cros_ec_get_proto_info() without passthru. */
570 {
571 mock = cros_kunit_ec_xfer_mock_next();
572 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
573
574 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
575 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
576 KUNIT_EXPECT_EQ(test, mock->msg.insize,
577 sizeof(struct ec_response_get_protocol_info));
578 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
579 }
580
581 /* For cros_ec_get_proto_info_legacy(). */
582 {
583 struct ec_params_hello *data;
584
585 mock = cros_kunit_ec_xfer_mock_next();
586 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
587
588 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
589 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
590 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
591 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
592
593 data = (struct ec_params_hello *)mock->i_data;
594 KUNIT_EXPECT_EQ(test, data->in_data, 0xa0b0c0d0);
595
596 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 2);
597 KUNIT_EXPECT_EQ(test, ec_dev->max_request, EC_PROTO2_MAX_PARAM_SIZE);
598 KUNIT_EXPECT_EQ(test, ec_dev->max_response, EC_PROTO2_MAX_PARAM_SIZE);
599 KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
600 KUNIT_EXPECT_PTR_EQ(test, ec_dev->pkt_xfer, NULL);
601 KUNIT_EXPECT_EQ(test, ec_dev->din_size, EC_PROTO2_MSG_BYTES);
602 KUNIT_EXPECT_EQ(test, ec_dev->dout_size, EC_PROTO2_MSG_BYTES);
603 }
604}
605
606static void cros_ec_proto_test_query_all_legacy_xfer_error(struct kunit *test)
607{
608 struct cros_ec_proto_test_priv *priv = test->priv;
609 struct cros_ec_device *ec_dev = &priv->ec_dev;
610 struct ec_xfer_mock *mock;
611 int ret;
612
613 /* For cros_ec_get_proto_info() without passthru. */
614 {
615 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
616 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
617 }
618
619 /* For cros_ec_get_proto_info_legacy(). */
620 {
621 mock = cros_kunit_ec_xfer_mock_addx(test, -EIO, EC_RES_SUCCESS, 0);
622 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
623 }
624
625 cros_ec_proto_test_query_all_pretest(test);
626 ret = cros_ec_query_all(ec_dev);
627 KUNIT_EXPECT_EQ(test, ret, -EIO);
628 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
629
630 /* For cros_ec_get_proto_info() without passthru. */
631 {
632 mock = cros_kunit_ec_xfer_mock_next();
633 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
634
635 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
636 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
637 KUNIT_EXPECT_EQ(test, mock->msg.insize,
638 sizeof(struct ec_response_get_protocol_info));
639 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
640 }
641
642 /* For cros_ec_get_proto_info_legacy(). */
643 {
644 mock = cros_kunit_ec_xfer_mock_next();
645 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
646
647 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
648 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
649 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
650 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
651 }
652}
653
654static void cros_ec_proto_test_query_all_legacy_return_error(struct kunit *test)
655{
656 struct cros_ec_proto_test_priv *priv = test->priv;
657 struct cros_ec_device *ec_dev = &priv->ec_dev;
658 struct ec_xfer_mock *mock;
659 int ret;
660
661 /* For cros_ec_get_proto_info() without passthru. */
662 {
663 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
664 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
665 }
666
667 /* For cros_ec_get_proto_info_legacy(). */
668 {
669 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
670 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
671 }
672
673 cros_ec_proto_test_query_all_pretest(test);
674 ret = cros_ec_query_all(ec_dev);
675 KUNIT_EXPECT_EQ(test, ret, -EOPNOTSUPP);
676 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
677
678 /* For cros_ec_get_proto_info() without passthru. */
679 {
680 mock = cros_kunit_ec_xfer_mock_next();
681 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
682
683 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
684 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
685 KUNIT_EXPECT_EQ(test, mock->msg.insize,
686 sizeof(struct ec_response_get_protocol_info));
687 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
688 }
689
690 /* For cros_ec_get_proto_info_legacy(). */
691 {
692 mock = cros_kunit_ec_xfer_mock_next();
693 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
694
695 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
696 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
697 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
698 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
699 }
700}
701
702static void cros_ec_proto_test_query_all_legacy_data_error(struct kunit *test)
703{
704 struct cros_ec_proto_test_priv *priv = test->priv;
705 struct cros_ec_device *ec_dev = &priv->ec_dev;
706 struct ec_xfer_mock *mock;
707 int ret;
708
709 /* For cros_ec_get_proto_info() without passthru. */
710 {
711 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
712 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
713 }
714
715 /* For cros_ec_get_proto_info_legacy(). */
716 {
717 struct ec_response_hello *data;
718
719 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
720 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
721
722 data = (struct ec_response_hello *)mock->o_data;
723 data->out_data = 0xbeefbfbf;
724 }
725
726 cros_ec_proto_test_query_all_pretest(test);
727 ret = cros_ec_query_all(ec_dev);
728 KUNIT_EXPECT_EQ(test, ret, -EBADMSG);
729 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
730
731 /* For cros_ec_get_proto_info() without passthru. */
732 {
733 mock = cros_kunit_ec_xfer_mock_next();
734 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
735
736 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
737 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
738 KUNIT_EXPECT_EQ(test, mock->msg.insize,
739 sizeof(struct ec_response_get_protocol_info));
740 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
741 }
742
743 /* For cros_ec_get_proto_info_legacy(). */
744 {
745 mock = cros_kunit_ec_xfer_mock_next();
746 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
747
748 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
749 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
750 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
751 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
752 }
753}
754
755static void cros_ec_proto_test_query_all_legacy_return0(struct kunit *test)
756{
757 struct cros_ec_proto_test_priv *priv = test->priv;
758 struct cros_ec_device *ec_dev = &priv->ec_dev;
759 struct ec_xfer_mock *mock;
760 int ret;
761
762 /* For cros_ec_get_proto_info() without passthru. */
763 {
764 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
765 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
766 }
767
768 /* For cros_ec_get_proto_info_legacy(). */
769 {
770 mock = cros_kunit_ec_xfer_mock_add(test, 0);
771 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
772 }
773
774 cros_ec_proto_test_query_all_pretest(test);
775 ret = cros_ec_query_all(ec_dev);
776 KUNIT_EXPECT_EQ(test, ret, -EPROTO);
777 KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
778
779 /* For cros_ec_get_proto_info() without passthru. */
780 {
781 mock = cros_kunit_ec_xfer_mock_next();
782 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
783
784 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
785 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
786 KUNIT_EXPECT_EQ(test, mock->msg.insize,
787 sizeof(struct ec_response_get_protocol_info));
788 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
789 }
790
791 /* For cros_ec_get_proto_info_legacy(). */
792 {
793 mock = cros_kunit_ec_xfer_mock_next();
794 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
795
796 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
797 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
798 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
799 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
800 }
801}
802
803static void cros_ec_proto_test_query_all_no_mkbp(struct kunit *test)
804{
805 struct cros_ec_proto_test_priv *priv = test->priv;
806 struct cros_ec_device *ec_dev = &priv->ec_dev;
807 struct ec_xfer_mock *mock;
808 int ret;
809
810 /* Set some garbage bytes. */
811 ec_dev->mkbp_event_supported = 0xbf;
812
813 /* For cros_ec_get_proto_info() without passthru. */
814 {
815 struct ec_response_get_protocol_info *data;
816
817 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
818 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
819
820 /*
821 * Although it doesn't check the value, provides valid sizes so that
822 * cros_ec_query_all() allocates din and dout correctly.
823 */
824 data = (struct ec_response_get_protocol_info *)mock->o_data;
825 data->max_request_packet_size = 0xbe;
826 data->max_response_packet_size = 0xef;
827 }
828
829 /* For cros_ec_get_proto_info() with passthru. */
830 {
831 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
832 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
833 }
834
835 /* For cros_ec_get_host_command_version_mask() for MKBP. */
836 {
837 struct ec_response_get_cmd_versions *data;
838
839 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
840 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
841
842 data = (struct ec_response_get_cmd_versions *)mock->o_data;
843 data->version_mask = 0;
844 }
845
846 cros_ec_proto_test_query_all_pretest(test);
847 ret = cros_ec_query_all(ec_dev);
848 KUNIT_EXPECT_EQ(test, ret, 0);
849
850 /* For cros_ec_get_proto_info() without passthru. */
851 {
852 mock = cros_kunit_ec_xfer_mock_next();
853 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
854
855 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
856 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
857 KUNIT_EXPECT_EQ(test, mock->msg.insize,
858 sizeof(struct ec_response_get_protocol_info));
859 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
860 }
861
862 /* For cros_ec_get_proto_info() with passthru. */
863 {
864 mock = cros_kunit_ec_xfer_mock_next();
865 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
866
867 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
868 KUNIT_EXPECT_EQ(test, mock->msg.command,
869 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
870 EC_CMD_GET_PROTOCOL_INFO);
871 KUNIT_EXPECT_EQ(test, mock->msg.insize,
872 sizeof(struct ec_response_get_protocol_info));
873 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
874 }
875
876 /* For cros_ec_get_host_command_version_mask() for MKBP. */
877 {
878 struct ec_params_get_cmd_versions *data;
879
880 mock = cros_kunit_ec_xfer_mock_next();
881 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
882
883 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
884 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
885 KUNIT_EXPECT_EQ(test, mock->msg.insize,
886 sizeof(struct ec_response_get_cmd_versions));
887 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
888
889 data = (struct ec_params_get_cmd_versions *)mock->i_data;
890 KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
891
892 KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
893 }
894}
895
896static void cros_ec_proto_test_query_all_no_mkbp_return_error(struct kunit *test)
897{
898 struct cros_ec_proto_test_priv *priv = test->priv;
899 struct cros_ec_device *ec_dev = &priv->ec_dev;
900 struct ec_xfer_mock *mock;
901 int ret;
902
903 /* Set some garbage bytes. */
904 ec_dev->mkbp_event_supported = 0xbf;
905
906 /* For cros_ec_get_proto_info() without passthru. */
907 {
908 struct ec_response_get_protocol_info *data;
909
910 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
911 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
912
913 /*
914 * Although it doesn't check the value, provides valid sizes so that
915 * cros_ec_query_all() allocates din and dout correctly.
916 */
917 data = (struct ec_response_get_protocol_info *)mock->o_data;
918 data->max_request_packet_size = 0xbe;
919 data->max_response_packet_size = 0xef;
920 }
921
922 /* For cros_ec_get_proto_info() with passthru. */
923 {
924 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
925 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
926 }
927
928 /* For cros_ec_get_host_command_version_mask() for MKBP. */
929 {
930 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
931 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
932 }
933
934 cros_ec_proto_test_query_all_pretest(test);
935 ret = cros_ec_query_all(ec_dev);
936 KUNIT_EXPECT_EQ(test, ret, 0);
937
938 /* For cros_ec_get_proto_info() without passthru. */
939 {
940 mock = cros_kunit_ec_xfer_mock_next();
941 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
942
943 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
944 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
945 KUNIT_EXPECT_EQ(test, mock->msg.insize,
946 sizeof(struct ec_response_get_protocol_info));
947 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
948 }
949
950 /* For cros_ec_get_proto_info() with passthru. */
951 {
952 mock = cros_kunit_ec_xfer_mock_next();
953 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
954
955 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
956 KUNIT_EXPECT_EQ(test, mock->msg.command,
957 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
958 EC_CMD_GET_PROTOCOL_INFO);
959 KUNIT_EXPECT_EQ(test, mock->msg.insize,
960 sizeof(struct ec_response_get_protocol_info));
961 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
962 }
963
964 /* For cros_ec_get_host_command_version_mask() for MKBP. */
965 {
966 struct ec_params_get_cmd_versions *data;
967
968 mock = cros_kunit_ec_xfer_mock_next();
969 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
970
971 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
972 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
973 KUNIT_EXPECT_EQ(test, mock->msg.insize,
974 sizeof(struct ec_response_get_cmd_versions));
975 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
976
977 data = (struct ec_params_get_cmd_versions *)mock->i_data;
978 KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
979
980 KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
981 }
982}
983
984static void cros_ec_proto_test_query_all_no_mkbp_return0(struct kunit *test)
985{
986 struct cros_ec_proto_test_priv *priv = test->priv;
987 struct cros_ec_device *ec_dev = &priv->ec_dev;
988 struct ec_xfer_mock *mock;
989 int ret;
990
991 /* Set some garbage bytes. */
992 ec_dev->mkbp_event_supported = 0xbf;
993
994 /* For cros_ec_get_proto_info() without passthru. */
995 {
996 struct ec_response_get_protocol_info *data;
997
998 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
999 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1000
1001 /*
1002 * Although it doesn't check the value, provides valid sizes so that
1003 * cros_ec_query_all() allocates din and dout correctly.
1004 */
1005 data = (struct ec_response_get_protocol_info *)mock->o_data;
1006 data->max_request_packet_size = 0xbe;
1007 data->max_response_packet_size = 0xef;
1008 }
1009
1010 /* For cros_ec_get_proto_info() with passthru. */
1011 {
1012 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1013 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1014 }
1015
1016 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1017 {
1018 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1019 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1020 }
1021
1022 cros_ec_proto_test_query_all_pretest(test);
1023 ret = cros_ec_query_all(ec_dev);
1024 KUNIT_EXPECT_EQ(test, ret, 0);
1025
1026 /* For cros_ec_get_proto_info() without passthru. */
1027 {
1028 mock = cros_kunit_ec_xfer_mock_next();
1029 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1030
1031 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1032 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1033 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1034 sizeof(struct ec_response_get_protocol_info));
1035 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1036 }
1037
1038 /* For cros_ec_get_proto_info() with passthru. */
1039 {
1040 mock = cros_kunit_ec_xfer_mock_next();
1041 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1042
1043 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1044 KUNIT_EXPECT_EQ(test, mock->msg.command,
1045 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1046 EC_CMD_GET_PROTOCOL_INFO);
1047 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1048 sizeof(struct ec_response_get_protocol_info));
1049 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1050 }
1051
1052 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1053 {
1054 struct ec_params_get_cmd_versions *data;
1055
1056 mock = cros_kunit_ec_xfer_mock_next();
1057 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1058
1059 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1060 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1061 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1062 sizeof(struct ec_response_get_cmd_versions));
1063 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
1064
1065 data = (struct ec_params_get_cmd_versions *)mock->i_data;
1066 KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
1067
1068 KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
1069 }
1070}
1071
1072static void cros_ec_proto_test_query_all_no_host_sleep(struct kunit *test)
1073{
1074 struct cros_ec_proto_test_priv *priv = test->priv;
1075 struct cros_ec_device *ec_dev = &priv->ec_dev;
1076 struct ec_xfer_mock *mock;
1077 int ret;
1078
1079 /* Set some garbage bytes. */
1080 ec_dev->host_sleep_v1 = true;
1081
1082 /* For cros_ec_get_proto_info() without passthru. */
1083 {
1084 struct ec_response_get_protocol_info *data;
1085
1086 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1087 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1088
1089 /*
1090 * Although it doesn't check the value, provides valid sizes so that
1091 * cros_ec_query_all() allocates din and dout correctly.
1092 */
1093 data = (struct ec_response_get_protocol_info *)mock->o_data;
1094 data->max_request_packet_size = 0xbe;
1095 data->max_response_packet_size = 0xef;
1096 }
1097
1098 /* For cros_ec_get_proto_info() with passthru. */
1099 {
1100 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1101 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1102 }
1103
1104 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1105 {
1106 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1107 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1108 }
1109
1110 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1111 {
1112 struct ec_response_get_cmd_versions *data;
1113
1114 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1115 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1116
1117 data = (struct ec_response_get_cmd_versions *)mock->o_data;
1118 data->version_mask = 0;
1119 }
1120
1121 cros_ec_proto_test_query_all_pretest(test);
1122 ret = cros_ec_query_all(ec_dev);
1123 KUNIT_EXPECT_EQ(test, ret, 0);
1124
1125 /* For cros_ec_get_proto_info() without passthru. */
1126 {
1127 mock = cros_kunit_ec_xfer_mock_next();
1128 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1129
1130 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1131 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1132 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1133 sizeof(struct ec_response_get_protocol_info));
1134 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1135 }
1136
1137 /* For cros_ec_get_proto_info() with passthru. */
1138 {
1139 mock = cros_kunit_ec_xfer_mock_next();
1140 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1141
1142 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1143 KUNIT_EXPECT_EQ(test, mock->msg.command,
1144 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1145 EC_CMD_GET_PROTOCOL_INFO);
1146 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1147 sizeof(struct ec_response_get_protocol_info));
1148 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1149 }
1150
1151 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1152 {
1153 mock = cros_kunit_ec_xfer_mock_next();
1154 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1155
1156 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1157 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1158 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1159 sizeof(struct ec_response_get_cmd_versions));
1160 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1161 }
1162
1163 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1164 {
1165 mock = cros_kunit_ec_xfer_mock_next();
1166 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1167
1168 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1169 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1170 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1171 sizeof(struct ec_response_get_cmd_versions));
1172 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1173
1174 KUNIT_EXPECT_FALSE(test, ec_dev->host_sleep_v1);
1175 }
1176}
1177
1178static void cros_ec_proto_test_query_all_no_host_sleep_return0(struct kunit *test)
1179{
1180 struct cros_ec_proto_test_priv *priv = test->priv;
1181 struct cros_ec_device *ec_dev = &priv->ec_dev;
1182 struct ec_xfer_mock *mock;
1183 int ret;
1184
1185 /* Set some garbage bytes. */
1186 ec_dev->host_sleep_v1 = true;
1187
1188 /* For cros_ec_get_proto_info() without passthru. */
1189 {
1190 struct ec_response_get_protocol_info *data;
1191
1192 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1193 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1194
1195 /*
1196 * Although it doesn't check the value, provides valid sizes so that
1197 * cros_ec_query_all() allocates din and dout correctly.
1198 */
1199 data = (struct ec_response_get_protocol_info *)mock->o_data;
1200 data->max_request_packet_size = 0xbe;
1201 data->max_response_packet_size = 0xef;
1202 }
1203
1204 /* For cros_ec_get_proto_info() with passthru. */
1205 {
1206 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1207 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1208 }
1209
1210 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1211 {
1212 struct ec_response_get_cmd_versions *data;
1213
1214 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1215 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1216
1217 /* In order to pollute next cros_ec_get_host_command_version_mask(). */
1218 data = (struct ec_response_get_cmd_versions *)mock->o_data;
1219 data->version_mask = 0xbeef;
1220 }
1221
1222 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1223 {
1224 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1225 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1226 }
1227
1228 cros_ec_proto_test_query_all_pretest(test);
1229 ret = cros_ec_query_all(ec_dev);
1230 KUNIT_EXPECT_EQ(test, ret, 0);
1231
1232 /* For cros_ec_get_proto_info() without passthru. */
1233 {
1234 mock = cros_kunit_ec_xfer_mock_next();
1235 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1236
1237 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1238 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1239 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1240 sizeof(struct ec_response_get_protocol_info));
1241 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1242 }
1243
1244 /* For cros_ec_get_proto_info() with passthru. */
1245 {
1246 mock = cros_kunit_ec_xfer_mock_next();
1247 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1248
1249 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1250 KUNIT_EXPECT_EQ(test, mock->msg.command,
1251 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1252 EC_CMD_GET_PROTOCOL_INFO);
1253 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1254 sizeof(struct ec_response_get_protocol_info));
1255 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1256 }
1257
1258 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1259 {
1260 mock = cros_kunit_ec_xfer_mock_next();
1261 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1262
1263 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1264 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1265 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1266 sizeof(struct ec_response_get_cmd_versions));
1267 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1268 }
1269
1270 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1271 {
1272 mock = cros_kunit_ec_xfer_mock_next();
1273 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1274
1275 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1276 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1277 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1278 sizeof(struct ec_response_get_cmd_versions));
1279 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1280
1281 KUNIT_EXPECT_FALSE(test, ec_dev->host_sleep_v1);
1282 }
1283}
1284
1285static void cros_ec_proto_test_query_all_default_wake_mask_return_error(struct kunit *test)
1286{
1287 struct cros_ec_proto_test_priv *priv = test->priv;
1288 struct cros_ec_device *ec_dev = &priv->ec_dev;
1289 struct ec_xfer_mock *mock;
1290 int ret;
1291
1292 /* Set some garbage bytes. */
1293 ec_dev->host_event_wake_mask = U32_MAX;
1294
1295 /* For cros_ec_get_proto_info() without passthru. */
1296 {
1297 struct ec_response_get_protocol_info *data;
1298
1299 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1300 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1301
1302 /*
1303 * Although it doesn't check the value, provides valid sizes so that
1304 * cros_ec_query_all() allocates din and dout correctly.
1305 */
1306 data = (struct ec_response_get_protocol_info *)mock->o_data;
1307 data->max_request_packet_size = 0xbe;
1308 data->max_response_packet_size = 0xef;
1309 }
1310
1311 /* For cros_ec_get_proto_info() with passthru. */
1312 {
1313 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1314 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1315 }
1316
1317 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1318 {
1319 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1320 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1321 }
1322
1323 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1324 {
1325 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1326 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1327 }
1328
1329 /* For cros_ec_get_host_event_wake_mask(). */
1330 {
1331 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1332 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1333 }
1334
1335 cros_ec_proto_test_query_all_pretest(test);
1336 ret = cros_ec_query_all(ec_dev);
1337 KUNIT_EXPECT_EQ(test, ret, 0);
1338
1339 /* For cros_ec_get_proto_info() without passthru. */
1340 {
1341 mock = cros_kunit_ec_xfer_mock_next();
1342 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1343
1344 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1345 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1346 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1347 sizeof(struct ec_response_get_protocol_info));
1348 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1349 }
1350
1351 /* For cros_ec_get_proto_info() with passthru. */
1352 {
1353 mock = cros_kunit_ec_xfer_mock_next();
1354 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1355
1356 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1357 KUNIT_EXPECT_EQ(test, mock->msg.command,
1358 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1359 EC_CMD_GET_PROTOCOL_INFO);
1360 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1361 sizeof(struct ec_response_get_protocol_info));
1362 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1363 }
1364
1365 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1366 {
1367 mock = cros_kunit_ec_xfer_mock_next();
1368 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1369
1370 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1371 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1372 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1373 sizeof(struct ec_response_get_cmd_versions));
1374 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1375 }
1376
1377 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1378 {
1379 mock = cros_kunit_ec_xfer_mock_next();
1380 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1381
1382 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1383 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1384 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1385 sizeof(struct ec_response_get_cmd_versions));
1386 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1387 }
1388
1389 /* For cros_ec_get_host_event_wake_mask(). */
1390 {
1391 u32 mask;
1392
1393 mock = cros_kunit_ec_xfer_mock_next();
1394 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1395
1396 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1397 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
1398 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
1399 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1400
1401 mask = ec_dev->host_event_wake_mask;
1402 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED), 0);
1403 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED), 0);
1404 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW), 0);
1405 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL), 0);
1406 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY), 0);
1407 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU), 0);
1408 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS), 0);
1409 }
1410}
1411
1412static void cros_ec_proto_test_query_all_default_wake_mask_return0(struct kunit *test)
1413{
1414 struct cros_ec_proto_test_priv *priv = test->priv;
1415 struct cros_ec_device *ec_dev = &priv->ec_dev;
1416 struct ec_xfer_mock *mock;
1417 int ret;
1418
1419 /* Set some garbage bytes. */
1420 ec_dev->host_event_wake_mask = U32_MAX;
1421
1422 /* For cros_ec_get_proto_info() without passthru. */
1423 {
1424 struct ec_response_get_protocol_info *data;
1425
1426 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1427 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1428
1429 /*
1430 * Although it doesn't check the value, provides valid sizes so that
1431 * cros_ec_query_all() allocates din and dout correctly.
1432 */
1433 data = (struct ec_response_get_protocol_info *)mock->o_data;
1434 data->max_request_packet_size = 0xbe;
1435 data->max_response_packet_size = 0xef;
1436 }
1437
1438 /* For cros_ec_get_proto_info() with passthru. */
1439 {
1440 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1441 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1442 }
1443
1444 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1445 {
1446 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1447 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1448 }
1449
1450 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1451 {
1452 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1453 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1454 }
1455
1456 /* For get_host_event_wake_mask(). */
1457 {
1458 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1459 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1460 }
1461
1462 cros_ec_proto_test_query_all_pretest(test);
1463 ret = cros_ec_query_all(ec_dev);
1464 KUNIT_EXPECT_EQ(test, ret, 0);
1465
1466 /* For cros_ec_get_proto_info() without passthru. */
1467 {
1468 mock = cros_kunit_ec_xfer_mock_next();
1469 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1470
1471 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1472 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1473 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1474 sizeof(struct ec_response_get_protocol_info));
1475 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1476 }
1477
1478 /* For cros_ec_get_proto_info() with passthru. */
1479 {
1480 mock = cros_kunit_ec_xfer_mock_next();
1481 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1482
1483 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1484 KUNIT_EXPECT_EQ(test, mock->msg.command,
1485 EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1486 EC_CMD_GET_PROTOCOL_INFO);
1487 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1488 sizeof(struct ec_response_get_protocol_info));
1489 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1490 }
1491
1492 /* For cros_ec_get_host_command_version_mask() for MKBP. */
1493 {
1494 mock = cros_kunit_ec_xfer_mock_next();
1495 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1496
1497 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1498 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1499 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1500 sizeof(struct ec_response_get_cmd_versions));
1501 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1502 }
1503
1504 /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1505 {
1506 mock = cros_kunit_ec_xfer_mock_next();
1507 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1508
1509 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1510 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1511 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1512 sizeof(struct ec_response_get_cmd_versions));
1513 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1514 }
1515
1516 /* For get_host_event_wake_mask(). */
1517 {
1518 u32 mask;
1519
1520 mock = cros_kunit_ec_xfer_mock_next();
1521 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1522
1523 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1524 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
1525 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
1526 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1527
1528 mask = ec_dev->host_event_wake_mask;
1529 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED), 0);
1530 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED), 0);
1531 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW), 0);
1532 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL), 0);
1533 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY), 0);
1534 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU), 0);
1535 KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS), 0);
1536 }
1537}
1538
1539static void cros_ec_proto_test_cmd_xfer_normal(struct kunit *test)
1540{
1541 struct cros_ec_proto_test_priv *priv = test->priv;
1542 struct cros_ec_device *ec_dev = &priv->ec_dev;
1543 struct ec_xfer_mock *mock;
1544 int ret;
1545 struct {
1546 struct cros_ec_command msg;
1547 u8 data[0x100];
1548 } __packed buf;
1549
1550 ec_dev->max_request = 0xff;
1551 ec_dev->max_response = 0xee;
1552 ec_dev->max_passthru = 0xdd;
1553
1554 buf.msg.version = 0;
1555 buf.msg.command = EC_CMD_HELLO;
1556 buf.msg.insize = 4;
1557 buf.msg.outsize = 2;
1558 buf.data[0] = 0x55;
1559 buf.data[1] = 0xaa;
1560
1561 {
1562 u8 *data;
1563
1564 mock = cros_kunit_ec_xfer_mock_add(test, 4);
1565 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1566
1567 data = (u8 *)mock->o_data;
1568 data[0] = 0xaa;
1569 data[1] = 0x55;
1570 data[2] = 0xcc;
1571 data[3] = 0x33;
1572 }
1573
1574 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1575 KUNIT_EXPECT_EQ(test, ret, 4);
1576
1577 {
1578 u8 *data;
1579
1580 mock = cros_kunit_ec_xfer_mock_next();
1581 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1582
1583 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1584 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
1585 KUNIT_EXPECT_EQ(test, mock->msg.insize, 4);
1586 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 2);
1587
1588 data = (u8 *)mock->i_data;
1589 KUNIT_EXPECT_EQ(test, data[0], 0x55);
1590 KUNIT_EXPECT_EQ(test, data[1], 0xaa);
1591
1592 KUNIT_EXPECT_EQ(test, buf.data[0], 0xaa);
1593 KUNIT_EXPECT_EQ(test, buf.data[1], 0x55);
1594 KUNIT_EXPECT_EQ(test, buf.data[2], 0xcc);
1595 KUNIT_EXPECT_EQ(test, buf.data[3], 0x33);
1596 }
1597}
1598
1599static void cros_ec_proto_test_cmd_xfer_excess_msg_insize(struct kunit *test)
1600{
1601 struct cros_ec_proto_test_priv *priv = test->priv;
1602 struct cros_ec_device *ec_dev = &priv->ec_dev;
1603 struct ec_xfer_mock *mock;
1604 int ret;
1605 struct {
1606 struct cros_ec_command msg;
1607 u8 data[0x100];
1608 } __packed buf;
1609
1610 ec_dev->max_request = 0xff;
1611 ec_dev->max_response = 0xee;
1612 ec_dev->max_passthru = 0xdd;
1613
1614 buf.msg.version = 0;
1615 buf.msg.command = EC_CMD_HELLO;
1616 buf.msg.insize = 0xee + 1;
1617 buf.msg.outsize = 2;
1618
1619 {
1620 mock = cros_kunit_ec_xfer_mock_add(test, 0xcc);
1621 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1622 }
1623
1624 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1625 KUNIT_EXPECT_EQ(test, ret, 0xcc);
1626
1627 {
1628 mock = cros_kunit_ec_xfer_mock_next();
1629 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1630
1631 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1632 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
1633 KUNIT_EXPECT_EQ(test, mock->msg.insize, 0xee);
1634 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 2);
1635 }
1636}
1637
1638static void cros_ec_proto_test_cmd_xfer_excess_msg_outsize_without_passthru(struct kunit *test)
1639{
1640 struct cros_ec_proto_test_priv *priv = test->priv;
1641 struct cros_ec_device *ec_dev = &priv->ec_dev;
1642 int ret;
1643 struct {
1644 struct cros_ec_command msg;
1645 u8 data[0x100];
1646 } __packed buf;
1647
1648 ec_dev->max_request = 0xff;
1649 ec_dev->max_response = 0xee;
1650 ec_dev->max_passthru = 0xdd;
1651
1652 buf.msg.version = 0;
1653 buf.msg.command = EC_CMD_HELLO;
1654 buf.msg.insize = 4;
1655 buf.msg.outsize = 0xff + 1;
1656
1657 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1658 KUNIT_EXPECT_EQ(test, ret, -EMSGSIZE);
1659}
1660
1661static void cros_ec_proto_test_cmd_xfer_excess_msg_outsize_with_passthru(struct kunit *test)
1662{
1663 struct cros_ec_proto_test_priv *priv = test->priv;
1664 struct cros_ec_device *ec_dev = &priv->ec_dev;
1665 int ret;
1666 struct {
1667 struct cros_ec_command msg;
1668 u8 data[0x100];
1669 } __packed buf;
1670
1671 ec_dev->max_request = 0xff;
1672 ec_dev->max_response = 0xee;
1673 ec_dev->max_passthru = 0xdd;
1674
1675 buf.msg.version = 0;
1676 buf.msg.command = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) + EC_CMD_HELLO;
1677 buf.msg.insize = 4;
1678 buf.msg.outsize = 0xdd + 1;
1679
1680 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1681 KUNIT_EXPECT_EQ(test, ret, -EMSGSIZE);
1682}
1683
1684static void cros_ec_proto_test_cmd_xfer_protocol_v3_normal(struct kunit *test)
1685{
1686 struct cros_ec_proto_test_priv *priv = test->priv;
1687 struct cros_ec_device *ec_dev = &priv->ec_dev;
1688 int ret;
1689 struct cros_ec_command msg;
1690
1691 memset(&msg, 0, sizeof(msg));
1692
1693 ec_dev->proto_version = 3;
1694 ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1695 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1696
1697 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1698 KUNIT_EXPECT_EQ(test, ret, 0);
1699
1700 KUNIT_EXPECT_EQ(test, cros_kunit_ec_cmd_xfer_mock_called, 0);
1701 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 1);
1702}
1703
1704static void cros_ec_proto_test_cmd_xfer_protocol_v3_no_op(struct kunit *test)
1705{
1706 struct cros_ec_proto_test_priv *priv = test->priv;
1707 struct cros_ec_device *ec_dev = &priv->ec_dev;
1708 int ret;
1709 struct cros_ec_command msg;
1710
1711 memset(&msg, 0, sizeof(msg));
1712
1713 ec_dev->proto_version = 3;
1714 ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1715 ec_dev->pkt_xfer = NULL;
1716
1717 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1718 KUNIT_EXPECT_EQ(test, ret, -EIO);
1719}
1720
1721static void cros_ec_proto_test_cmd_xfer_protocol_v2_normal(struct kunit *test)
1722{
1723 struct cros_ec_proto_test_priv *priv = test->priv;
1724 struct cros_ec_device *ec_dev = &priv->ec_dev;
1725 int ret;
1726 struct cros_ec_command msg;
1727
1728 memset(&msg, 0, sizeof(msg));
1729
1730 ec_dev->proto_version = 2;
1731 ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1732 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1733
1734 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1735 KUNIT_EXPECT_EQ(test, ret, 0);
1736
1737 KUNIT_EXPECT_EQ(test, cros_kunit_ec_cmd_xfer_mock_called, 1);
1738 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 0);
1739}
1740
1741static void cros_ec_proto_test_cmd_xfer_protocol_v2_no_op(struct kunit *test)
1742{
1743 struct cros_ec_proto_test_priv *priv = test->priv;
1744 struct cros_ec_device *ec_dev = &priv->ec_dev;
1745 int ret;
1746 struct cros_ec_command msg;
1747
1748 memset(&msg, 0, sizeof(msg));
1749
1750 ec_dev->proto_version = 2;
1751 ec_dev->cmd_xfer = NULL;
1752 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1753
1754 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1755 KUNIT_EXPECT_EQ(test, ret, -EIO);
1756}
1757
1758static void cros_ec_proto_test_cmd_xfer_in_progress_normal(struct kunit *test)
1759{
1760 struct cros_ec_proto_test_priv *priv = test->priv;
1761 struct cros_ec_device *ec_dev = &priv->ec_dev;
1762 struct ec_xfer_mock *mock;
1763 int ret;
1764 struct cros_ec_command msg;
1765
1766 memset(&msg, 0, sizeof(msg));
1767
1768 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1769
1770 /* For the first host command to return EC_RES_IN_PROGRESS. */
1771 {
1772 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1773 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1774 }
1775
1776 /* For EC_CMD_GET_COMMS_STATUS. */
1777 {
1778 struct ec_response_get_comms_status *data;
1779
1780 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1781 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1782
1783 data = (struct ec_response_get_comms_status *)mock->o_data;
1784 data->flags = 0;
1785 }
1786
1787 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1788 KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_comms_status));
1789
1790 KUNIT_EXPECT_EQ(test, msg.result, EC_RES_SUCCESS);
1791
1792 /* For the first host command to return EC_RES_IN_PROGRESS. */
1793 {
1794 mock = cros_kunit_ec_xfer_mock_next();
1795 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1796 }
1797
1798 /* For EC_CMD_GET_COMMS_STATUS. */
1799 {
1800 mock = cros_kunit_ec_xfer_mock_next();
1801 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1802
1803 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1804 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_COMMS_STATUS);
1805 KUNIT_EXPECT_EQ(test, mock->msg.insize,
1806 sizeof(struct ec_response_get_comms_status));
1807 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1808 }
1809
1810 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1811}
1812
1813static void cros_ec_proto_test_cmd_xfer_in_progress_retries_eagain(struct kunit *test)
1814{
1815 struct cros_ec_proto_test_priv *priv = test->priv;
1816 struct cros_ec_device *ec_dev = &priv->ec_dev;
1817 struct ec_xfer_mock *mock;
1818 int ret;
1819 struct cros_ec_command msg;
1820
1821 memset(&msg, 0, sizeof(msg));
1822
1823 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1824
1825 /* For the first host command to return EC_RES_IN_PROGRESS. */
1826 {
1827 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1828 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1829 }
1830
1831 /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1832 cros_kunit_ec_xfer_mock_default_ret = -EAGAIN;
1833
1834 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1835 KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
1836
1837 /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1838 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 51);
1839}
1840
1841static void cros_ec_proto_test_cmd_xfer_in_progress_retries_status_processing(struct kunit *test)
1842{
1843 struct cros_ec_proto_test_priv *priv = test->priv;
1844 struct cros_ec_device *ec_dev = &priv->ec_dev;
1845 struct ec_xfer_mock *mock;
1846 int ret;
1847 struct cros_ec_command msg;
1848
1849 memset(&msg, 0, sizeof(msg));
1850
1851 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1852
1853 /* For the first host command to return EC_RES_IN_PROGRESS. */
1854 {
1855 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1856 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1857 }
1858
1859 /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1860 {
1861 struct ec_response_get_comms_status *data;
1862 int i;
1863
1864 for (i = 0; i < 50; ++i) {
1865 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1866 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1867
1868 data = (struct ec_response_get_comms_status *)mock->o_data;
1869 data->flags |= EC_COMMS_STATUS_PROCESSING;
1870 }
1871 }
1872
1873 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1874 KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
1875
1876 /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1877 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 51);
1878}
1879
1880static void cros_ec_proto_test_cmd_xfer_in_progress_xfer_error(struct kunit *test)
1881{
1882 struct cros_ec_proto_test_priv *priv = test->priv;
1883 struct cros_ec_device *ec_dev = &priv->ec_dev;
1884 struct ec_xfer_mock *mock;
1885 int ret;
1886 struct cros_ec_command msg;
1887
1888 memset(&msg, 0, sizeof(msg));
1889
1890 /* For the first host command to return EC_RES_IN_PROGRESS. */
1891 {
1892 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1893 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1894 }
1895
1896 /* For EC_CMD_GET_COMMS_STATUS. */
1897 {
1898 mock = cros_kunit_ec_xfer_mock_addx(test, -EIO, EC_RES_SUCCESS, 0);
1899 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1900 }
1901
1902 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1903 KUNIT_EXPECT_EQ(test, ret, -EIO);
1904}
1905
1906static void cros_ec_proto_test_cmd_xfer_in_progress_return_error(struct kunit *test)
1907{
1908 struct cros_ec_proto_test_priv *priv = test->priv;
1909 struct cros_ec_device *ec_dev = &priv->ec_dev;
1910 struct ec_xfer_mock *mock;
1911 int ret;
1912 struct cros_ec_command msg;
1913
1914 memset(&msg, 0, sizeof(msg));
1915
1916 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1917
1918 /* For the first host command to return EC_RES_IN_PROGRESS. */
1919 {
1920 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1921 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1922 }
1923
1924 /* For EC_CMD_GET_COMMS_STATUS. */
1925 {
1926 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1927 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1928 }
1929
1930 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1931 KUNIT_EXPECT_EQ(test, ret, 0);
1932
1933 KUNIT_EXPECT_EQ(test, msg.result, EC_RES_INVALID_COMMAND);
1934
1935 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1936}
1937
1938static void cros_ec_proto_test_cmd_xfer_in_progress_return0(struct kunit *test)
1939{
1940 struct cros_ec_proto_test_priv *priv = test->priv;
1941 struct cros_ec_device *ec_dev = &priv->ec_dev;
1942 struct ec_xfer_mock *mock;
1943 int ret;
1944 struct cros_ec_command msg;
1945
1946 memset(&msg, 0, sizeof(msg));
1947
1948 ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1949
1950 /* For the first host command to return EC_RES_IN_PROGRESS. */
1951 {
1952 mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1953 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1954 }
1955
1956 /* For EC_CMD_GET_COMMS_STATUS. */
1957 {
1958 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1959 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1960 }
1961
1962 ret = cros_ec_cmd_xfer(ec_dev, &msg);
1963 KUNIT_EXPECT_EQ(test, ret, -EPROTO);
1964
1965 KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1966}
1967
1968static void cros_ec_proto_test_cmd_xfer_status_normal(struct kunit *test)
1969{
1970 struct cros_ec_proto_test_priv *priv = test->priv;
1971 struct cros_ec_device *ec_dev = &priv->ec_dev;
1972 struct ec_xfer_mock *mock;
1973 int ret;
1974 struct cros_ec_command msg;
1975
1976 memset(&msg, 0, sizeof(msg));
1977
1978 /* For cros_ec_cmd_xfer(). */
1979 {
1980 mock = cros_kunit_ec_xfer_mock_add(test, 0);
1981 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1982 }
1983
1984 ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
1985 KUNIT_EXPECT_EQ(test, ret, 0);
1986}
1987
1988static void cros_ec_proto_test_cmd_xfer_status_xfer_error(struct kunit *test)
1989{
1990 struct cros_ec_proto_test_priv *priv = test->priv;
1991 struct cros_ec_device *ec_dev = &priv->ec_dev;
1992 struct ec_xfer_mock *mock;
1993 int ret;
1994 struct cros_ec_command msg;
1995
1996 memset(&msg, 0, sizeof(msg));
1997
1998 /* For cros_ec_cmd_xfer(). */
1999 {
2000 mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2001 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2002 }
2003
2004 ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
2005 KUNIT_EXPECT_EQ(test, ret, -EPROTO);
2006}
2007
2008static void cros_ec_proto_test_cmd_xfer_status_return_error(struct kunit *test)
2009{
2010 struct cros_ec_proto_test_priv *priv = test->priv;
2011 struct cros_ec_device *ec_dev = &priv->ec_dev;
2012 struct ec_xfer_mock *mock;
2013 int ret, i;
2014 struct cros_ec_command msg;
2015 static const int map[] = {
2016 [EC_RES_SUCCESS] = 0,
2017 [EC_RES_INVALID_COMMAND] = -EOPNOTSUPP,
2018 [EC_RES_ERROR] = -EIO,
2019 [EC_RES_INVALID_PARAM] = -EINVAL,
2020 [EC_RES_ACCESS_DENIED] = -EACCES,
2021 [EC_RES_INVALID_RESPONSE] = -EPROTO,
2022 [EC_RES_INVALID_VERSION] = -ENOPROTOOPT,
2023 [EC_RES_INVALID_CHECKSUM] = -EBADMSG,
2024 /*
2025 * EC_RES_IN_PROGRESS is special because cros_ec_send_command() has extra logic to
2026 * handle it. Note that default cros_kunit_ec_xfer_mock_default_ret == 0 thus
2027 * cros_ec_xfer_command() in cros_ec_wait_until_complete() returns 0. As a result,
2028 * it returns -EPROTO without calling cros_ec_map_error().
2029 */
2030 [EC_RES_IN_PROGRESS] = -EPROTO,
2031 [EC_RES_UNAVAILABLE] = -ENODATA,
2032 [EC_RES_TIMEOUT] = -ETIMEDOUT,
2033 [EC_RES_OVERFLOW] = -EOVERFLOW,
2034 [EC_RES_INVALID_HEADER] = -EBADR,
2035 [EC_RES_REQUEST_TRUNCATED] = -EBADR,
2036 [EC_RES_RESPONSE_TOO_BIG] = -EFBIG,
2037 [EC_RES_BUS_ERROR] = -EFAULT,
2038 [EC_RES_BUSY] = -EBUSY,
2039 [EC_RES_INVALID_HEADER_VERSION] = -EBADMSG,
2040 [EC_RES_INVALID_HEADER_CRC] = -EBADMSG,
2041 [EC_RES_INVALID_DATA_CRC] = -EBADMSG,
2042 [EC_RES_DUP_UNAVAILABLE] = -ENODATA,
2043 };
2044
2045 memset(&msg, 0, sizeof(msg));
2046
2047 for (i = 0; i < ARRAY_SIZE(map); ++i) {
2048 mock = cros_kunit_ec_xfer_mock_addx(test, 0, i, 0);
2049 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2050
2051 ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
2052 KUNIT_EXPECT_EQ(test, ret, map[i]);
2053 }
2054}
2055
2056static void cros_ec_proto_test_get_next_event_no_mkbp_event(struct kunit *test)
2057{
2058 struct cros_ec_proto_test_priv *priv = test->priv;
2059 struct cros_ec_device *ec_dev = &priv->ec_dev;
2060 struct ec_xfer_mock *mock;
2061 int ret;
2062 bool wake_event, more_events;
2063
2064 ec_dev->max_request = 0xff;
2065 ec_dev->max_response = 0xee;
2066 ec_dev->mkbp_event_supported = 0;
2067
2068 /* Set some garbage bytes. */
2069 wake_event = false;
2070 more_events = true;
2071
2072 /* For get_keyboard_state_event(). */
2073 {
2074 union ec_response_get_next_data_v1 *data;
2075
2076 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2077 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2078
2079 data = (union ec_response_get_next_data_v1 *)mock->o_data;
2080 data->host_event = 0xbeef;
2081 }
2082
2083 ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2084 KUNIT_EXPECT_EQ(test, ret, sizeof(union ec_response_get_next_data_v1));
2085
2086 KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_KEY_MATRIX);
2087 KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.host_event, 0xbeef);
2088
2089 KUNIT_EXPECT_TRUE(test, wake_event);
2090 KUNIT_EXPECT_FALSE(test, more_events);
2091
2092 /* For get_keyboard_state_event(). */
2093 {
2094 mock = cros_kunit_ec_xfer_mock_next();
2095 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2096
2097 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2098 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MKBP_STATE);
2099 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(union ec_response_get_next_data_v1));
2100 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2101 }
2102}
2103
2104static void cros_ec_proto_test_get_next_event_mkbp_event_ec_suspended(struct kunit *test)
2105{
2106 struct cros_ec_proto_test_priv *priv = test->priv;
2107 struct cros_ec_device *ec_dev = &priv->ec_dev;
2108 int ret;
2109
2110 ec_dev->mkbp_event_supported = 1;
2111 ec_dev->suspended = true;
2112
2113 ret = cros_ec_get_next_event(ec_dev, NULL, NULL);
2114 KUNIT_EXPECT_EQ(test, ret, -EHOSTDOWN);
2115}
2116
2117static void cros_ec_proto_test_get_next_event_mkbp_event_version0(struct kunit *test)
2118{
2119 struct cros_ec_proto_test_priv *priv = test->priv;
2120 struct cros_ec_device *ec_dev = &priv->ec_dev;
2121 struct ec_xfer_mock *mock;
2122 int ret;
2123 bool wake_event, more_events;
2124
2125 ec_dev->max_request = 0xff;
2126 ec_dev->max_response = 0xee;
2127 ec_dev->mkbp_event_supported = 1;
2128
2129 /* Set some garbage bytes. */
2130 wake_event = true;
2131 more_events = false;
2132
2133 /* For get_next_event_xfer(). */
2134 {
2135 struct ec_response_get_next_event *data;
2136
2137 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2138 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2139
2140 data = (struct ec_response_get_next_event *)mock->o_data;
2141 data->event_type = EC_MKBP_EVENT_SENSOR_FIFO | EC_MKBP_HAS_MORE_EVENTS;
2142 data->data.sysrq = 0xbeef;
2143 }
2144
2145 ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2146 KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_next_event));
2147
2148 KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_SENSOR_FIFO);
2149 KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.sysrq, 0xbeef);
2150
2151 KUNIT_EXPECT_FALSE(test, wake_event);
2152 KUNIT_EXPECT_TRUE(test, more_events);
2153
2154 /* For get_next_event_xfer(). */
2155 {
2156 mock = cros_kunit_ec_xfer_mock_next();
2157 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2158
2159 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2160 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2161 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_get_next_event));
2162 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2163 }
2164}
2165
2166static void cros_ec_proto_test_get_next_event_mkbp_event_version2(struct kunit *test)
2167{
2168 struct cros_ec_proto_test_priv *priv = test->priv;
2169 struct cros_ec_device *ec_dev = &priv->ec_dev;
2170 struct ec_xfer_mock *mock;
2171 int ret;
2172 bool wake_event, more_events;
2173
2174 ec_dev->max_request = 0xff;
2175 ec_dev->max_response = 0xee;
2176 ec_dev->mkbp_event_supported = 3;
2177
2178 /* Set some garbage bytes. */
2179 wake_event = false;
2180 more_events = true;
2181
2182 /* For get_next_event_xfer(). */
2183 {
2184 struct ec_response_get_next_event_v1 *data;
2185
2186 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2187 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2188
2189 data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2190 data->event_type = EC_MKBP_EVENT_FINGERPRINT;
2191 data->data.sysrq = 0xbeef;
2192 }
2193
2194 ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2195 KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_next_event_v1));
2196
2197 KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_FINGERPRINT);
2198 KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.sysrq, 0xbeef);
2199
2200 KUNIT_EXPECT_TRUE(test, wake_event);
2201 KUNIT_EXPECT_FALSE(test, more_events);
2202
2203 /* For get_next_event_xfer(). */
2204 {
2205 mock = cros_kunit_ec_xfer_mock_next();
2206 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2207
2208 KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2209 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2210 KUNIT_EXPECT_EQ(test, mock->msg.insize,
2211 sizeof(struct ec_response_get_next_event_v1));
2212 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2213 }
2214}
2215
2216static void cros_ec_proto_test_get_next_event_mkbp_event_host_event_rtc(struct kunit *test)
2217{
2218 struct cros_ec_proto_test_priv *priv = test->priv;
2219 struct cros_ec_device *ec_dev = &priv->ec_dev;
2220 struct ec_xfer_mock *mock;
2221 int ret;
2222 bool wake_event;
2223 struct ec_response_get_next_event_v1 *data;
2224
2225 ec_dev->max_request = 0xff;
2226 ec_dev->max_response = 0xee;
2227 ec_dev->mkbp_event_supported = 3;
2228 ec_dev->host_event_wake_mask = U32_MAX;
2229
2230 /* Set some garbage bytes. */
2231 wake_event = true;
2232
2233 /* For get_next_event_xfer(). */
2234 {
2235 mock = cros_kunit_ec_xfer_mock_add(test,
2236 sizeof(data->event_type) +
2237 sizeof(data->data.host_event));
2238 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2239
2240 data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2241 data->event_type = EC_MKBP_EVENT_HOST_EVENT;
2242 put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC), &data->data.host_event);
2243 }
2244
2245 ret = cros_ec_get_next_event(ec_dev, &wake_event, NULL);
2246 KUNIT_EXPECT_EQ(test, ret, sizeof(data->event_type) + sizeof(data->data.host_event));
2247
2248 KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_HOST_EVENT);
2249
2250 KUNIT_EXPECT_FALSE(test, wake_event);
2251
2252 /* For get_next_event_xfer(). */
2253 {
2254 mock = cros_kunit_ec_xfer_mock_next();
2255 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2256
2257 KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2258 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2259 KUNIT_EXPECT_EQ(test, mock->msg.insize,
2260 sizeof(struct ec_response_get_next_event_v1));
2261 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2262 }
2263}
2264
2265static void cros_ec_proto_test_get_next_event_mkbp_event_host_event_masked(struct kunit *test)
2266{
2267 struct cros_ec_proto_test_priv *priv = test->priv;
2268 struct cros_ec_device *ec_dev = &priv->ec_dev;
2269 struct ec_xfer_mock *mock;
2270 int ret;
2271 bool wake_event;
2272 struct ec_response_get_next_event_v1 *data;
2273
2274 ec_dev->max_request = 0xff;
2275 ec_dev->max_response = 0xee;
2276 ec_dev->mkbp_event_supported = 3;
2277 ec_dev->host_event_wake_mask = U32_MAX & ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED);
2278
2279 /* Set some garbage bytes. */
2280 wake_event = true;
2281
2282 /* For get_next_event_xfer(). */
2283 {
2284 mock = cros_kunit_ec_xfer_mock_add(test,
2285 sizeof(data->event_type) +
2286 sizeof(data->data.host_event));
2287 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2288
2289 data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2290 data->event_type = EC_MKBP_EVENT_HOST_EVENT;
2291 put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED),
2292 &data->data.host_event);
2293 }
2294
2295 ret = cros_ec_get_next_event(ec_dev, &wake_event, NULL);
2296 KUNIT_EXPECT_EQ(test, ret, sizeof(data->event_type) + sizeof(data->data.host_event));
2297
2298 KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_HOST_EVENT);
2299
2300 KUNIT_EXPECT_FALSE(test, wake_event);
2301
2302 /* For get_next_event_xfer(). */
2303 {
2304 mock = cros_kunit_ec_xfer_mock_next();
2305 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2306
2307 KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2308 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2309 KUNIT_EXPECT_EQ(test, mock->msg.insize,
2310 sizeof(struct ec_response_get_next_event_v1));
2311 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2312 }
2313}
2314
2315static void cros_ec_proto_test_get_host_event_no_mkbp_event(struct kunit *test)
2316{
2317 struct cros_ec_proto_test_priv *priv = test->priv;
2318 struct cros_ec_device *ec_dev = &priv->ec_dev;
2319 int ret;
2320
2321 ec_dev->mkbp_event_supported = 0;
2322
2323 ret = cros_ec_get_host_event(ec_dev);
2324 KUNIT_EXPECT_EQ(test, ret, 0);
2325}
2326
2327static void cros_ec_proto_test_get_host_event_not_host_event(struct kunit *test)
2328{
2329 struct cros_ec_proto_test_priv *priv = test->priv;
2330 struct cros_ec_device *ec_dev = &priv->ec_dev;
2331 int ret;
2332
2333 ec_dev->mkbp_event_supported = 1;
2334 ec_dev->event_data.event_type = EC_MKBP_EVENT_FINGERPRINT;
2335
2336 ret = cros_ec_get_host_event(ec_dev);
2337 KUNIT_EXPECT_EQ(test, ret, 0);
2338}
2339
2340static void cros_ec_proto_test_get_host_event_wrong_event_size(struct kunit *test)
2341{
2342 struct cros_ec_proto_test_priv *priv = test->priv;
2343 struct cros_ec_device *ec_dev = &priv->ec_dev;
2344 int ret;
2345
2346 ec_dev->mkbp_event_supported = 1;
2347 ec_dev->event_data.event_type = EC_MKBP_EVENT_HOST_EVENT;
2348 ec_dev->event_size = 0xff;
2349
2350 ret = cros_ec_get_host_event(ec_dev);
2351 KUNIT_EXPECT_EQ(test, ret, 0);
2352}
2353
2354static void cros_ec_proto_test_get_host_event_normal(struct kunit *test)
2355{
2356 struct cros_ec_proto_test_priv *priv = test->priv;
2357 struct cros_ec_device *ec_dev = &priv->ec_dev;
2358 int ret;
2359
2360 ec_dev->mkbp_event_supported = 1;
2361 ec_dev->event_data.event_type = EC_MKBP_EVENT_HOST_EVENT;
2362 ec_dev->event_size = sizeof(ec_dev->event_data.data.host_event);
2363 put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC),
2364 &ec_dev->event_data.data.host_event);
2365
2366 ret = cros_ec_get_host_event(ec_dev);
2367 KUNIT_EXPECT_EQ(test, ret, EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC));
2368}
2369
2370static void cros_ec_proto_test_check_features_cached(struct kunit *test)
2371{
2372 int ret, i;
2373 struct cros_ec_dev ec;
2374
2375 ec.features.flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);
2376 ec.features.flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);
2377
2378 for (i = 0; i < EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK; ++i) {
2379 ret = cros_ec_check_features(&ec, i);
2380 switch (i) {
2381 case EC_FEATURE_FINGERPRINT:
2382 case EC_FEATURE_SCP:
2383 KUNIT_EXPECT_TRUE(test, ret);
2384 break;
2385 default:
2386 KUNIT_EXPECT_FALSE(test, ret);
2387 break;
2388 }
2389 }
2390}
2391
2392static void cros_ec_proto_test_check_features_not_cached(struct kunit *test)
2393{
2394 struct cros_ec_proto_test_priv *priv = test->priv;
2395 struct cros_ec_device *ec_dev = &priv->ec_dev;
2396 struct ec_xfer_mock *mock;
2397 int ret, i;
2398 struct cros_ec_dev ec;
2399
2400 ec_dev->max_request = 0xff;
2401 ec_dev->max_response = 0xee;
2402 ec.ec_dev = ec_dev;
2403 ec.dev = ec_dev->dev;
2404 ec.cmd_offset = 0;
2405 ec.features.flags[0] = -1;
2406 ec.features.flags[1] = -1;
2407
2408 /* For EC_CMD_GET_FEATURES. */
2409 {
2410 struct ec_response_get_features *data;
2411
2412 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2413 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2414
2415 data = (struct ec_response_get_features *)mock->o_data;
2416 data->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);
2417 data->flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);
2418 }
2419
2420 for (i = 0; i < EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK; ++i) {
2421 ret = cros_ec_check_features(&ec, i);
2422 switch (i) {
2423 case EC_FEATURE_FINGERPRINT:
2424 case EC_FEATURE_SCP:
2425 KUNIT_EXPECT_TRUE(test, ret);
2426 break;
2427 default:
2428 KUNIT_EXPECT_FALSE(test, ret);
2429 break;
2430 }
2431 }
2432
2433 /* For EC_CMD_GET_FEATURES. */
2434 {
2435 mock = cros_kunit_ec_xfer_mock_next();
2436 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2437
2438 KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2439 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_FEATURES);
2440 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_get_features));
2441 KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2442 }
2443}
2444
2445static void cros_ec_proto_test_get_sensor_count_normal(struct kunit *test)
2446{
2447 struct cros_ec_proto_test_priv *priv = test->priv;
2448 struct cros_ec_device *ec_dev = &priv->ec_dev;
2449 struct ec_xfer_mock *mock;
2450 int ret;
2451 struct cros_ec_dev ec;
2452
2453 ec_dev->max_request = 0xff;
2454 ec_dev->max_response = 0xee;
2455 ec.ec_dev = ec_dev;
2456 ec.dev = ec_dev->dev;
2457 ec.cmd_offset = 0;
2458
2459 /* For EC_CMD_MOTION_SENSE_CMD. */
2460 {
2461 struct ec_response_motion_sense *data;
2462
2463 mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2464 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2465
2466 data = (struct ec_response_motion_sense *)mock->o_data;
2467 data->dump.sensor_count = 0xbf;
2468 }
2469
2470 ret = cros_ec_get_sensor_count(&ec);
2471 KUNIT_EXPECT_EQ(test, ret, 0xbf);
2472
2473 /* For EC_CMD_MOTION_SENSE_CMD. */
2474 {
2475 struct ec_params_motion_sense *data;
2476
2477 mock = cros_kunit_ec_xfer_mock_next();
2478 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2479
2480 KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2481 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2482 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_motion_sense));
2483 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2484
2485 data = (struct ec_params_motion_sense *)mock->i_data;
2486 KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2487 }
2488}
2489
2490static void cros_ec_proto_test_get_sensor_count_xfer_error(struct kunit *test)
2491{
2492 struct cros_ec_proto_test_priv *priv = test->priv;
2493 struct cros_ec_device *ec_dev = &priv->ec_dev;
2494 struct ec_xfer_mock *mock;
2495 int ret;
2496 struct cros_ec_dev ec;
2497
2498 ec_dev->max_request = 0xff;
2499 ec_dev->max_response = 0xee;
2500 ec.ec_dev = ec_dev;
2501 ec.dev = ec_dev->dev;
2502 ec.cmd_offset = 0;
2503
2504 /* For EC_CMD_MOTION_SENSE_CMD. */
2505 {
2506 mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2507 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2508 }
2509
2510 ret = cros_ec_get_sensor_count(&ec);
2511 KUNIT_EXPECT_EQ(test, ret, -EPROTO);
2512
2513 /* For EC_CMD_MOTION_SENSE_CMD. */
2514 {
2515 struct ec_params_motion_sense *data;
2516
2517 mock = cros_kunit_ec_xfer_mock_next();
2518 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2519
2520 KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2521 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2522 KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_motion_sense));
2523 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2524
2525 data = (struct ec_params_motion_sense *)mock->i_data;
2526 KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2527 }
2528}
2529
2530static void cros_ec_proto_test_get_sensor_count_legacy(struct kunit *test)
2531{
2532 struct cros_ec_proto_test_priv *priv = test->priv;
2533 struct cros_ec_device *ec_dev = &priv->ec_dev;
2534 struct ec_xfer_mock *mock;
2535 int ret, i;
2536 struct cros_ec_dev ec;
2537 struct {
2538 u8 readmem_data;
2539 int expected_result;
2540 } test_data[] = {
2541 { 0, 0 },
2542 { EC_MEMMAP_ACC_STATUS_PRESENCE_BIT, 2 },
2543 };
2544
2545 ec_dev->max_request = 0xff;
2546 ec_dev->max_response = 0xee;
2547 ec_dev->cmd_readmem = cros_kunit_readmem_mock;
2548 ec.ec_dev = ec_dev;
2549 ec.dev = ec_dev->dev;
2550 ec.cmd_offset = 0;
2551
2552 for (i = 0; i < ARRAY_SIZE(test_data); ++i) {
2553 /* For EC_CMD_MOTION_SENSE_CMD. */
2554 {
2555 mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2556 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2557 }
2558
2559 /* For readmem. */
2560 {
2561 cros_kunit_readmem_mock_data = kunit_kzalloc(test, 1, GFP_KERNEL);
2562 KUNIT_ASSERT_PTR_NE(test, cros_kunit_readmem_mock_data, NULL);
2563 cros_kunit_readmem_mock_data[0] = test_data[i].readmem_data;
2564
2565 cros_kunit_ec_xfer_mock_default_ret = 1;
2566 }
2567
2568 ret = cros_ec_get_sensor_count(&ec);
2569 KUNIT_EXPECT_EQ(test, ret, test_data[i].expected_result);
2570
2571 /* For EC_CMD_MOTION_SENSE_CMD. */
2572 {
2573 struct ec_params_motion_sense *data;
2574
2575 mock = cros_kunit_ec_xfer_mock_next();
2576 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2577
2578 KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2579 KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2580 KUNIT_EXPECT_EQ(test, mock->msg.insize,
2581 sizeof(struct ec_response_motion_sense));
2582 KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2583
2584 data = (struct ec_params_motion_sense *)mock->i_data;
2585 KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2586 }
2587
2588 /* For readmem. */
2589 {
2590 KUNIT_EXPECT_EQ(test, cros_kunit_readmem_mock_offset, EC_MEMMAP_ACC_STATUS);
2591 }
2592 }
2593}
2594
2595static void cros_ec_proto_test_ec_cmd(struct kunit *test)
2596{
2597 struct cros_ec_proto_test_priv *priv = test->priv;
2598 struct cros_ec_device *ec_dev = &priv->ec_dev;
2599 struct ec_xfer_mock *mock;
2600 int ret;
2601 u8 out[3], in[2];
2602
2603 ec_dev->max_request = 0xff;
2604 ec_dev->max_response = 0xee;
2605
2606 out[0] = 0xdd;
2607 out[1] = 0xcc;
2608 out[2] = 0xbb;
2609
2610 {
2611 u8 *data;
2612
2613 mock = cros_kunit_ec_xfer_mock_add(test, 2);
2614 KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2615
2616 data = (u8 *)mock->o_data;
2617 data[0] = 0xaa;
2618 data[1] = 0x99;
2619 }
2620
2621 ret = cros_ec_cmd(ec_dev, 0x88, 0x77, out, ARRAY_SIZE(out), in, ARRAY_SIZE(in));
2622 KUNIT_EXPECT_EQ(test, ret, 2);
2623
2624 {
2625 u8 *data;
2626
2627 mock = cros_kunit_ec_xfer_mock_next();
2628 KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2629
2630 KUNIT_EXPECT_EQ(test, mock->msg.version, 0x88);
2631 KUNIT_EXPECT_EQ(test, mock->msg.command, 0x77);
2632 KUNIT_EXPECT_EQ(test, mock->msg.insize, ARRAY_SIZE(in));
2633 KUNIT_EXPECT_EQ(test, mock->msg.outsize, ARRAY_SIZE(out));
2634
2635 data = (u8 *)mock->i_data;
2636 KUNIT_EXPECT_EQ(test, data[0], 0xdd);
2637 KUNIT_EXPECT_EQ(test, data[1], 0xcc);
2638 KUNIT_EXPECT_EQ(test, data[2], 0xbb);
2639 }
2640}
2641
2642static void cros_ec_proto_test_release(struct device *dev)
2643{
2644}
2645
2646static int cros_ec_proto_test_init(struct kunit *test)
2647{
2648 struct cros_ec_proto_test_priv *priv;
2649 struct cros_ec_device *ec_dev;
2650
2651 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2652 if (!priv)
2653 return -ENOMEM;
2654 test->priv = priv;
2655
2656 ec_dev = &priv->ec_dev;
2657 ec_dev->dout = (u8 *)priv->dout;
2658 ec_dev->dout_size = ARRAY_SIZE(priv->dout);
2659 ec_dev->din = (u8 *)priv->din;
2660 ec_dev->din_size = ARRAY_SIZE(priv->din);
2661 ec_dev->proto_version = EC_HOST_REQUEST_VERSION;
2662 ec_dev->dev = kunit_kzalloc(test, sizeof(*ec_dev->dev), GFP_KERNEL);
2663 if (!ec_dev->dev)
2664 return -ENOMEM;
2665 device_initialize(ec_dev->dev);
2666 dev_set_name(ec_dev->dev, "cros_ec_proto_test");
2667 ec_dev->dev->release = cros_ec_proto_test_release;
2668 ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock;
2669 ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock;
2670
2671 priv->msg = (struct cros_ec_command *)priv->_msg;
2672
2673 cros_kunit_mock_reset();
2674
2675 return 0;
2676}
2677
2678static void cros_ec_proto_test_exit(struct kunit *test)
2679{
2680 struct cros_ec_proto_test_priv *priv = test->priv;
2681 struct cros_ec_device *ec_dev = &priv->ec_dev;
2682
2683 put_device(ec_dev->dev);
2684}
2685
2686static struct kunit_case cros_ec_proto_test_cases[] = {
2687 KUNIT_CASE(cros_ec_proto_test_prepare_tx_legacy_normal),
2688 KUNIT_CASE(cros_ec_proto_test_prepare_tx_legacy_bad_msg_outsize),
2689 KUNIT_CASE(cros_ec_proto_test_prepare_tx_normal),
2690 KUNIT_CASE(cros_ec_proto_test_prepare_tx_bad_msg_outsize),
2691 KUNIT_CASE(cros_ec_proto_test_check_result),
2692 KUNIT_CASE(cros_ec_proto_test_query_all_normal),
2693 KUNIT_CASE(cros_ec_proto_test_query_all_no_pd_return_error),
2694 KUNIT_CASE(cros_ec_proto_test_query_all_no_pd_return0),
2695 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_normal_v3_return_error),
2696 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_normal_v3_return0),
2697 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_xfer_error),
2698 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_return_error),
2699 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_data_error),
2700 KUNIT_CASE(cros_ec_proto_test_query_all_legacy_return0),
2701 KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp),
2702 KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp_return_error),
2703 KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp_return0),
2704 KUNIT_CASE(cros_ec_proto_test_query_all_no_host_sleep),
2705 KUNIT_CASE(cros_ec_proto_test_query_all_no_host_sleep_return0),
2706 KUNIT_CASE(cros_ec_proto_test_query_all_default_wake_mask_return_error),
2707 KUNIT_CASE(cros_ec_proto_test_query_all_default_wake_mask_return0),
2708 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_normal),
2709 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_insize),
2710 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_outsize_without_passthru),
2711 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_outsize_with_passthru),
2712 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v3_normal),
2713 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v3_no_op),
2714 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v2_normal),
2715 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v2_no_op),
2716 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_normal),
2717 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_retries_eagain),
2718 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_retries_status_processing),
2719 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_xfer_error),
2720 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_return_error),
2721 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_return0),
2722 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_normal),
2723 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_xfer_error),
2724 KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_return_error),
2725 KUNIT_CASE(cros_ec_proto_test_get_next_event_no_mkbp_event),
2726 KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_ec_suspended),
2727 KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_version0),
2728 KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_version2),
2729 KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_host_event_rtc),
2730 KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_host_event_masked),
2731 KUNIT_CASE(cros_ec_proto_test_get_host_event_no_mkbp_event),
2732 KUNIT_CASE(cros_ec_proto_test_get_host_event_not_host_event),
2733 KUNIT_CASE(cros_ec_proto_test_get_host_event_wrong_event_size),
2734 KUNIT_CASE(cros_ec_proto_test_get_host_event_normal),
2735 KUNIT_CASE(cros_ec_proto_test_check_features_cached),
2736 KUNIT_CASE(cros_ec_proto_test_check_features_not_cached),
2737 KUNIT_CASE(cros_ec_proto_test_get_sensor_count_normal),
2738 KUNIT_CASE(cros_ec_proto_test_get_sensor_count_xfer_error),
2739 KUNIT_CASE(cros_ec_proto_test_get_sensor_count_legacy),
2740 KUNIT_CASE(cros_ec_proto_test_ec_cmd),
2741 {}
2742};
2743
2744static struct kunit_suite cros_ec_proto_test_suite = {
2745 .name = "cros_ec_proto_test",
2746 .init = cros_ec_proto_test_init,
2747 .exit = cros_ec_proto_test_exit,
2748 .test_cases = cros_ec_proto_test_cases,
2749};
2750
2751kunit_test_suite(cros_ec_proto_test_suite);
2752
2753MODULE_LICENSE("GPL");
drivers/platform/chrome/cros_ec_trace.h+4−4
@@ -30,8 +30,8 @@ TRACE_EVENT(cros_ec_request_start, · 29 unmodified lines
30 ),30 ),
31 TP_fast_assign(31 TP_fast_assign(
32 __entry->version = cmd->version;32 __entry->version = cmd->version;
33 __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1);33 __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
34 __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1);34 __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
35 __entry->outsize = cmd->outsize;35 __entry->outsize = cmd->outsize;
36 __entry->insize = cmd->insize;36 __entry->insize = cmd->insize;
37 ),37 ),
@@ -55,8 +55,8 @@ TRACE_EVENT(cros_ec_request_done, · 17 unmodified lines
55 ),55 ),
56 TP_fast_assign(56 TP_fast_assign(
57 __entry->version = cmd->version;57 __entry->version = cmd->version;
58 __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1);58 __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
59 __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1);59 __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
60 __entry->outsize = cmd->outsize;60 __entry->outsize = cmd->outsize;
61 __entry->insize = cmd->insize;61 __entry->insize = cmd->insize;
62 __entry->result = cmd->result;62 __entry->result = cmd->result;
drivers/platform/chrome/cros_ec_typec.c+60−33
@@ -25,6 +25,8 @@ · 24 unmodified lines
25 25
26#define DRV_NAME "cros-ec-typec"26#define DRV_NAME "cros-ec-typec"
27 27
28#define DP_PORT_VDO (BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
29
28/* Supported alt modes. */30/* Supported alt modes. */
29enum {31enum {
30 CROS_EC_ALTMODE_DP = 0,32 CROS_EC_ALTMODE_DP = 0,
@@ -60,8 +62,7 @@ struct cros_typec_port { · 29 unmodified lines
60 uint8_t mux_flags;62 uint8_t mux_flags;
61 uint8_t role;63 uint8_t role;
62 64
63 /* Port alt modes. */65 struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
64 struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
65 66
66 /* Flag indicating that PD partner discovery data parsing is completed. */67 /* Flag indicating that PD partner discovery data parsing is completed. */
67 bool sop_disc_done;68 bool sop_disc_done;
@@ -254,6 +255,14 @@ static void cros_typec_remove_cable(struct cros_typec_data *typec, · 186 unmodified lines
254 port->sop_prime_disc_done = false;255 port->sop_prime_disc_done = false;
255}256}
256 257
258static void cros_typec_unregister_port_altmodes(struct cros_typec_port *port)
259{
260 int i;
261
262 for (i = 0; i < CROS_EC_ALTMODE_MAX; i++)
263 typec_unregister_altmode(port->port_altmode[i]);
264}
265
257static void cros_unregister_ports(struct cros_typec_data *typec)266static void cros_unregister_ports(struct cros_typec_data *typec)
258{267{
259 int i;268 int i;
@@ -268,34 +277,49 @@ static void cros_unregister_ports(struct cros_typec_data *typec) · 8 unmodified lines
268 usb_role_switch_put(typec->ports[i]->role_sw);277 usb_role_switch_put(typec->ports[i]->role_sw);
269 typec_switch_put(typec->ports[i]->ori_sw);278 typec_switch_put(typec->ports[i]->ori_sw);
270 typec_mux_put(typec->ports[i]->mux);279 typec_mux_put(typec->ports[i]->mux);
280 cros_typec_unregister_port_altmodes(typec->ports[i]);
271 typec_unregister_port(typec->ports[i]->port);281 typec_unregister_port(typec->ports[i]->port);
272 }282 }
273}283}
274 284
275/*285/*
276 * Fake the alt mode structs until we actually start registering Type C port286 * Register port alt modes with known values till we start retrieving
277 * and partner alt modes.287 * port capabilities from the EC.
278 */288 */
279static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,289static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
280 int port_num)290 int port_num)
281{291{
282 struct cros_typec_port *port = typec->ports[port_num];292 struct cros_typec_port *port = typec->ports[port_num];
293 struct typec_altmode_desc desc;
294 struct typec_altmode *amode;
283 295
284 /* All PD capable CrOS devices are assumed to support DP altmode. */296 /* All PD capable CrOS devices are assumed to support DP altmode. */
285 port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;297 desc.svid = USB_TYPEC_DP_SID,
286 port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;298 desc.mode = USB_TYPEC_DP_MODE,
299 desc.vdo = DP_PORT_VDO,
300 amode = typec_port_register_altmode(port->port, &desc);
301 if (IS_ERR(amode))
302 return PTR_ERR(amode);
303 port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
287 304
288 /*305 /*
289 * Register TBT compatibility alt mode. The EC will not enter the mode306 * Register TBT compatibility alt mode. The EC will not enter the mode
290 * if it doesn't support it, so it's safe to register it unconditionally307 * if it doesn't support it, so it's safe to register it unconditionally
291 * here for now.308 * here for now.
292 */309 */
293 port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;310 memset(&desc, 0, sizeof(desc));
294 port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;311 desc.svid = USB_TYPEC_TBT_SID,
312 desc.mode = TYPEC_ANY_MODE,
313 amode = typec_port_register_altmode(port->port, &desc);
314 if (IS_ERR(amode))
315 return PTR_ERR(amode);
316 port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
295 317
296 port->state.alt = NULL;318 port->state.alt = NULL;
297 port->state.mode = TYPEC_STATE_USB;319 port->state.mode = TYPEC_STATE_USB;
298 port->state.data = NULL;320 port->state.data = NULL;
321
322 return 0;
299}323}
300 324
301static int cros_typec_init_ports(struct cros_typec_data *typec)325static int cros_typec_init_ports(struct cros_typec_data *typec)
@@ -352,8 +376,8 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 50 unmodified lines
352 376
353 cros_port->port = typec_register_port(dev, cap);377 cros_port->port = typec_register_port(dev, cap);
354 if (IS_ERR(cros_port->port)) {378 if (IS_ERR(cros_port->port)) {
355 dev_err(dev, "Failed to register port %d\n", port_num);
356 ret = PTR_ERR(cros_port->port);379 ret = PTR_ERR(cros_port->port);
380 dev_err_probe(dev, ret, "Failed to register port %d\n", port_num);
357 goto unregister_ports;381 goto unregister_ports;
358 }382 }
359 383
@@ -362,7 +386,11 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 2 unmodified lines
362 dev_dbg(dev, "No switch control for port %d\n",386 dev_dbg(dev, "No switch control for port %d\n",
363 port_num);387 port_num);
364 388
365 cros_typec_register_port_altmodes(typec, port_num);389 ret = cros_typec_register_port_altmodes(typec, port_num);
390 if (ret) {
391 dev_err(dev, "Failed to register port altmodes\n");
392 goto unregister_ports;
393 }
366 394
367 cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);395 cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
368 if (!cros_port->disc_data) {396 if (!cros_port->disc_data) {
@@ -431,7 +459,7 @@ static int cros_typec_enable_tbt(struct cros_typec_data *typec, · 62 unmodified lines
431 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;459 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
432 460
433 if (!port->state.alt) {461 if (!port->state.alt) {
434 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];462 port->state.alt = port->port_altmode[CROS_EC_ALTMODE_TBT];
435 ret = cros_typec_usb_safe_state(port);463 ret = cros_typec_usb_safe_state(port);
436 if (ret)464 if (ret)
437 return ret;465 return ret;
@@ -473,7 +501,7 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec, · 35 unmodified lines
473 /* Configuration VDO. */501 /* Configuration VDO. */
474 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);502 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
475 if (!port->state.alt) {503 if (!port->state.alt) {
476 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];504 port->state.alt = port->port_altmode[CROS_EC_ALTMODE_DP];
477 ret = cros_typec_usb_safe_state(port);505 ret = cros_typec_usb_safe_state(port);
478 if (ret)506 if (ret)
479 return ret;507 return ret;
@@ -525,8 +553,8 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, · 45 unmodified lines
525 enum typec_orientation orientation;553 enum typec_orientation orientation;
526 int ret;554 int ret;
527 555
528 ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,556 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
529 &req, sizeof(req), &resp, sizeof(resp));557 &req, sizeof(req), &resp, sizeof(resp));
530 if (ret < 0) {558 if (ret < 0) {
531 dev_warn(typec->dev, "Failed to get mux info for port: %d, err = %d\n",559 dev_warn(typec->dev, "Failed to get mux info for port: %d, err = %d\n",
532 port_num, ret);560 port_num, ret);
@@ -585,8 +613,8 @@ mux_ack: · 52 unmodified lines
585 /* Sending Acknowledgment to EC */613 /* Sending Acknowledgment to EC */
586 mux_ack.port = port_num;614 mux_ack.port = port_num;
587 615
588 if (cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,616 if (cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
589 sizeof(mux_ack), NULL, 0) < 0)617 sizeof(mux_ack), NULL, 0) < 0)
590 dev_warn(typec->dev,618 dev_warn(typec->dev,
591 "Failed to send Mux ACK to EC for port: %d\n",619 "Failed to send Mux ACK to EC for port: %d\n",
592 port_num);620 port_num);
@@ -754,8 +782,8 @@ static int cros_typec_handle_sop_prime_disc(struct cros_typec_data *typec, int p · 161 unmodified lines
754 int ret = 0;782 int ret = 0;
755 783
756 memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);784 memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
757 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),785 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
758 disc, EC_PROTO2_MAX_RESPONSE_SIZE);786 disc, EC_PROTO2_MAX_RESPONSE_SIZE);
759 if (ret < 0) {787 if (ret < 0) {
760 dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num);788 dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num);
761 goto sop_prime_disc_exit;789 goto sop_prime_disc_exit;
@@ -837,8 +865,8 @@ static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_nu · 75 unmodified lines
837 typec_partner_set_pd_revision(port->partner, pd_revision);865 typec_partner_set_pd_revision(port->partner, pd_revision);
838 866
839 memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);867 memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
840 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),868 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
841 sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);869 sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
842 if (ret < 0) {870 if (ret < 0) {
843 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);871 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
844 goto disc_exit;872 goto disc_exit;
@@ -870,8 +898,8 @@ static int cros_typec_send_clear_event(struct cros_typec_data *typec, int port_n · 25 unmodified lines
870 .clear_events_mask = events_mask,898 .clear_events_mask = events_mask,
871 };899 };
872 900
873 return cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,901 return cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
874 sizeof(req), NULL, 0);902 sizeof(req), NULL, 0);
875}903}
876 904
877static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)905static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
@@ -882,8 +910,8 @@ static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num · 4 unmodified lines
882 };910 };
883 int ret;911 int ret;
884 912
885 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),913 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
886 &resp, sizeof(resp));914 &resp, sizeof(resp));
887 if (ret < 0) {915 if (ret < 0) {
888 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);916 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
889 return;917 return;
@@ -960,9 +988,9 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) · 70 unmodified lines
960 req.mux = USB_PD_CTRL_MUX_NO_CHANGE;988 req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
961 req.swap = USB_PD_CTRL_SWAP_NONE;989 req.swap = USB_PD_CTRL_SWAP_NONE;
962 990
963 ret = cros_ec_command(typec->ec, typec->pd_ctrl_ver,991 ret = cros_ec_cmd(typec->ec, typec->pd_ctrl_ver,
964 EC_CMD_USB_PD_CONTROL, &req, sizeof(req),992 EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
965 &resp, sizeof(resp));993 &resp, sizeof(resp));
966 if (ret < 0)994 if (ret < 0)
967 return ret;995 return ret;
968 996
@@ -997,9 +1025,8 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec) · 28 unmodified lines
997 1025
998 /* We're interested in the PD control command version. */1026 /* We're interested in the PD control command version. */
999 req_v1.cmd = EC_CMD_USB_PD_CONTROL;1027 req_v1.cmd = EC_CMD_USB_PD_CONTROL;
1000 ret = cros_ec_command(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,1028 ret = cros_ec_cmd(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,
1001 &req_v1, sizeof(req_v1), &resp,1029 &req_v1, sizeof(req_v1), &resp, sizeof(resp));
1002 sizeof(resp));
1003 if (ret < 0)1030 if (ret < 0)
1004 return ret;1031 return ret;
1005 1032
@@ -1090,8 +1117,8 @@ static int cros_typec_probe(struct platform_device *pdev) · 84 unmodified lines
1090 typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD);1117 typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD);
1091 typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK);1118 typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK);
1092 1119
1093 ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,1120 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
1094 &resp, sizeof(resp));1121 &resp, sizeof(resp));
1095 if (ret < 0)1122 if (ret < 0)
1096 return ret;1123 return ret;
1097 1124
drivers/platform/chrome/cros_kbd_led_backlight.c+174−22
@@ -4,24 +4,60 @@ · 3 unmodified lines
4// Copyright (C) 2012 Google, Inc.4// Copyright (C) 2012 Google, Inc.
5 5
6#include <linux/acpi.h>6#include <linux/acpi.h>
7#include <linux/leds.h>
8#include <linux/delay.h>7#include <linux/delay.h>
9#include <linux/err.h>8#include <linux/err.h>
10#include <linux/module.h>
11#include <linux/init.h>9#include <linux/init.h>
12#include <linux/kernel.h>10#include <linux/kernel.h>
11#include <linux/leds.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/platform_data/cros_ec_commands.h>
15#include <linux/platform_data/cros_ec_proto.h>
13#include <linux/platform_device.h>16#include <linux/platform_device.h>
17#include <linux/property.h>
14#include <linux/slab.h>18#include <linux/slab.h>
15 19
20struct keyboard_led {
21 struct led_classdev cdev;
22 struct cros_ec_device *ec;
23};
24
25/**
26 * struct keyboard_led_drvdata - keyboard LED driver data.
27 * @init: Init function.
28 * @brightness_get: Get LED brightness level.
29 * @brightness_set: Set LED brightness level. Must not sleep.
30 * @brightness_set_blocking: Set LED brightness level. It can block the
31 * caller for the time required for accessing a
32 * LED device register
33 * @max_brightness: Maximum brightness.
34 *
35 * See struct led_classdev in include/linux/leds.h for more details.
36 */
37struct keyboard_led_drvdata {
38 int (*init)(struct platform_device *pdev);
39
40 enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
41
42 void (*brightness_set)(struct led_classdev *led_cdev,
43 enum led_brightness brightness);
44 int (*brightness_set_blocking)(struct led_classdev *led_cdev,
45 enum led_brightness brightness);
46
47 enum led_brightness max_brightness;
48};
49
50#define KEYBOARD_BACKLIGHT_MAX 100
51
52#ifdef CONFIG_ACPI
53
16/* Keyboard LED ACPI Device must be defined in firmware */54/* Keyboard LED ACPI Device must be defined in firmware */
17#define ACPI_KEYBOARD_BACKLIGHT_DEVICE "\\_SB.KBLT"55#define ACPI_KEYBOARD_BACKLIGHT_DEVICE "\\_SB.KBLT"
18#define ACPI_KEYBOARD_BACKLIGHT_READ ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC"56#define ACPI_KEYBOARD_BACKLIGHT_READ ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC"
19#define ACPI_KEYBOARD_BACKLIGHT_WRITE ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM"57#define ACPI_KEYBOARD_BACKLIGHT_WRITE ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM"
20 58
21#define ACPI_KEYBOARD_BACKLIGHT_MAX 10059static void keyboard_led_set_brightness_acpi(struct led_classdev *cdev,
22 60 enum led_brightness brightness)
23static void keyboard_led_set_brightness(struct led_classdev *cdev,
24 enum led_brightness brightness)
25{61{
26 union acpi_object param;62 union acpi_object param;
27 struct acpi_object_list input;63 struct acpi_object_list input;
@@ -40,7 +76,7 @@ static void keyboard_led_set_brightness(struct led_classdev *cdev, · 12 unmodified lines
40}76}
41 77
42static enum led_brightness78static enum led_brightness
43keyboard_led_get_brightness(struct led_classdev *cdev)79keyboard_led_get_brightness_acpi(struct led_classdev *cdev)
44{80{
45 unsigned long long brightness;81 unsigned long long brightness;
46 acpi_status status;82 acpi_status status;
@@ -56,12 +92,10 @@ keyboard_led_get_brightness(struct led_classdev *cdev) · 9 unmodified lines
56 return brightness;92 return brightness;
57}93}
58 94
59static int keyboard_led_probe(struct platform_device *pdev)95static int keyboard_led_init_acpi(struct platform_device *pdev)
60{96{
61 struct led_classdev *cdev;
62 acpi_handle handle;97 acpi_handle handle;
63 acpi_status status;98 acpi_status status;
64 int error;
65 99
66 /* Look for the keyboard LED ACPI Device */100 /* Look for the keyboard LED ACPI Device */
67 status = acpi_get_handle(ACPI_ROOT_OBJECT,101 status = acpi_get_handle(ACPI_ROOT_OBJECT,
@@ -73,33 +107,151 @@ static int keyboard_led_probe(struct platform_device *pdev) · 5 unmodified lines
73 return -ENXIO;107 return -ENXIO;
74 }108 }
75 109
76 cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL);110 return 0;
77 if (!cdev)111}
112
113static const struct keyboard_led_drvdata keyboard_led_drvdata_acpi = {
114 .init = keyboard_led_init_acpi,
115 .brightness_set = keyboard_led_set_brightness_acpi,
116 .brightness_get = keyboard_led_get_brightness_acpi,
117 .max_brightness = KEYBOARD_BACKLIGHT_MAX,
118};
119
120#endif /* CONFIG_ACPI */
121
122#if IS_ENABLED(CONFIG_CROS_EC)
123
124static int
125keyboard_led_set_brightness_ec_pwm(struct led_classdev *cdev,
126 enum led_brightness brightness)
127{
128 struct {
129 struct cros_ec_command msg;
130 struct ec_params_pwm_set_keyboard_backlight params;
131 } __packed buf;
132 struct ec_params_pwm_set_keyboard_backlight *params = &buf.params;
133 struct cros_ec_command *msg = &buf.msg;
134 struct keyboard_led *keyboard_led = container_of(cdev, struct keyboard_led, cdev);
135
136 memset(&buf, 0, sizeof(buf));
137
138 msg->command = EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT;
139 msg->outsize = sizeof(*params);
140
141 params->percent = brightness;
142
143 return cros_ec_cmd_xfer_status(keyboard_led->ec, msg);
144}
145
146static enum led_brightness
147keyboard_led_get_brightness_ec_pwm(struct led_classdev *cdev)
148{
149 struct {
150 struct cros_ec_command msg;
151 struct ec_response_pwm_get_keyboard_backlight resp;
152 } __packed buf;
153 struct ec_response_pwm_get_keyboard_backlight *resp = &buf.resp;
154 struct cros_ec_command *msg = &buf.msg;
155 struct keyboard_led *keyboard_led = container_of(cdev, struct keyboard_led, cdev);
156 int ret;
157
158 memset(&buf, 0, sizeof(buf));
159
160 msg->command = EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT;
161 msg->insize = sizeof(*resp);
162
163 ret = cros_ec_cmd_xfer_status(keyboard_led->ec, msg);
164 if (ret < 0)
165 return ret;
166
167 return resp->percent;
168}
169
170static int keyboard_led_init_ec_pwm(struct platform_device *pdev)
171{
172 struct keyboard_led *keyboard_led = platform_get_drvdata(pdev);
173
174 keyboard_led->ec = dev_get_drvdata(pdev->dev.parent);
175 if (!keyboard_led->ec) {
176 dev_err(&pdev->dev, "no parent EC device\n");
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static const __maybe_unused struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm = {
184 .init = keyboard_led_init_ec_pwm,
185 .brightness_set_blocking = keyboard_led_set_brightness_ec_pwm,
186 .brightness_get = keyboard_led_get_brightness_ec_pwm,
187 .max_brightness = KEYBOARD_BACKLIGHT_MAX,
188};
189
190#else /* IS_ENABLED(CONFIG_CROS_EC) */
191
192static const __maybe_unused struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm = {};
193
194#endif /* IS_ENABLED(CONFIG_CROS_EC) */
195
196static int keyboard_led_probe(struct platform_device *pdev)
197{
198 const struct keyboard_led_drvdata *drvdata;
199 struct keyboard_led *keyboard_led;
200 int error;
201
202 drvdata = device_get_match_data(&pdev->dev);
203 if (!drvdata)
204 return -EINVAL;
205
206 keyboard_led = devm_kzalloc(&pdev->dev, sizeof(*keyboard_led), GFP_KERNEL);
207 if (!keyboard_led)
78 return -ENOMEM;208 return -ENOMEM;
209 platform_set_drvdata(pdev, keyboard_led);
210
211 if (drvdata->init) {
212 error = drvdata->init(pdev);
213 if (error)
214 return error;
215 }
79 216
80 cdev->name = "chromeos::kbd_backlight";217 keyboard_led->cdev.name = "chromeos::kbd_backlight";
81 cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX;218 keyboard_led->cdev.flags |= LED_CORE_SUSPENDRESUME;
82 cdev->flags |= LED_CORE_SUSPENDRESUME;219 keyboard_led->cdev.max_brightness = drvdata->max_brightness;
83 cdev->brightness_set = keyboard_led_set_brightness;220 keyboard_led->cdev.brightness_set = drvdata->brightness_set;
84 cdev->brightness_get = keyboard_led_get_brightness;221 keyboard_led->cdev.brightness_set_blocking = drvdata->brightness_set_blocking;
222 keyboard_led->cdev.brightness_get = drvdata->brightness_get;
85 223
86 error = devm_led_classdev_register(&pdev->dev, cdev);224 error = devm_led_classdev_register(&pdev->dev, &keyboard_led->cdev);
87 if (error)225 if (error)
88 return error;226 return error;
89 227
90 return 0;228 return 0;
91}229}
92 230
93static const struct acpi_device_id keyboard_led_id[] = {231#ifdef CONFIG_ACPI
94 { "GOOG0002", 0 },232static const struct acpi_device_id keyboard_led_acpi_match[] = {
233 { "GOOG0002", (kernel_ulong_t)&keyboard_led_drvdata_acpi },
95 { }234 { }
96};235};
97MODULE_DEVICE_TABLE(acpi, keyboard_led_id);236MODULE_DEVICE_TABLE(acpi, keyboard_led_acpi_match);
237#endif
238
239#ifdef CONFIG_OF
240static const struct of_device_id keyboard_led_of_match[] = {
241 {
242 .compatible = "google,cros-kbd-led-backlight",
243 .data = &keyboard_led_drvdata_ec_pwm,
244 },
245 {}
246};
247MODULE_DEVICE_TABLE(of, keyboard_led_of_match);
248#endif
98 249
99static struct platform_driver keyboard_led_driver = {250static struct platform_driver keyboard_led_driver = {
100 .driver = {251 .driver = {
101 .name = "chromeos-keyboard-leds",252 .name = "chromeos-keyboard-leds",
102 .acpi_match_table = ACPI_PTR(keyboard_led_id),253 .acpi_match_table = ACPI_PTR(keyboard_led_acpi_match),
254 .of_match_table = of_match_ptr(keyboard_led_of_match),
103 },255 },
104 .probe = keyboard_led_probe,256 .probe = keyboard_led_probe,
105};257};
drivers/platform/chrome/cros_kunit_util.c+130−0
@@ -0,0 +1,130 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * CrOS Kunit tests utilities.
4 */
5
6#include <kunit/test.h>
7
8#include <linux/list.h>
9#include <linux/minmax.h>
10#include <linux/platform_data/cros_ec_commands.h>
11#include <linux/platform_data/cros_ec_proto.h>
12
13#include "cros_ec.h"
14#include "cros_kunit_util.h"
15
16int cros_kunit_ec_xfer_mock_default_result;
17int cros_kunit_ec_xfer_mock_default_ret;
18int cros_kunit_ec_cmd_xfer_mock_called;
19int cros_kunit_ec_pkt_xfer_mock_called;
20
21static struct list_head cros_kunit_ec_xfer_mock_in;
22static struct list_head cros_kunit_ec_xfer_mock_out;
23
24int cros_kunit_ec_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
25{
26 struct ec_xfer_mock *mock;
27
28 mock = list_first_entry_or_null(&cros_kunit_ec_xfer_mock_in, struct ec_xfer_mock, list);
29 if (!mock) {
30 msg->result = cros_kunit_ec_xfer_mock_default_result;
31 return cros_kunit_ec_xfer_mock_default_ret;
32 }
33
34 list_del(&mock->list);
35
36 memcpy(&mock->msg, msg, sizeof(*msg));
37 if (msg->outsize) {
38 mock->i_data = kunit_kzalloc(mock->test, msg->outsize, GFP_KERNEL);
39 if (mock->i_data)
40 memcpy(mock->i_data, msg->data, msg->outsize);
41 }
42
43 msg->result = mock->result;
44 if (msg->insize)
45 memcpy(msg->data, mock->o_data, min(msg->insize, mock->o_data_len));
46
47 list_add_tail(&mock->list, &cros_kunit_ec_xfer_mock_out);
48
49 return mock->ret;
50}
51
52int cros_kunit_ec_cmd_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
53{
54 ++cros_kunit_ec_cmd_xfer_mock_called;
55 return cros_kunit_ec_xfer_mock(ec_dev, msg);
56}
57
58int cros_kunit_ec_pkt_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
59{
60 ++cros_kunit_ec_pkt_xfer_mock_called;
61 return cros_kunit_ec_xfer_mock(ec_dev, msg);
62}
63
64struct ec_xfer_mock *cros_kunit_ec_xfer_mock_add(struct kunit *test, size_t size)
65{
66 return cros_kunit_ec_xfer_mock_addx(test, size, EC_RES_SUCCESS, size);
67}
68
69struct ec_xfer_mock *cros_kunit_ec_xfer_mock_addx(struct kunit *test,
70 int ret, int result, size_t size)
71{
72 struct ec_xfer_mock *mock;
73
74 mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
75 if (!mock)
76 return NULL;
77
78 list_add_tail(&mock->list, &cros_kunit_ec_xfer_mock_in);
79 mock->test = test;
80
81 mock->ret = ret;
82 mock->result = result;
83 mock->o_data = kunit_kzalloc(test, size, GFP_KERNEL);
84 if (!mock->o_data)
85 return NULL;
86 mock->o_data_len = size;
87
88 return mock;
89}
90
91struct ec_xfer_mock *cros_kunit_ec_xfer_mock_next(void)
92{
93 struct ec_xfer_mock *mock;
94
95 mock = list_first_entry_or_null(&cros_kunit_ec_xfer_mock_out, struct ec_xfer_mock, list);
96 if (mock)
97 list_del(&mock->list);
98
99 return mock;
100}
101
102int cros_kunit_readmem_mock_offset;
103u8 *cros_kunit_readmem_mock_data;
104int cros_kunit_readmem_mock_ret;
105
106int cros_kunit_readmem_mock(struct cros_ec_device *ec_dev, unsigned int offset,
107 unsigned int bytes, void *dest)
108{
109 cros_kunit_readmem_mock_offset = offset;
110
111 memcpy(dest, cros_kunit_readmem_mock_data, bytes);
112
113 return cros_kunit_readmem_mock_ret;
114}
115
116void cros_kunit_mock_reset(void)
117{
118 cros_kunit_ec_xfer_mock_default_result = 0;
119 cros_kunit_ec_xfer_mock_default_ret = 0;
120 cros_kunit_ec_cmd_xfer_mock_called = 0;
121 cros_kunit_ec_pkt_xfer_mock_called = 0;
122 INIT_LIST_HEAD(&cros_kunit_ec_xfer_mock_in);
123 INIT_LIST_HEAD(&cros_kunit_ec_xfer_mock_out);
124
125 cros_kunit_readmem_mock_offset = 0;
126 cros_kunit_readmem_mock_data = NULL;
127 cros_kunit_readmem_mock_ret = 0;
128}
129
130MODULE_LICENSE("GPL");
drivers/platform/chrome/cros_kunit_util.h+48−0
@@ -0,0 +1,48 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * CrOS Kunit tests utilities.
4 */
5
6#ifndef _CROS_KUNIT_UTIL_H_
7#define _CROS_KUNIT_UTIL_H_
8
9#include <linux/platform_data/cros_ec_proto.h>
10
11struct ec_xfer_mock {
12 struct list_head list;
13 struct kunit *test;
14
15 /* input */
16 struct cros_ec_command msg;
17 void *i_data;
18
19 /* output */
20 int ret;
21 int result;
22 void *o_data;
23 u32 o_data_len;
24};
25
26extern int cros_kunit_ec_xfer_mock_default_result;
27extern int cros_kunit_ec_xfer_mock_default_ret;
28extern int cros_kunit_ec_cmd_xfer_mock_called;
29extern int cros_kunit_ec_pkt_xfer_mock_called;
30
31int cros_kunit_ec_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
32int cros_kunit_ec_cmd_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
33int cros_kunit_ec_pkt_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
34struct ec_xfer_mock *cros_kunit_ec_xfer_mock_add(struct kunit *test, size_t size);
35struct ec_xfer_mock *cros_kunit_ec_xfer_mock_addx(struct kunit *test,
36 int ret, int result, size_t size);
37struct ec_xfer_mock *cros_kunit_ec_xfer_mock_next(void);
38
39extern int cros_kunit_readmem_mock_offset;
40extern u8 *cros_kunit_readmem_mock_data;
41extern int cros_kunit_readmem_mock_ret;
42
43int cros_kunit_readmem_mock(struct cros_ec_device *ec_dev, unsigned int offset,
44 unsigned int bytes, void *dest);
45
46void cros_kunit_mock_reset(void);
47
48#endif
drivers/platform/chrome/cros_usbpd_notify.c+2−2
@@ -71,8 +71,8 @@ static void cros_usbpd_get_event_and_notify(struct device *dev, · 70 unmodified lines
71 }71 }
72 72
73 /* Check for PD host events on EC. */73 /* Check for PD host events on EC. */
74 ret = cros_ec_command(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS,74 ret = cros_ec_cmd(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS,
75 NULL, 0, &host_event_status, sizeof(host_event_status));75 NULL, 0, &host_event_status, sizeof(host_event_status));
76 if (ret < 0) {76 if (ret < 0) {
77 dev_warn(dev, "Can't get host event status (err: %d)\n", ret);77 dev_warn(dev, "Can't get host event status (err: %d)\n", ret);
78 goto send_notify;78 goto send_notify;
drivers/platform/chrome/wilco_ec/event.c+1−1
@@ -343,7 +343,7 @@ static __poll_t event_poll(struct file *filp, poll_table *wait) · 342 unmodified lines
343 *343 *
344 * Removes the first event from the queue, places it in the passed buffer.344 * Removes the first event from the queue, places it in the passed buffer.
345 *345 *
346 * If there are no events in the the queue, then one of two things happens,346 * If there are no events in the queue, then one of two things happens,
347 * depending on if the file was opened in nonblocking mode: If in nonblocking347 * depending on if the file was opened in nonblocking mode: If in nonblocking
348 * mode, then return -EAGAIN to say there's no data. If in blocking mode, then348 * mode, then return -EAGAIN to say there's no data. If in blocking mode, then
349 * block until an event is available.349 * block until an event is available.
drivers/regulator/cros-ec-regulator.c+3−33
@@ -22,36 +22,6 @@ struct cros_ec_regulator_data { · 21 unmodified lines
22 u16 num_voltages;22 u16 num_voltages;
23};23};
24 24
25static int cros_ec_cmd(struct cros_ec_device *ec, u32 version, u32 command,
26 void *outdata, u32 outsize, void *indata, u32 insize)
27{
28 struct cros_ec_command *msg;
29 int ret;
30
31 msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
32 if (!msg)
33 return -ENOMEM;
34
35 msg->version = version;
36 msg->command = command;
37 msg->outsize = outsize;
38 msg->insize = insize;
39
40 if (outdata && outsize > 0)
41 memcpy(msg->data, outdata, outsize);
42
43 ret = cros_ec_cmd_xfer_status(ec, msg);
44 if (ret < 0)
45 goto cleanup;
46
47 if (insize)
48 memcpy(indata, msg->data, insize);
49
50cleanup:
51 kfree(msg);
52 return ret;
53}
54
55static int cros_ec_regulator_enable(struct regulator_dev *dev)25static int cros_ec_regulator_enable(struct regulator_dev *dev)
56{26{
57 struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);27 struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
@@ -61,7 +31,7 @@ static int cros_ec_regulator_enable(struct regulator_dev *dev) · 3 unmodified lines
61 };31 };
62 32
63 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,33 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
64 sizeof(cmd), NULL, 0);34 sizeof(cmd), NULL, 0);
65}35}
66 36
67static int cros_ec_regulator_disable(struct regulator_dev *dev)37static int cros_ec_regulator_disable(struct regulator_dev *dev)
@@ -73,7 +43,7 @@ static int cros_ec_regulator_disable(struct regulator_dev *dev) · 5 unmodified lines
73 };43 };
74 44
75 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,45 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
76 sizeof(cmd), NULL, 0);46 sizeof(cmd), NULL, 0);
77}47}
78 48
79static int cros_ec_regulator_is_enabled(struct regulator_dev *dev)49static int cros_ec_regulator_is_enabled(struct regulator_dev *dev)
@@ -161,7 +131,7 @@ static int cros_ec_regulator_init_info(struct device *dev, · 81 unmodified lines
161 int ret;131 int ret;
162 132
163 ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_INFO, &cmd,133 ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_INFO, &cmd,
164 sizeof(cmd), &resp, sizeof(resp));134 sizeof(cmd), &resp, sizeof(resp));
165 if (ret < 0)135 if (ret < 0)
166 return ret;136 return ret;
167 137
include/linux/platform_data/cros_ec_commands.h+3−3
@@ -13,8 +13,8 @@ · 12 unmodified lines
13#ifndef __CROS_EC_COMMANDS_H13#ifndef __CROS_EC_COMMANDS_H
14#define __CROS_EC_COMMANDS_H14#define __CROS_EC_COMMANDS_H
15 15
16 16#include <linux/bits.h>
17 17#include <linux/types.h>
18 18
19#define BUILD_ASSERT(_cond)19#define BUILD_ASSERT(_cond)
20 20
@@ -787,7 +787,7 @@ struct ec_host_response { · 766 unmodified lines
787 *787 *
788 * Packets always start with a request or response header. They are followed788 * Packets always start with a request or response header. They are followed
789 * by data_len bytes of data. If the data_crc_present flag is set, the data789 * by data_len bytes of data. If the data_crc_present flag is set, the data
790 * bytes are followed by a CRC-8 of that data, using using x^8 + x^2 + x + 1790 * bytes are followed by a CRC-8 of that data, using x^8 + x^2 + x + 1
791 * polynomial.791 * polynomial.
792 *792 *
793 * Host algorithm when sending a request q:793 * Host algorithm when sending a request q:
include/linux/platform_data/cros_ec_proto.h+5−2
@@ -21,6 +21,9 @@ · 20 unmodified lines
21#define CROS_EC_DEV_SCP_NAME "cros_scp"21#define CROS_EC_DEV_SCP_NAME "cros_scp"
22#define CROS_EC_DEV_TP_NAME "cros_tp"22#define CROS_EC_DEV_TP_NAME "cros_tp"
23 23
24#define CROS_EC_DEV_EC_INDEX 0
25#define CROS_EC_DEV_PD_INDEX 1
26
24/*27/*
25 * The EC is unresponsive for a time after a reboot command. Add a28 * The EC is unresponsive for a time after a reboot command. Add a
26 * simple delay to make sure that the bus stays locked.29 * simple delay to make sure that the bus stays locked.
@@ -231,8 +234,8 @@ bool cros_ec_check_features(struct cros_ec_dev *ec, int feature); · 204 unmodified lines
231 234
232int cros_ec_get_sensor_count(struct cros_ec_dev *ec);235int cros_ec_get_sensor_count(struct cros_ec_dev *ec);
233 236
234int cros_ec_command(struct cros_ec_device *ec_dev, unsigned int version, int command, void *outdata,237int cros_ec_cmd(struct cros_ec_device *ec_dev, unsigned int version, int command, void *outdata,
235 int outsize, void *indata, int insize);238 size_t outsize, void *indata, size_t insize);
236 239
237/**240/**
238 * cros_ec_get_time_ns() - Return time in ns.241 * cros_ec_get_time_ns() - Return time in ns.