xref: /linux/drivers/platform/chrome/cros_ec_proto.c (revision e5d379e9c3148aaef37909ce6d4c3ca18fad0312)
1 // SPDX-License-Identifier: GPL-2.0
2 // ChromeOS EC communication protocol helper functions
3 //
4 // Copyright (C) 2015 Google, Inc
5 
6 #include <linux/cleanup.h>
7 #include <linux/delay.h>
8 #include <linux/device.h>
9 #include <linux/limits.h>
10 #include <linux/module.h>
11 #include <linux/platform_data/cros_ec_commands.h>
12 #include <linux/platform_data/cros_ec_proto.h>
13 #include <linux/slab.h>
14 #include <linux/unaligned.h>
15 
16 #include "cros_ec_trace.h"
17 
18 #define EC_COMMAND_RETRIES	50
19 #define RWSIG_CONTINUE_RETRIES	8
20 #define RWSIG_CONTINUE_MAX_ERRORS_IN_ROW	3
21 
22 static const int cros_ec_error_map[] = {
23 	[EC_RES_INVALID_COMMAND] = -EOPNOTSUPP,
24 	[EC_RES_ERROR] = -EIO,
25 	[EC_RES_INVALID_PARAM] = -EINVAL,
26 	[EC_RES_ACCESS_DENIED] = -EACCES,
27 	[EC_RES_INVALID_RESPONSE] = -EPROTO,
28 	[EC_RES_INVALID_VERSION] = -ENOPROTOOPT,
29 	[EC_RES_INVALID_CHECKSUM] = -EBADMSG,
30 	[EC_RES_IN_PROGRESS] = -EINPROGRESS,
31 	[EC_RES_UNAVAILABLE] = -ENODATA,
32 	[EC_RES_TIMEOUT] = -ETIMEDOUT,
33 	[EC_RES_OVERFLOW] = -EOVERFLOW,
34 	[EC_RES_INVALID_HEADER] = -EBADR,
35 	[EC_RES_REQUEST_TRUNCATED] = -EBADR,
36 	[EC_RES_RESPONSE_TOO_BIG] = -EFBIG,
37 	[EC_RES_BUS_ERROR] = -EFAULT,
38 	[EC_RES_BUSY] = -EBUSY,
39 	[EC_RES_INVALID_HEADER_VERSION] = -EBADMSG,
40 	[EC_RES_INVALID_HEADER_CRC] = -EBADMSG,
41 	[EC_RES_INVALID_DATA_CRC] = -EBADMSG,
42 	[EC_RES_DUP_UNAVAILABLE] = -ENODATA,
43 };
44 
cros_ec_map_error(uint32_t result)45 static int cros_ec_map_error(uint32_t result)
46 {
47 	int ret = 0;
48 
49 	if (result != EC_RES_SUCCESS) {
50 		if (result < ARRAY_SIZE(cros_ec_error_map) && cros_ec_error_map[result])
51 			ret = cros_ec_error_map[result];
52 		else
53 			ret = -EPROTO;
54 	}
55 
56 	return ret;
57 }
58 
prepare_tx(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)59 static int prepare_tx(struct cros_ec_device *ec_dev,
60 		      struct cros_ec_command *msg)
61 {
62 	struct ec_host_request *request;
63 	u8 *out;
64 	int i;
65 	u8 csum = 0;
66 
67 	if (msg->outsize + sizeof(*request) > ec_dev->dout_size)
68 		return -EINVAL;
69 
70 	out = ec_dev->dout;
71 	request = (struct ec_host_request *)out;
72 	request->struct_version = EC_HOST_REQUEST_VERSION;
73 	request->checksum = 0;
74 	request->command = msg->command;
75 	request->command_version = msg->version;
76 	request->reserved = 0;
77 	request->data_len = msg->outsize;
78 
79 	for (i = 0; i < sizeof(*request); i++)
80 		csum += out[i];
81 
82 	/* Copy data and update checksum */
83 	memcpy(out + sizeof(*request), msg->data, msg->outsize);
84 	for (i = 0; i < msg->outsize; i++)
85 		csum += msg->data[i];
86 
87 	request->checksum = -csum;
88 
89 	return sizeof(*request) + msg->outsize;
90 }
91 
prepare_tx_legacy(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)92 static int prepare_tx_legacy(struct cros_ec_device *ec_dev,
93 			     struct cros_ec_command *msg)
94 {
95 	u8 *out;
96 	u8 csum;
97 	int i;
98 
99 	if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
100 		return -EINVAL;
101 
102 	out = ec_dev->dout;
103 	out[0] = EC_CMD_VERSION0 + msg->version;
104 	out[1] = msg->command;
105 	out[2] = msg->outsize;
106 	csum = out[0] + out[1] + out[2];
107 	for (i = 0; i < msg->outsize; i++)
108 		csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
109 	out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
110 
111 	return EC_MSG_TX_PROTO_BYTES + msg->outsize;
112 }
113 
cros_ec_xfer_command(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)114 static int cros_ec_xfer_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
115 {
116 	int ret;
117 	int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
118 
119 	if (ec_dev->proto_version > 2)
120 		xfer_fxn = ec_dev->pkt_xfer;
121 	else
122 		xfer_fxn = ec_dev->cmd_xfer;
123 
124 	if (!xfer_fxn) {
125 		/*
126 		 * This error can happen if a communication error happened and
127 		 * the EC is trying to use protocol v2, on an underlying
128 		 * communication mechanism that does not support v2.
129 		 */
130 		dev_err_once(ec_dev->dev, "missing EC transfer API, cannot send command\n");
131 		return -EIO;
132 	}
133 
134 	trace_cros_ec_request_start(msg);
135 	ret = (*xfer_fxn)(ec_dev, msg);
136 	trace_cros_ec_request_done(msg, ret);
137 
138 	return ret;
139 }
140 
cros_ec_wait_until_complete(struct cros_ec_device * ec_dev,struct cros_ec_command * orig_msg)141 static int cros_ec_wait_until_complete(struct cros_ec_device *ec_dev,
142 				       struct cros_ec_command *orig_msg)
143 {
144 	DEFINE_RAW_FLEX(struct cros_ec_command, msg, data,
145 			sizeof(struct ec_response_get_comms_status));
146 	struct ec_response_get_comms_status *status =
147 			(struct ec_response_get_comms_status *)msg->data;
148 	int ret = 0, i;
149 
150 	msg->version = 0;
151 	msg->command = EC_CMD_GET_COMMS_STATUS;
152 	msg->insize = sizeof(*status);
153 	msg->outsize = 0;
154 
155 	/* Query the EC's status until it's no longer busy or we encounter an error. */
156 	for (i = 0; i < EC_COMMAND_RETRIES; ++i) {
157 		usleep_range(10000, 11000);
158 
159 		ret = cros_ec_xfer_command(ec_dev, msg);
160 		if (ret == -EAGAIN)
161 			continue;
162 		if (ret < 0)
163 			return ret;
164 
165 		orig_msg->result = msg->result;
166 		if (msg->result != EC_RES_SUCCESS)
167 			return ret;
168 
169 		if (ret == 0)
170 			return -EPROTO;
171 
172 		if (!(status->flags & EC_COMMS_STATUS_PROCESSING)) {
173 			u32 orig_cmd, orig_outsize, orig_version;
174 
175 			/* If no response payload is expected, return 0. */
176 			if (orig_msg->insize == 0)
177 				return 0;
178 
179 			/*
180 			 * Request the response using EC_CMD_RESEND_RESPONSE.
181 			 * Restore the original message fields so it appears
182 			 * to be a direct response to the original command.
183 			 */
184 			orig_cmd = orig_msg->command;
185 			orig_outsize = orig_msg->outsize;
186 			orig_version = orig_msg->version;
187 
188 			orig_msg->command = EC_CMD_RESEND_RESPONSE;
189 			orig_msg->outsize = 0;
190 			orig_msg->version = 0;
191 			ret = cros_ec_xfer_command(ec_dev, orig_msg);
192 			orig_msg->command = orig_cmd;
193 			orig_msg->outsize = orig_outsize;
194 			orig_msg->version = orig_version;
195 			return ret;
196 		}
197 	}
198 
199 	return -EAGAIN;
200 }
201 
cros_ec_send_command(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)202 static int cros_ec_send_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
203 {
204 	int ret = cros_ec_xfer_command(ec_dev, msg);
205 
206 	if (msg->result == EC_RES_IN_PROGRESS)
207 		ret = cros_ec_wait_until_complete(ec_dev, msg);
208 
209 	return ret;
210 }
211 
212 /**
213  * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer.
214  * @ec_dev: Device to register.
215  * @msg: Message to write.
216  *
217  * This is used by all ChromeOS EC drivers to prepare the outgoing message
218  * according to different protocol versions.
219  *
220  * Return: number of prepared bytes on success or negative error code.
221  */
cros_ec_prepare_tx(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)222 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
223 		       struct cros_ec_command *msg)
224 {
225 	if (ec_dev->proto_version > 2)
226 		return prepare_tx(ec_dev, msg);
227 
228 	return prepare_tx_legacy(ec_dev, msg);
229 }
230 EXPORT_SYMBOL(cros_ec_prepare_tx);
231 
232 /**
233  * cros_ec_check_result() - Check ec_msg->result.
234  * @ec_dev: EC device.
235  * @msg: Message to check.
236  *
237  * This is used by ChromeOS EC drivers to check the ec_msg->result for
238  * EC_RES_IN_PROGRESS and to warn about them.
239  *
240  * The function should not check for furthermore error codes.  Otherwise,
241  * it would break the ABI.
242  *
243  * Return: -EAGAIN if ec_msg->result == EC_RES_IN_PROGRESS.  Otherwise, 0.
244  */
cros_ec_check_result(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)245 int cros_ec_check_result(struct cros_ec_device *ec_dev,
246 			 struct cros_ec_command *msg)
247 {
248 	switch (msg->result) {
249 	case EC_RES_SUCCESS:
250 		return 0;
251 	case EC_RES_IN_PROGRESS:
252 		dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
253 			msg->command);
254 		return -EAGAIN;
255 	default:
256 		dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
257 			msg->command, msg->result);
258 		return 0;
259 	}
260 }
261 EXPORT_SYMBOL(cros_ec_check_result);
262 
263 /**
264  * cros_ec_get_host_event_wake_mask
265  *
266  * Get the mask of host events that cause wake from suspend.
267  *
268  * @ec_dev: EC device to call
269  * @mask: result when function returns 0.
270  *
271  * LOCKING:
272  * the caller has ec_dev->lock mutex, or the caller knows there is
273  * no other command in progress.
274  */
cros_ec_get_host_event_wake_mask(struct cros_ec_device * ec_dev,uint32_t * mask)275 static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev, uint32_t *mask)
276 {
277 	struct cros_ec_command *msg;
278 	struct ec_response_host_event_mask *r;
279 	int ret, mapped;
280 
281 	msg = kzalloc(sizeof(*msg) + sizeof(*r), GFP_KERNEL);
282 	if (!msg)
283 		return -ENOMEM;
284 
285 	msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
286 	msg->insize = sizeof(*r);
287 
288 	ret = cros_ec_send_command(ec_dev, msg);
289 	if (ret < 0)
290 		goto exit;
291 
292 	mapped = cros_ec_map_error(msg->result);
293 	if (mapped) {
294 		ret = mapped;
295 		goto exit;
296 	}
297 
298 	if (ret == 0) {
299 		ret = -EPROTO;
300 		goto exit;
301 	}
302 
303 	r = (struct ec_response_host_event_mask *)msg->data;
304 	*mask = r->mask;
305 	ret = 0;
306 exit:
307 	kfree(msg);
308 	return ret;
309 }
310 
cros_ec_rwsig_continue(struct cros_ec_device * ec_dev)311 int cros_ec_rwsig_continue(struct cros_ec_device *ec_dev)
312 {
313 	struct cros_ec_command *msg;
314 	struct ec_params_rwsig_action *rwsig_action;
315 	int ret = 0;
316 	int error_count = 0;
317 
318 	ec_dev->proto_version = 3;
319 
320 	msg = kmalloc(sizeof(*msg) + sizeof(*rwsig_action), GFP_KERNEL);
321 	if (!msg)
322 		return -ENOMEM;
323 
324 	msg->version = 0;
325 	msg->command = EC_CMD_RWSIG_ACTION;
326 	msg->insize = 0;
327 	msg->outsize = sizeof(*rwsig_action);
328 
329 	rwsig_action = (struct ec_params_rwsig_action *)msg->data;
330 	rwsig_action->action = RWSIG_ACTION_CONTINUE;
331 
332 	for (int i = 0; i < RWSIG_CONTINUE_RETRIES; i++) {
333 		ret = cros_ec_send_command(ec_dev, msg);
334 
335 		if (ret < 0) {
336 			if (++error_count >= RWSIG_CONTINUE_MAX_ERRORS_IN_ROW)
337 				break;
338 		} else if (msg->result == EC_RES_INVALID_COMMAND) {
339 			/*
340 			 * If EC_RES_INVALID_COMMAND is retured, it means RWSIG
341 			 * is not supported or EC is already in RW, so there is
342 			 * nothing left to do.
343 			 */
344 			break;
345 		} else if (msg->result != EC_RES_SUCCESS) {
346 			/* Unexpected command error. */
347 			ret = cros_ec_map_error(msg->result);
348 			break;
349 		} else {
350 			/*
351 			 * The EC_CMD_RWSIG_ACTION succeed. Send the command
352 			 * more times, to make sure EC is in RW. A following
353 			 * command can timeout, because EC may need some time to
354 			 * initialize after jump to RW.
355 			 */
356 			error_count = 0;
357 		}
358 
359 		if (ret != -ETIMEDOUT)
360 			usleep_range(90000, 100000);
361 	}
362 
363 	kfree(msg);
364 
365 	return ret;
366 }
367 EXPORT_SYMBOL(cros_ec_rwsig_continue);
368 
cros_ec_get_proto_info(struct cros_ec_device * ec_dev,int devidx)369 static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx)
370 {
371 	struct cros_ec_command *msg;
372 	struct ec_response_get_protocol_info *info;
373 	int ret, mapped;
374 
375 	ec_dev->proto_version = 3;
376 	if (devidx > 0)
377 		ec_dev->max_passthru = 0;
378 
379 	msg = kzalloc(sizeof(*msg) + sizeof(*info), GFP_KERNEL);
380 	if (!msg)
381 		return -ENOMEM;
382 
383 	msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
384 	msg->insize = sizeof(*info);
385 
386 	ret = cros_ec_send_command(ec_dev, msg);
387 
388 	if (ret < 0) {
389 		dev_dbg(ec_dev->dev,
390 			"failed to check for EC[%d] protocol version: %d\n",
391 			devidx, ret);
392 		goto exit;
393 	}
394 
395 	mapped = cros_ec_map_error(msg->result);
396 	if (mapped) {
397 		ret = mapped;
398 		goto exit;
399 	}
400 
401 	if (ret == 0) {
402 		ret = -EPROTO;
403 		goto exit;
404 	}
405 
406 	info = (struct ec_response_get_protocol_info *)msg->data;
407 
408 	switch (devidx) {
409 	case CROS_EC_DEV_EC_INDEX:
410 		ec_dev->max_request = info->max_request_packet_size -
411 						sizeof(struct ec_host_request);
412 		ec_dev->max_response = info->max_response_packet_size -
413 						sizeof(struct ec_host_response);
414 		ec_dev->proto_version = min(EC_HOST_REQUEST_VERSION,
415 					    fls(info->protocol_versions) - 1);
416 		ec_dev->din_size = info->max_response_packet_size + EC_MAX_RESPONSE_OVERHEAD;
417 		ec_dev->dout_size = info->max_request_packet_size + EC_MAX_REQUEST_OVERHEAD;
418 
419 		dev_dbg(ec_dev->dev, "using proto v%u\n", ec_dev->proto_version);
420 		break;
421 	case CROS_EC_DEV_PD_INDEX:
422 		ec_dev->max_passthru = info->max_request_packet_size -
423 						sizeof(struct ec_host_request);
424 
425 		dev_dbg(ec_dev->dev, "found PD chip\n");
426 		break;
427 	default:
428 		dev_dbg(ec_dev->dev, "unknown passthru index: %d\n", devidx);
429 		break;
430 	}
431 
432 	ret = 0;
433 exit:
434 	kfree(msg);
435 	return ret;
436 }
437 
cros_ec_get_proto_info_legacy(struct cros_ec_device * ec_dev)438 static int cros_ec_get_proto_info_legacy(struct cros_ec_device *ec_dev)
439 {
440 	struct cros_ec_command *msg;
441 	struct ec_params_hello *params;
442 	struct ec_response_hello *response;
443 	int ret, mapped;
444 
445 	ec_dev->proto_version = 2;
446 
447 	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*response)), GFP_KERNEL);
448 	if (!msg)
449 		return -ENOMEM;
450 
451 	msg->command = EC_CMD_HELLO;
452 	msg->insize = sizeof(*response);
453 	msg->outsize = sizeof(*params);
454 
455 	params = (struct ec_params_hello *)msg->data;
456 	params->in_data = 0xa0b0c0d0;
457 
458 	ret = cros_ec_send_command(ec_dev, msg);
459 	if (ret < 0) {
460 		dev_dbg(ec_dev->dev, "EC failed to respond to v2 hello: %d\n", ret);
461 		goto exit;
462 	}
463 
464 	mapped = cros_ec_map_error(msg->result);
465 	if (mapped) {
466 		ret = mapped;
467 		dev_err(ec_dev->dev, "EC responded to v2 hello with error: %d\n", msg->result);
468 		goto exit;
469 	}
470 
471 	if (ret == 0) {
472 		ret = -EPROTO;
473 		goto exit;
474 	}
475 
476 	response = (struct ec_response_hello *)msg->data;
477 	if (response->out_data != 0xa1b2c3d4) {
478 		dev_err(ec_dev->dev,
479 			"EC responded to v2 hello with bad result: %u\n",
480 			response->out_data);
481 		ret = -EBADMSG;
482 		goto exit;
483 	}
484 
485 	ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
486 	ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
487 	ec_dev->max_passthru = 0;
488 	ec_dev->pkt_xfer = NULL;
489 	ec_dev->din_size = EC_PROTO2_MSG_BYTES;
490 	ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
491 
492 	dev_dbg(ec_dev->dev, "falling back to proto v2\n");
493 	ret = 0;
494 exit:
495 	kfree(msg);
496 	return ret;
497 }
498 
499 /**
500  * cros_ec_get_host_command_version_mask
501  *
502  * Get the version mask of a given command.
503  *
504  * @ec_dev: EC device to call
505  * @cmd: command to get the version of.
506  * @mask: result when function returns 0.
507  *
508  * @return 0 on success, error code otherwise
509  *
510  * LOCKING:
511  * the caller has ec_dev->lock mutex or the caller knows there is
512  * no other command in progress.
513  */
cros_ec_get_host_command_version_mask(struct cros_ec_device * ec_dev,u16 cmd,u32 * mask)514 static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, u16 cmd, u32 *mask)
515 {
516 	struct ec_params_get_cmd_versions *pver;
517 	struct ec_response_get_cmd_versions *rver;
518 	struct cros_ec_command *msg;
519 	int ret, mapped;
520 
521 	msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
522 		      GFP_KERNEL);
523 	if (!msg)
524 		return -ENOMEM;
525 
526 	msg->version = 0;
527 	msg->command = EC_CMD_GET_CMD_VERSIONS;
528 	msg->insize = sizeof(*rver);
529 	msg->outsize = sizeof(*pver);
530 
531 	pver = (struct ec_params_get_cmd_versions *)msg->data;
532 	pver->cmd = cmd;
533 
534 	ret = cros_ec_send_command(ec_dev, msg);
535 	if (ret < 0)
536 		goto exit;
537 
538 	mapped = cros_ec_map_error(msg->result);
539 	if (mapped) {
540 		ret = mapped;
541 		goto exit;
542 	}
543 
544 	if (ret == 0) {
545 		ret = -EPROTO;
546 		goto exit;
547 	}
548 
549 	rver = (struct ec_response_get_cmd_versions *)msg->data;
550 	*mask = rver->version_mask;
551 	ret = 0;
552 exit:
553 	kfree(msg);
554 	return ret;
555 }
556 
557 /**
558  * cros_ec_query_all() -  Query the protocol version supported by the
559  *         ChromeOS EC.
560  * @ec_dev: Device to register.
561  *
562  * Return: 0 on success or negative error code.
563  */
cros_ec_query_all(struct cros_ec_device * ec_dev)564 int cros_ec_query_all(struct cros_ec_device *ec_dev)
565 {
566 	struct device *dev = ec_dev->dev;
567 	u32 ver_mask;
568 	int ret;
569 
570 	/* First try sending with proto v3. */
571 	if (!cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_EC_INDEX)) {
572 		/* Check for PD. */
573 		cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_PD_INDEX);
574 	} else {
575 		/* Try querying with a v2 hello message. */
576 		ret = cros_ec_get_proto_info_legacy(ec_dev);
577 		if (ret) {
578 			/*
579 			 * It's possible for a test to occur too early when
580 			 * the EC isn't listening. If this happens, we'll
581 			 * test later when the first command is run.
582 			 */
583 			ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
584 			dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
585 			return ret;
586 		}
587 	}
588 
589 	devm_kfree(dev, ec_dev->din);
590 	devm_kfree(dev, ec_dev->dout);
591 
592 	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
593 	if (!ec_dev->din) {
594 		ret = -ENOMEM;
595 		goto exit;
596 	}
597 
598 	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
599 	if (!ec_dev->dout) {
600 		devm_kfree(dev, ec_dev->din);
601 		ret = -ENOMEM;
602 		goto exit;
603 	}
604 
605 	/* Probe if MKBP event is supported */
606 	ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_GET_NEXT_EVENT, &ver_mask);
607 	if (ret < 0 || ver_mask == 0) {
608 		ec_dev->mkbp_event_supported = 0;
609 	} else {
610 		ec_dev->mkbp_event_supported = fls(ver_mask);
611 
612 		dev_dbg(ec_dev->dev, "MKBP support version %u\n", ec_dev->mkbp_event_supported - 1);
613 	}
614 
615 	/* Probe if host sleep v1 is supported for S0ix failure detection. */
616 	ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_HOST_SLEEP_EVENT, &ver_mask);
617 	ec_dev->host_sleep_v1 = (ret == 0 && (ver_mask & EC_VER_MASK(1)));
618 
619 	/* Get host event wake mask. */
620 	ret = cros_ec_get_host_event_wake_mask(ec_dev, &ec_dev->host_event_wake_mask);
621 	if (ret < 0) {
622 		/*
623 		 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,
624 		 * use a reasonable default. Note that we ignore various
625 		 * battery, AC status, and power-state events, because (a)
626 		 * those can be quite common (e.g., when sitting at full
627 		 * charge, on AC) and (b) these are not actionable wake events;
628 		 * if anything, we'd like to continue suspending (to save
629 		 * power), not wake up.
630 		 */
631 		ec_dev->host_event_wake_mask = U32_MAX &
632 			~(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |
633 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |
634 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW) |
635 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |
636 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY) |
637 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) |
638 			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS));
639 		/*
640 		 * Old ECs may not support this command. Complain about all
641 		 * other errors.
642 		 */
643 		if (ret != -EOPNOTSUPP)
644 			dev_err(ec_dev->dev,
645 				"failed to retrieve wake mask: %d\n", ret);
646 	}
647 
648 	ret = 0;
649 
650 exit:
651 	return ret;
652 }
653 EXPORT_SYMBOL(cros_ec_query_all);
654 
655 /**
656  * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC.
657  * @ec_dev: EC device.
658  * @msg: Message to write.
659  *
660  * Call this to send a command to the ChromeOS EC. This should be used instead
661  * of calling the EC's cmd_xfer() callback directly. This function does not
662  * convert EC command execution error codes to Linux error codes. Most
663  * in-kernel users will want to use cros_ec_cmd_xfer_status() instead since
664  * that function implements the conversion.
665  *
666  * Return:
667  * >0 - EC command was executed successfully. The return value is the number
668  *      of bytes returned by the EC (excluding the header).
669  * =0 - EC communication was successful. EC command execution results are
670  *      reported in msg->result. The result will be EC_RES_SUCCESS if the
671  *      command was executed successfully or report an EC command execution
672  *      error.
673  * <0 - EC communication error. Return value is the Linux error code.
674  */
cros_ec_cmd_xfer(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)675 int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
676 {
677 	int ret;
678 
679 	mutex_lock(&ec_dev->lock);
680 	if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
681 		ret = cros_ec_query_all(ec_dev);
682 		if (ret) {
683 			dev_err(ec_dev->dev,
684 				"EC version unknown and query failed; aborting command\n");
685 			mutex_unlock(&ec_dev->lock);
686 			return ret;
687 		}
688 	}
689 
690 	if (msg->insize > ec_dev->max_response) {
691 		dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
692 		msg->insize = ec_dev->max_response;
693 	}
694 
695 	if (msg->command < EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX)) {
696 		if (msg->outsize > ec_dev->max_request) {
697 			dev_err(ec_dev->dev,
698 				"request of size %u is too big (max: %u)\n",
699 				msg->outsize,
700 				ec_dev->max_request);
701 			mutex_unlock(&ec_dev->lock);
702 			return -EMSGSIZE;
703 		}
704 	} else {
705 		if (msg->outsize > ec_dev->max_passthru) {
706 			dev_err(ec_dev->dev,
707 				"passthru rq of size %u is too big (max: %u)\n",
708 				msg->outsize,
709 				ec_dev->max_passthru);
710 			mutex_unlock(&ec_dev->lock);
711 			return -EMSGSIZE;
712 		}
713 	}
714 
715 	ret = cros_ec_send_command(ec_dev, msg);
716 	mutex_unlock(&ec_dev->lock);
717 
718 	return ret;
719 }
720 EXPORT_SYMBOL(cros_ec_cmd_xfer);
721 
722 /**
723  * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC.
724  * @ec_dev: EC device.
725  * @msg: Message to write.
726  *
727  * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's
728  * cmd_xfer() callback directly. It returns success status only if both the command was transmitted
729  * successfully and the EC replied with success status.
730  *
731  * Return:
732  * >=0 - The number of bytes transferred.
733  * <0 - Linux error code
734  */
cros_ec_cmd_xfer_status(struct cros_ec_device * ec_dev,struct cros_ec_command * msg)735 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
736 			    struct cros_ec_command *msg)
737 {
738 	int ret, mapped;
739 
740 	ret = cros_ec_cmd_xfer(ec_dev, msg);
741 	if (ret < 0)
742 		return ret;
743 
744 	mapped = cros_ec_map_error(msg->result);
745 	if (mapped) {
746 		dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n",
747 			msg->result, mapped);
748 		ret = mapped;
749 	}
750 
751 	return ret;
752 }
753 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
754 
get_next_event_xfer(struct cros_ec_device * ec_dev,struct cros_ec_command * msg,struct ec_response_get_next_event_v3 * event,int version,uint32_t size)755 static int get_next_event_xfer(struct cros_ec_device *ec_dev,
756 			       struct cros_ec_command *msg,
757 			       struct ec_response_get_next_event_v3 *event,
758 			       int version, uint32_t size)
759 {
760 	int ret;
761 
762 	msg->version = version;
763 	msg->command = EC_CMD_GET_NEXT_EVENT;
764 	msg->insize = size;
765 	msg->outsize = 0;
766 
767 	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
768 	if (ret > 0) {
769 		ec_dev->event_size = ret - 1;
770 		ec_dev->event_data = *event;
771 	}
772 
773 	return ret;
774 }
775 
get_next_event(struct cros_ec_device * ec_dev)776 static int get_next_event(struct cros_ec_device *ec_dev)
777 {
778 	DEFINE_RAW_FLEX(struct cros_ec_command, msg, data,
779 			sizeof(struct ec_response_get_next_event_v3));
780 	struct ec_response_get_next_event_v3 *event =
781 			(struct ec_response_get_next_event_v3 *)msg->data;
782 	int cmd_version = ec_dev->mkbp_event_supported - 1;
783 	u32 size;
784 
785 	if (ec_dev->suspended) {
786 		dev_dbg(ec_dev->dev, "Device suspended.\n");
787 		return -EHOSTDOWN;
788 	}
789 
790 	if (cmd_version == 0) {
791 		size = sizeof(struct ec_response_get_next_event);
792 	} else if (cmd_version < 3) {
793 		size = sizeof(struct ec_response_get_next_event_v1);
794 	} else {
795 		/*
796 		 * The max version we support is v3. So, we speak v3 even if the
797 		 * EC says it supports v4+.
798 		 */
799 		cmd_version = 3;
800 		size = sizeof(struct ec_response_get_next_event_v3);
801 	}
802 
803 	return get_next_event_xfer(ec_dev, msg, event, cmd_version, size);
804 }
805 
get_keyboard_state_event(struct cros_ec_device * ec_dev)806 static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
807 {
808 	u8 buffer[sizeof(struct cros_ec_command) +
809 		  sizeof(ec_dev->event_data.data)];
810 	struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
811 
812 	msg->version = 0;
813 	msg->command = EC_CMD_MKBP_STATE;
814 	msg->insize = sizeof(ec_dev->event_data.data);
815 	msg->outsize = 0;
816 
817 	ec_dev->event_size = cros_ec_cmd_xfer_status(ec_dev, msg);
818 	ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX;
819 	memcpy(&ec_dev->event_data.data, msg->data,
820 	       sizeof(ec_dev->event_data.data));
821 
822 	return ec_dev->event_size;
823 }
824 
825 /**
826  * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC.
827  * @ec_dev: Device to fetch event from.
828  * @wake_event: Pointer to a bool set to true upon return if the event might be
829  *              treated as a wake event. Ignored if null.
830  * @has_more_events: Pointer to bool set to true if more than one event is
831  *              pending.
832  *              Some EC will set this flag to indicate cros_ec_get_next_event()
833  *              can be called multiple times in a row.
834  *              It is an optimization to prevent issuing a EC command for
835  *              nothing or wait for another interrupt from the EC to process
836  *              the next message.
837  *              Ignored if null.
838  *
839  * Return: negative error code on errors; 0 for no data; or else number of
840  * bytes received (i.e., an event was retrieved successfully). Event types are
841  * written out to @ec_dev->event_data.event_type on success.
842  */
cros_ec_get_next_event(struct cros_ec_device * ec_dev,bool * wake_event,bool * has_more_events)843 int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
844 			   bool *wake_event,
845 			   bool *has_more_events)
846 {
847 	u8 event_type;
848 	u32 host_event;
849 	int ret;
850 	u32 ver_mask;
851 
852 	/*
853 	 * Default value for wake_event.
854 	 * Wake up on keyboard event, wake up for spurious interrupt or link
855 	 * error to the EC.
856 	 */
857 	if (wake_event)
858 		*wake_event = true;
859 
860 	/*
861 	 * Default value for has_more_events.
862 	 * EC will raise another interrupt if AP does not process all events
863 	 * anyway.
864 	 */
865 	if (has_more_events)
866 		*has_more_events = false;
867 
868 	if (!ec_dev->mkbp_event_supported)
869 		return get_keyboard_state_event(ec_dev);
870 
871 	ret = get_next_event(ec_dev);
872 	/*
873 	 * -ENOPROTOOPT is returned when EC returns EC_RES_INVALID_VERSION.
874 	 * This can occur when EC based device (e.g. Fingerprint MCU) jumps to
875 	 * the RO image which doesn't support newer version of the command. In
876 	 * this case we will attempt to update maximum supported version of the
877 	 * EC_CMD_GET_NEXT_EVENT.
878 	 */
879 	if (ret == -ENOPROTOOPT) {
880 		dev_dbg(ec_dev->dev,
881 			"GET_NEXT_EVENT returned invalid version error.\n");
882 		mutex_lock(&ec_dev->lock);
883 		ret = cros_ec_get_host_command_version_mask(ec_dev,
884 							EC_CMD_GET_NEXT_EVENT,
885 							&ver_mask);
886 		mutex_unlock(&ec_dev->lock);
887 		if (ret < 0 || ver_mask == 0)
888 			/*
889 			 * Do not change the MKBP supported version if we can't
890 			 * obtain supported version correctly. Please note that
891 			 * calling EC_CMD_GET_NEXT_EVENT returned
892 			 * EC_RES_INVALID_VERSION which means that the command
893 			 * is present.
894 			 */
895 			return -ENOPROTOOPT;
896 
897 		ec_dev->mkbp_event_supported = fls(ver_mask);
898 		dev_dbg(ec_dev->dev, "MKBP support version changed to %u\n",
899 			ec_dev->mkbp_event_supported - 1);
900 
901 		/* Try to get next event with new MKBP support version set. */
902 		ret = get_next_event(ec_dev);
903 	}
904 
905 	if (ret <= 0)
906 		return ret;
907 
908 	if (has_more_events)
909 		*has_more_events = ec_dev->event_data.event_type &
910 			EC_MKBP_HAS_MORE_EVENTS;
911 	ec_dev->event_data.event_type &= EC_MKBP_EVENT_TYPE_MASK;
912 
913 	if (wake_event) {
914 		event_type = ec_dev->event_data.event_type;
915 		host_event = cros_ec_get_host_event(ec_dev);
916 
917 		/*
918 		 * Sensor events need to be parsed by the sensor sub-device.
919 		 * Defer them, and don't report the wakeup here.
920 		 */
921 		if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) {
922 			*wake_event = false;
923 		} else if (host_event) {
924 			/* rtc_update_irq() already handles wakeup events. */
925 			if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC))
926 				*wake_event = false;
927 			/* Masked host-events should not count as wake events. */
928 			if (!(host_event & ec_dev->host_event_wake_mask))
929 				*wake_event = false;
930 		}
931 	}
932 
933 	return ret;
934 }
935 EXPORT_SYMBOL(cros_ec_get_next_event);
936 
937 /**
938  * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC.
939  * @ec_dev: Device to fetch event from.
940  *
941  * When MKBP is supported, when the EC raises an interrupt, we collect the
942  * events raised and call the functions in the ec notifier. This function
943  * is a helper to know which events are raised.
944  *
945  * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*.
946  */
cros_ec_get_host_event(struct cros_ec_device * ec_dev)947 u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev)
948 {
949 	u32 host_event;
950 
951 	if (!ec_dev->mkbp_event_supported)
952 		return 0;
953 
954 	if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT)
955 		return 0;
956 
957 	if (ec_dev->event_size != sizeof(host_event)) {
958 		dev_warn(ec_dev->dev, "Invalid host event size\n");
959 		return 0;
960 	}
961 
962 	host_event = get_unaligned_le32(&ec_dev->event_data.data.host_event);
963 
964 	return host_event;
965 }
966 EXPORT_SYMBOL(cros_ec_get_host_event);
967 
968 /**
969  * cros_ec_read_features() - Read EC features
970  *
971  * @ec: EC device.
972  *
973  * Return: >= 0 on success, negative error number on failure.
974  */
cros_ec_read_features(struct cros_ec_dev * ec)975 int cros_ec_read_features(struct cros_ec_dev *ec)
976 {
977 	int ret = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
978 			      NULL, 0, &ec->features, sizeof(ec->features));
979 
980 	if (ret < 0) {
981 		dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
982 		memset(&ec->features, 0, sizeof(ec->features));
983 	}
984 
985 	return ret;
986 }
987 EXPORT_SYMBOL_GPL(cros_ec_read_features);
988 
989 /**
990  * cros_ec_check_features() - Test for the presence of EC features
991  *
992  * @ec: EC device, does not have to be connected directly to the AP,
993  *      can be daisy chained through another device.
994  * @feature: One of ec_feature_code bit.
995  *
996  * Call this function to test whether the ChromeOS EC supports a feature.
997  *
998  * Return: true if supported, false if not (or if an error was encountered).
999  */
cros_ec_check_features(struct cros_ec_dev * ec,int feature)1000 bool cros_ec_check_features(struct cros_ec_dev *ec, int feature)
1001 {
1002 	struct ec_response_get_features *features = &ec->features;
1003 
1004 	if (features->flags[0] == -1U && features->flags[1] == -1U) {
1005 		/* features bitmap not read yet */
1006 		cros_ec_read_features(ec);
1007 		dev_dbg(ec->dev, "EC features %08x %08x\n",
1008 			features->flags[0], features->flags[1]);
1009 	}
1010 
1011 	return !!(features->flags[feature / 32] & EC_FEATURE_MASK_0(feature));
1012 }
1013 EXPORT_SYMBOL_GPL(cros_ec_check_features);
1014 
1015 /**
1016  * cros_ec_get_sensor_count() - Return the number of MEMS sensors supported.
1017  *
1018  * @ec: EC device, does not have to be connected directly to the AP,
1019  *      can be daisy chained through another device.
1020  * Return: < 0 in case of error.
1021  */
cros_ec_get_sensor_count(struct cros_ec_dev * ec)1022 int cros_ec_get_sensor_count(struct cros_ec_dev *ec)
1023 {
1024 	/*
1025 	 * Issue a command to get the number of sensor reported.
1026 	 * If not supported, check for legacy mode.
1027 	 */
1028 	int ret, sensor_count;
1029 	struct ec_params_motion_sense *params;
1030 	struct ec_response_motion_sense *resp;
1031 	struct cros_ec_command *msg;
1032 	struct cros_ec_device *ec_dev = ec->ec_dev;
1033 	u8 status;
1034 
1035 	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*resp)),
1036 		      GFP_KERNEL);
1037 	if (!msg)
1038 		return -ENOMEM;
1039 
1040 	msg->version = 1;
1041 	msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
1042 	msg->outsize = sizeof(*params);
1043 	msg->insize = sizeof(*resp);
1044 
1045 	params = (struct ec_params_motion_sense *)msg->data;
1046 	params->cmd = MOTIONSENSE_CMD_DUMP;
1047 
1048 	ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
1049 	if (ret < 0) {
1050 		sensor_count = ret;
1051 	} else {
1052 		resp = (struct ec_response_motion_sense *)msg->data;
1053 		sensor_count = resp->dump.sensor_count;
1054 	}
1055 	kfree(msg);
1056 
1057 	/*
1058 	 * Check legacy mode: Let's find out if sensors are accessible
1059 	 * via LPC interface.
1060 	 */
1061 	if (sensor_count < 0 && ec->cmd_offset == 0 && ec_dev->cmd_readmem) {
1062 		ret = ec_dev->cmd_readmem(ec_dev, EC_MEMMAP_ACC_STATUS,
1063 				1, &status);
1064 		if (ret >= 0 &&
1065 		    (status & EC_MEMMAP_ACC_STATUS_PRESENCE_BIT)) {
1066 			/*
1067 			 * We have 2 sensors, one in the lid, one in the base.
1068 			 */
1069 			sensor_count = 2;
1070 		} else {
1071 			/*
1072 			 * EC uses LPC interface and no sensors are presented.
1073 			 */
1074 			sensor_count = 0;
1075 		}
1076 	}
1077 	return sensor_count;
1078 }
1079 EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);
1080 
1081 /**
1082  * cros_ec_cmd - Send a command to the EC.
1083  *
1084  * @ec_dev: EC device
1085  * @version: EC command version
1086  * @command: EC command
1087  * @outdata: EC command output data
1088  * @outsize: Size of outdata
1089  * @indata: EC command input data
1090  * @insize: Size of indata
1091  *
1092  * Return: >= 0 on success, negative error number on failure.
1093  */
cros_ec_cmd(struct cros_ec_device * ec_dev,unsigned int version,int command,const void * outdata,size_t outsize,void * indata,size_t insize)1094 int cros_ec_cmd(struct cros_ec_device *ec_dev,
1095 		unsigned int version,
1096 		int command,
1097 		const void *outdata,
1098 		size_t outsize,
1099 		void *indata,
1100 		size_t insize)
1101 {
1102 	struct cros_ec_command *msg;
1103 	int ret;
1104 
1105 	msg = kzalloc(sizeof(*msg) + max(insize, outsize), GFP_KERNEL);
1106 	if (!msg)
1107 		return -ENOMEM;
1108 
1109 	msg->version = version;
1110 	msg->command = command;
1111 	msg->outsize = outsize;
1112 	msg->insize = insize;
1113 
1114 	if (outsize)
1115 		memcpy(msg->data, outdata, outsize);
1116 
1117 	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
1118 	if (ret < 0)
1119 		goto error;
1120 
1121 	if (insize)
1122 		memcpy(indata, msg->data, insize);
1123 error:
1124 	kfree(msg);
1125 	return ret;
1126 }
1127 EXPORT_SYMBOL_GPL(cros_ec_cmd);
1128 
1129 /**
1130  * cros_ec_cmd_readmem - Read from EC memory.
1131  *
1132  * @ec_dev: EC device
1133  * @offset: Is within EC_LPC_ADDR_MEMMAP region.
1134  * @size: Number of bytes to read.
1135  * @dest: EC command output data
1136  *
1137  * Return: >= 0 on success, negative error number on failure.
1138  */
cros_ec_cmd_readmem(struct cros_ec_device * ec_dev,u8 offset,u8 size,void * dest)1139 int cros_ec_cmd_readmem(struct cros_ec_device *ec_dev, u8 offset, u8 size, void *dest)
1140 {
1141 	struct ec_params_read_memmap params = {};
1142 
1143 	if (!size)
1144 		return -EINVAL;
1145 
1146 	if (ec_dev->cmd_readmem)
1147 		return ec_dev->cmd_readmem(ec_dev, offset, size, dest);
1148 
1149 	params.offset = offset;
1150 	params.size = size;
1151 	return cros_ec_cmd(ec_dev, 0, EC_CMD_READ_MEMMAP,
1152 			   &params, sizeof(params), dest, size);
1153 }
1154 EXPORT_SYMBOL_GPL(cros_ec_cmd_readmem);
1155 
1156 /**
1157  * cros_ec_get_cmd_versions - Get supported version mask.
1158  *
1159  * @ec_dev: EC device
1160  * @cmd: Command to test
1161  *
1162  * Return: version mask on success, negative error number on failure.
1163  */
cros_ec_get_cmd_versions(struct cros_ec_device * ec_dev,u16 cmd)1164 int cros_ec_get_cmd_versions(struct cros_ec_device *ec_dev, u16 cmd)
1165 {
1166 	struct ec_params_get_cmd_versions req_v0;
1167 	struct ec_params_get_cmd_versions_v1 req_v1;
1168 	struct ec_response_get_cmd_versions resp;
1169 	int ret;
1170 
1171 	if (cmd <= U8_MAX) {
1172 		req_v0.cmd = cmd;
1173 		ret = cros_ec_cmd(ec_dev, 0, EC_CMD_GET_CMD_VERSIONS,
1174 				  &req_v0, sizeof(req_v0), &resp, sizeof(resp));
1175 	} else {
1176 		req_v1.cmd = cmd;
1177 		ret = cros_ec_cmd(ec_dev, 1, EC_CMD_GET_CMD_VERSIONS,
1178 				  &req_v1, sizeof(req_v1), &resp, sizeof(resp));
1179 	}
1180 
1181 	if (ret == -EINVAL)
1182 		return 0; /* Command not implemented */
1183 	else if (ret < 0)
1184 		return ret;
1185 	else
1186 		return resp.version_mask;
1187 }
1188 EXPORT_SYMBOL_GPL(cros_ec_get_cmd_versions);
1189 
1190 /**
1191  * cros_ec_device_registered - Return if the ec_dev is registered.
1192  *
1193  * @ec_dev: EC device
1194  *
1195  * Return: true if registered.  Otherwise, false.
1196  */
cros_ec_device_registered(struct cros_ec_device * ec_dev)1197 bool cros_ec_device_registered(struct cros_ec_device *ec_dev)
1198 {
1199 	guard(mutex)(&ec_dev->lock);
1200 	return ec_dev->registered;
1201 }
1202 EXPORT_SYMBOL_GPL(cros_ec_device_registered);
1203 
1204 MODULE_LICENSE("GPL");
1205 MODULE_DESCRIPTION("ChromeOS EC communication protocol helpers");
1206