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/delay.h>
7 #include <linux/device.h>
8 #include <linux/module.h>
9 #include <linux/platform_data/cros_ec_commands.h>
10 #include <linux/platform_data/cros_ec_proto.h>
11 #include <linux/slab.h>
12 #include <asm/unaligned.h>
13 
14 #include "cros_ec_trace.h"
15 
16 #define EC_COMMAND_RETRIES	50
17 
18 static int prepare_packet(struct cros_ec_device *ec_dev,
19 			  struct cros_ec_command *msg)
20 {
21 	struct ec_host_request *request;
22 	u8 *out;
23 	int i;
24 	u8 csum = 0;
25 
26 	BUG_ON(ec_dev->proto_version != EC_HOST_REQUEST_VERSION);
27 	BUG_ON(msg->outsize + sizeof(*request) > ec_dev->dout_size);
28 
29 	out = ec_dev->dout;
30 	request = (struct ec_host_request *)out;
31 	request->struct_version = EC_HOST_REQUEST_VERSION;
32 	request->checksum = 0;
33 	request->command = msg->command;
34 	request->command_version = msg->version;
35 	request->reserved = 0;
36 	request->data_len = msg->outsize;
37 
38 	for (i = 0; i < sizeof(*request); i++)
39 		csum += out[i];
40 
41 	/* Copy data and update checksum */
42 	memcpy(out + sizeof(*request), msg->data, msg->outsize);
43 	for (i = 0; i < msg->outsize; i++)
44 		csum += msg->data[i];
45 
46 	request->checksum = -csum;
47 
48 	return sizeof(*request) + msg->outsize;
49 }
50 
51 static int send_command(struct cros_ec_device *ec_dev,
52 			struct cros_ec_command *msg)
53 {
54 	int ret;
55 	int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
56 
57 	if (ec_dev->proto_version > 2)
58 		xfer_fxn = ec_dev->pkt_xfer;
59 	else
60 		xfer_fxn = ec_dev->cmd_xfer;
61 
62 	if (!xfer_fxn) {
63 		/*
64 		 * This error can happen if a communication error happened and
65 		 * the EC is trying to use protocol v2, on an underlying
66 		 * communication mechanism that does not support v2.
67 		 */
68 		dev_err_once(ec_dev->dev,
69 			     "missing EC transfer API, cannot send command\n");
70 		return -EIO;
71 	}
72 
73 	trace_cros_ec_request_start(msg);
74 	ret = (*xfer_fxn)(ec_dev, msg);
75 	trace_cros_ec_request_done(msg, ret);
76 	if (msg->result == EC_RES_IN_PROGRESS) {
77 		int i;
78 		struct cros_ec_command *status_msg;
79 		struct ec_response_get_comms_status *status;
80 
81 		status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
82 				     GFP_KERNEL);
83 		if (!status_msg)
84 			return -ENOMEM;
85 
86 		status_msg->version = 0;
87 		status_msg->command = EC_CMD_GET_COMMS_STATUS;
88 		status_msg->insize = sizeof(*status);
89 		status_msg->outsize = 0;
90 
91 		/*
92 		 * Query the EC's status until it's no longer busy or
93 		 * we encounter an error.
94 		 */
95 		for (i = 0; i < EC_COMMAND_RETRIES; i++) {
96 			usleep_range(10000, 11000);
97 
98 			trace_cros_ec_request_start(status_msg);
99 			ret = (*xfer_fxn)(ec_dev, status_msg);
100 			trace_cros_ec_request_done(status_msg, ret);
101 			if (ret == -EAGAIN)
102 				continue;
103 			if (ret < 0)
104 				break;
105 
106 			msg->result = status_msg->result;
107 			if (status_msg->result != EC_RES_SUCCESS)
108 				break;
109 
110 			status = (struct ec_response_get_comms_status *)
111 				 status_msg->data;
112 			if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
113 				break;
114 		}
115 
116 		kfree(status_msg);
117 	}
118 
119 	return ret;
120 }
121 
122 /**
123  * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer.
124  * @ec_dev: Device to register.
125  * @msg: Message to write.
126  *
127  * This is intended to be used by all ChromeOS EC drivers, but at present
128  * only SPI uses it. Once LPC uses the same protocol it can start using it.
129  * I2C could use it now, with a refactor of the existing code.
130  *
131  * Return: 0 on success or negative error code.
132  */
133 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
134 		       struct cros_ec_command *msg)
135 {
136 	u8 *out;
137 	u8 csum;
138 	int i;
139 
140 	if (ec_dev->proto_version > 2)
141 		return prepare_packet(ec_dev, msg);
142 
143 	BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
144 	out = ec_dev->dout;
145 	out[0] = EC_CMD_VERSION0 + msg->version;
146 	out[1] = msg->command;
147 	out[2] = msg->outsize;
148 	csum = out[0] + out[1] + out[2];
149 	for (i = 0; i < msg->outsize; i++)
150 		csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
151 	out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
152 
153 	return EC_MSG_TX_PROTO_BYTES + msg->outsize;
154 }
155 EXPORT_SYMBOL(cros_ec_prepare_tx);
156 
157 /**
158  * cros_ec_check_result() - Check ec_msg->result.
159  * @ec_dev: EC device.
160  * @msg: Message to check.
161  *
162  * This is used by ChromeOS EC drivers to check the ec_msg->result for
163  * errors and to warn about them.
164  *
165  * Return: 0 on success or negative error code.
166  */
167 int cros_ec_check_result(struct cros_ec_device *ec_dev,
168 			 struct cros_ec_command *msg)
169 {
170 	switch (msg->result) {
171 	case EC_RES_SUCCESS:
172 		return 0;
173 	case EC_RES_IN_PROGRESS:
174 		dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
175 			msg->command);
176 		return -EAGAIN;
177 	default:
178 		dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
179 			msg->command, msg->result);
180 		return 0;
181 	}
182 }
183 EXPORT_SYMBOL(cros_ec_check_result);
184 
185 /*
186  * cros_ec_get_host_event_wake_mask
187  *
188  * Get the mask of host events that cause wake from suspend.
189  *
190  * @ec_dev: EC device to call
191  * @msg: message structure to use
192  * @mask: result when function returns >=0.
193  *
194  * LOCKING:
195  * the caller has ec_dev->lock mutex, or the caller knows there is
196  * no other command in progress.
197  */
198 static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,
199 					    struct cros_ec_command *msg,
200 					    uint32_t *mask)
201 {
202 	struct ec_response_host_event_mask *r;
203 	int ret;
204 
205 	msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
206 	msg->version = 0;
207 	msg->outsize = 0;
208 	msg->insize = sizeof(*r);
209 
210 	ret = send_command(ec_dev, msg);
211 	if (ret >= 0) {
212 		if (msg->result == EC_RES_INVALID_COMMAND)
213 			return -EOPNOTSUPP;
214 		if (msg->result != EC_RES_SUCCESS)
215 			return -EPROTO;
216 	}
217 	if (ret > 0) {
218 		r = (struct ec_response_host_event_mask *)msg->data;
219 		*mask = r->mask;
220 	}
221 
222 	return ret;
223 }
224 
225 static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
226 					    int devidx,
227 					    struct cros_ec_command *msg)
228 {
229 	/*
230 	 * Try using v3+ to query for supported protocols. If this
231 	 * command fails, fall back to v2. Returns the highest protocol
232 	 * supported by the EC.
233 	 * Also sets the max request/response/passthru size.
234 	 */
235 	int ret;
236 
237 	if (!ec_dev->pkt_xfer)
238 		return -EPROTONOSUPPORT;
239 
240 	memset(msg, 0, sizeof(*msg));
241 	msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
242 	msg->insize = sizeof(struct ec_response_get_protocol_info);
243 
244 	ret = send_command(ec_dev, msg);
245 
246 	if (ret < 0) {
247 		dev_dbg(ec_dev->dev,
248 			"failed to check for EC[%d] protocol version: %d\n",
249 			devidx, ret);
250 		return ret;
251 	}
252 
253 	if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)
254 		return -ENODEV;
255 	else if (msg->result != EC_RES_SUCCESS)
256 		return msg->result;
257 
258 	return 0;
259 }
260 
261 static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
262 {
263 	struct cros_ec_command *msg;
264 	struct ec_params_hello *hello_params;
265 	struct ec_response_hello *hello_response;
266 	int ret;
267 	int len = max(sizeof(*hello_params), sizeof(*hello_response));
268 
269 	msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
270 	if (!msg)
271 		return -ENOMEM;
272 
273 	msg->version = 0;
274 	msg->command = EC_CMD_HELLO;
275 	hello_params = (struct ec_params_hello *)msg->data;
276 	msg->outsize = sizeof(*hello_params);
277 	hello_response = (struct ec_response_hello *)msg->data;
278 	msg->insize = sizeof(*hello_response);
279 
280 	hello_params->in_data = 0xa0b0c0d0;
281 
282 	ret = send_command(ec_dev, msg);
283 
284 	if (ret < 0) {
285 		dev_dbg(ec_dev->dev,
286 			"EC failed to respond to v2 hello: %d\n",
287 			ret);
288 		goto exit;
289 	} else if (msg->result != EC_RES_SUCCESS) {
290 		dev_err(ec_dev->dev,
291 			"EC responded to v2 hello with error: %d\n",
292 			msg->result);
293 		ret = msg->result;
294 		goto exit;
295 	} else if (hello_response->out_data != 0xa1b2c3d4) {
296 		dev_err(ec_dev->dev,
297 			"EC responded to v2 hello with bad result: %u\n",
298 			hello_response->out_data);
299 		ret = -EBADMSG;
300 		goto exit;
301 	}
302 
303 	ret = 0;
304 
305  exit:
306 	kfree(msg);
307 	return ret;
308 }
309 
310 /*
311  * cros_ec_get_host_command_version_mask
312  *
313  * Get the version mask of a given command.
314  *
315  * @ec_dev: EC device to call
316  * @msg: message structure to use
317  * @cmd: command to get the version of.
318  * @mask: result when function returns 0.
319  *
320  * @return 0 on success, error code otherwise
321  *
322  * LOCKING:
323  * the caller has ec_dev->lock mutex or the caller knows there is
324  * no other command in progress.
325  */
326 static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,
327 	u16 cmd, u32 *mask)
328 {
329 	struct ec_params_get_cmd_versions *pver;
330 	struct ec_response_get_cmd_versions *rver;
331 	struct cros_ec_command *msg;
332 	int ret;
333 
334 	msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
335 		      GFP_KERNEL);
336 	if (!msg)
337 		return -ENOMEM;
338 
339 	msg->version = 0;
340 	msg->command = EC_CMD_GET_CMD_VERSIONS;
341 	msg->insize = sizeof(*rver);
342 	msg->outsize = sizeof(*pver);
343 
344 	pver = (struct ec_params_get_cmd_versions *)msg->data;
345 	pver->cmd = cmd;
346 
347 	ret = send_command(ec_dev, msg);
348 	if (ret > 0) {
349 		rver = (struct ec_response_get_cmd_versions *)msg->data;
350 		*mask = rver->version_mask;
351 	}
352 
353 	kfree(msg);
354 
355 	return ret;
356 }
357 
358 /**
359  * cros_ec_query_all() -  Query the protocol version supported by the
360  *         ChromeOS EC.
361  * @ec_dev: Device to register.
362  *
363  * Return: 0 on success or negative error code.
364  */
365 int cros_ec_query_all(struct cros_ec_device *ec_dev)
366 {
367 	struct device *dev = ec_dev->dev;
368 	struct cros_ec_command *proto_msg;
369 	struct ec_response_get_protocol_info *proto_info;
370 	u32 ver_mask = 0;
371 	int ret;
372 
373 	proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
374 			    GFP_KERNEL);
375 	if (!proto_msg)
376 		return -ENOMEM;
377 
378 	/* First try sending with proto v3. */
379 	ec_dev->proto_version = 3;
380 	ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);
381 
382 	if (ret == 0) {
383 		proto_info = (struct ec_response_get_protocol_info *)
384 			proto_msg->data;
385 		ec_dev->max_request = proto_info->max_request_packet_size -
386 			sizeof(struct ec_host_request);
387 		ec_dev->max_response = proto_info->max_response_packet_size -
388 			sizeof(struct ec_host_response);
389 		ec_dev->proto_version =
390 			min(EC_HOST_REQUEST_VERSION,
391 					fls(proto_info->protocol_versions) - 1);
392 		dev_dbg(ec_dev->dev,
393 			"using proto v%u\n",
394 			ec_dev->proto_version);
395 
396 		ec_dev->din_size = ec_dev->max_response +
397 			sizeof(struct ec_host_response) +
398 			EC_MAX_RESPONSE_OVERHEAD;
399 		ec_dev->dout_size = ec_dev->max_request +
400 			sizeof(struct ec_host_request) +
401 			EC_MAX_REQUEST_OVERHEAD;
402 
403 		/*
404 		 * Check for PD
405 		 */
406 		ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
407 
408 		if (ret) {
409 			dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
410 			ec_dev->max_passthru = 0;
411 		} else {
412 			dev_dbg(ec_dev->dev, "found PD chip\n");
413 			ec_dev->max_passthru =
414 				proto_info->max_request_packet_size -
415 				sizeof(struct ec_host_request);
416 		}
417 	} else {
418 		/* Try querying with a v2 hello message. */
419 		ec_dev->proto_version = 2;
420 		ret = cros_ec_host_command_proto_query_v2(ec_dev);
421 
422 		if (ret == 0) {
423 			/* V2 hello succeeded. */
424 			dev_dbg(ec_dev->dev, "falling back to proto v2\n");
425 
426 			ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
427 			ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
428 			ec_dev->max_passthru = 0;
429 			ec_dev->pkt_xfer = NULL;
430 			ec_dev->din_size = EC_PROTO2_MSG_BYTES;
431 			ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
432 		} else {
433 			/*
434 			 * It's possible for a test to occur too early when
435 			 * the EC isn't listening. If this happens, we'll
436 			 * test later when the first command is run.
437 			 */
438 			ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
439 			dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
440 			goto exit;
441 		}
442 	}
443 
444 	devm_kfree(dev, ec_dev->din);
445 	devm_kfree(dev, ec_dev->dout);
446 
447 	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
448 	if (!ec_dev->din) {
449 		ret = -ENOMEM;
450 		goto exit;
451 	}
452 
453 	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
454 	if (!ec_dev->dout) {
455 		devm_kfree(dev, ec_dev->din);
456 		ret = -ENOMEM;
457 		goto exit;
458 	}
459 
460 	/* Probe if MKBP event is supported */
461 	ret = cros_ec_get_host_command_version_mask(ec_dev,
462 						    EC_CMD_GET_NEXT_EVENT,
463 						    &ver_mask);
464 	if (ret < 0 || ver_mask == 0)
465 		ec_dev->mkbp_event_supported = 0;
466 	else
467 		ec_dev->mkbp_event_supported = fls(ver_mask);
468 
469 	dev_dbg(ec_dev->dev, "MKBP support version %u\n",
470 		ec_dev->mkbp_event_supported - 1);
471 
472 	/* Probe if host sleep v1 is supported for S0ix failure detection. */
473 	ret = cros_ec_get_host_command_version_mask(ec_dev,
474 						    EC_CMD_HOST_SLEEP_EVENT,
475 						    &ver_mask);
476 	ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1)));
477 
478 	/* Get host event wake mask. */
479 	ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,
480 					       &ec_dev->host_event_wake_mask);
481 	if (ret < 0) {
482 		/*
483 		 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,
484 		 * use a reasonable default. Note that we ignore various
485 		 * battery, AC status, and power-state events, because (a)
486 		 * those can be quite common (e.g., when sitting at full
487 		 * charge, on AC) and (b) these are not actionable wake events;
488 		 * if anything, we'd like to continue suspending (to save
489 		 * power), not wake up.
490 		 */
491 		ec_dev->host_event_wake_mask = U32_MAX &
492 			~(BIT(EC_HOST_EVENT_AC_DISCONNECTED) |
493 			  BIT(EC_HOST_EVENT_BATTERY_LOW) |
494 			  BIT(EC_HOST_EVENT_BATTERY_CRITICAL) |
495 			  BIT(EC_HOST_EVENT_PD_MCU) |
496 			  BIT(EC_HOST_EVENT_BATTERY_STATUS));
497 		/*
498 		 * Old ECs may not support this command. Complain about all
499 		 * other errors.
500 		 */
501 		if (ret != -EOPNOTSUPP)
502 			dev_err(ec_dev->dev,
503 				"failed to retrieve wake mask: %d\n", ret);
504 	}
505 
506 	ret = 0;
507 
508 exit:
509 	kfree(proto_msg);
510 	return ret;
511 }
512 EXPORT_SYMBOL(cros_ec_query_all);
513 
514 /**
515  * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC.
516  * @ec_dev: EC device.
517  * @msg: Message to write.
518  *
519  * Call this to send a command to the ChromeOS EC.  This should be used
520  * instead of calling the EC's cmd_xfer() callback directly.
521  *
522  * Return: 0 on success or negative error code.
523  */
524 static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
525 			    struct cros_ec_command *msg)
526 {
527 	int ret;
528 
529 	mutex_lock(&ec_dev->lock);
530 	if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
531 		ret = cros_ec_query_all(ec_dev);
532 		if (ret) {
533 			dev_err(ec_dev->dev,
534 				"EC version unknown and query failed; aborting command\n");
535 			mutex_unlock(&ec_dev->lock);
536 			return ret;
537 		}
538 	}
539 
540 	if (msg->insize > ec_dev->max_response) {
541 		dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
542 		msg->insize = ec_dev->max_response;
543 	}
544 
545 	if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
546 		if (msg->outsize > ec_dev->max_request) {
547 			dev_err(ec_dev->dev,
548 				"request of size %u is too big (max: %u)\n",
549 				msg->outsize,
550 				ec_dev->max_request);
551 			mutex_unlock(&ec_dev->lock);
552 			return -EMSGSIZE;
553 		}
554 	} else {
555 		if (msg->outsize > ec_dev->max_passthru) {
556 			dev_err(ec_dev->dev,
557 				"passthru rq of size %u is too big (max: %u)\n",
558 				msg->outsize,
559 				ec_dev->max_passthru);
560 			mutex_unlock(&ec_dev->lock);
561 			return -EMSGSIZE;
562 		}
563 	}
564 	ret = send_command(ec_dev, msg);
565 	mutex_unlock(&ec_dev->lock);
566 
567 	return ret;
568 }
569 
570 /**
571  * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC.
572  * @ec_dev: EC device.
573  * @msg: Message to write.
574  *
575  * This function is identical to cros_ec_cmd_xfer, except it returns success
576  * status only if both the command was transmitted successfully and the EC
577  * replied with success status. It's not necessary to check msg->result when
578  * using this function.
579  *
580  * Return:
581  * >=0 - The number of bytes transferred
582  * -ENOTSUPP - Operation not supported
583  * -EPROTO - Protocol error
584  */
585 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
586 			    struct cros_ec_command *msg)
587 {
588 	int ret;
589 
590 	ret = cros_ec_cmd_xfer(ec_dev, msg);
591 	if (ret < 0) {
592 		dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret);
593 	} else if (msg->result == EC_RES_INVALID_VERSION) {
594 		dev_dbg(ec_dev->dev, "Command invalid version (err:%d)\n",
595 			msg->result);
596 		return -ENOTSUPP;
597 	} else if (msg->result != EC_RES_SUCCESS) {
598 		dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result);
599 		return -EPROTO;
600 	}
601 
602 	return ret;
603 }
604 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
605 
606 static int get_next_event_xfer(struct cros_ec_device *ec_dev,
607 			       struct cros_ec_command *msg,
608 			       struct ec_response_get_next_event_v1 *event,
609 			       int version, uint32_t size)
610 {
611 	int ret;
612 
613 	msg->version = version;
614 	msg->command = EC_CMD_GET_NEXT_EVENT;
615 	msg->insize = size;
616 	msg->outsize = 0;
617 
618 	ret = cros_ec_cmd_xfer(ec_dev, msg);
619 	if (ret > 0) {
620 		ec_dev->event_size = ret - 1;
621 		ec_dev->event_data = *event;
622 	}
623 
624 	return ret;
625 }
626 
627 static int get_next_event(struct cros_ec_device *ec_dev)
628 {
629 	struct {
630 		struct cros_ec_command msg;
631 		struct ec_response_get_next_event_v1 event;
632 	} __packed buf;
633 	struct cros_ec_command *msg = &buf.msg;
634 	struct ec_response_get_next_event_v1 *event = &buf.event;
635 	const int cmd_version = ec_dev->mkbp_event_supported - 1;
636 
637 	memset(msg, 0, sizeof(*msg));
638 	if (ec_dev->suspended) {
639 		dev_dbg(ec_dev->dev, "Device suspended.\n");
640 		return -EHOSTDOWN;
641 	}
642 
643 	if (cmd_version == 0)
644 		return get_next_event_xfer(ec_dev, msg, event, 0,
645 				  sizeof(struct ec_response_get_next_event));
646 
647 	return get_next_event_xfer(ec_dev, msg, event, cmd_version,
648 				sizeof(struct ec_response_get_next_event_v1));
649 }
650 
651 static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
652 {
653 	u8 buffer[sizeof(struct cros_ec_command) +
654 		  sizeof(ec_dev->event_data.data)];
655 	struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
656 
657 	msg->version = 0;
658 	msg->command = EC_CMD_MKBP_STATE;
659 	msg->insize = sizeof(ec_dev->event_data.data);
660 	msg->outsize = 0;
661 
662 	ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg);
663 	ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX;
664 	memcpy(&ec_dev->event_data.data, msg->data,
665 	       sizeof(ec_dev->event_data.data));
666 
667 	return ec_dev->event_size;
668 }
669 
670 /**
671  * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC.
672  * @ec_dev: Device to fetch event from.
673  * @wake_event: Pointer to a bool set to true upon return if the event might be
674  *              treated as a wake event. Ignored if null.
675  * @has_more_events: Pointer to bool set to true if more than one event is
676  *              pending.
677  *              Some EC will set this flag to indicate cros_ec_get_next_event()
678  *              can be called multiple times in a row.
679  *              It is an optimization to prevent issuing a EC command for
680  *              nothing or wait for another interrupt from the EC to process
681  *              the next message.
682  *              Ignored if null.
683  *
684  * Return: negative error code on errors; 0 for no data; or else number of
685  * bytes received (i.e., an event was retrieved successfully). Event types are
686  * written out to @ec_dev->event_data.event_type on success.
687  */
688 int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
689 			   bool *wake_event,
690 			   bool *has_more_events)
691 {
692 	u8 event_type;
693 	u32 host_event;
694 	int ret;
695 
696 	/*
697 	 * Default value for wake_event.
698 	 * Wake up on keyboard event, wake up for spurious interrupt or link
699 	 * error to the EC.
700 	 */
701 	if (wake_event)
702 		*wake_event = true;
703 
704 	/*
705 	 * Default value for has_more_events.
706 	 * EC will raise another interrupt if AP does not process all events
707 	 * anyway.
708 	 */
709 	if (has_more_events)
710 		*has_more_events = false;
711 
712 	if (!ec_dev->mkbp_event_supported)
713 		return get_keyboard_state_event(ec_dev);
714 
715 	ret = get_next_event(ec_dev);
716 	if (ret <= 0)
717 		return ret;
718 
719 	if (has_more_events)
720 		*has_more_events = ec_dev->event_data.event_type &
721 			EC_MKBP_HAS_MORE_EVENTS;
722 	ec_dev->event_data.event_type &= EC_MKBP_EVENT_TYPE_MASK;
723 
724 	if (wake_event) {
725 		event_type = ec_dev->event_data.event_type;
726 		host_event = cros_ec_get_host_event(ec_dev);
727 
728 		/*
729 		 * Sensor events need to be parsed by the sensor sub-device.
730 		 * Defer them, and don't report the wakeup here.
731 		 */
732 		if (event_type == EC_MKBP_EVENT_SENSOR_FIFO)
733 			*wake_event = false;
734 		/* Masked host-events should not count as wake events. */
735 		else if (host_event &&
736 			 !(host_event & ec_dev->host_event_wake_mask))
737 			*wake_event = false;
738 	}
739 
740 	return ret;
741 }
742 EXPORT_SYMBOL(cros_ec_get_next_event);
743 
744 /**
745  * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC.
746  * @ec_dev: Device to fetch event from.
747  *
748  * When MKBP is supported, when the EC raises an interrupt, we collect the
749  * events raised and call the functions in the ec notifier. This function
750  * is a helper to know which events are raised.
751  *
752  * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*.
753  */
754 u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev)
755 {
756 	u32 host_event;
757 
758 	BUG_ON(!ec_dev->mkbp_event_supported);
759 
760 	if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT)
761 		return 0;
762 
763 	if (ec_dev->event_size != sizeof(host_event)) {
764 		dev_warn(ec_dev->dev, "Invalid host event size\n");
765 		return 0;
766 	}
767 
768 	host_event = get_unaligned_le32(&ec_dev->event_data.data.host_event);
769 
770 	return host_event;
771 }
772 EXPORT_SYMBOL(cros_ec_get_host_event);
773 
774 /**
775  * cros_ec_check_features() - Test for the presence of EC features
776  *
777  * @ec: EC device, does not have to be connected directly to the AP,
778  *      can be daisy chained through another device.
779  * @feature: One of ec_feature_code bit.
780  *
781  * Call this function to test whether the ChromeOS EC supports a feature.
782  *
783  * Return: 1 if supported, 0 if not
784  */
785 int cros_ec_check_features(struct cros_ec_dev *ec, int feature)
786 {
787 	struct cros_ec_command *msg;
788 	int ret;
789 
790 	if (ec->features[0] == -1U && ec->features[1] == -1U) {
791 		/* features bitmap not read yet */
792 		msg = kzalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL);
793 		if (!msg)
794 			return -ENOMEM;
795 
796 		msg->command = EC_CMD_GET_FEATURES + ec->cmd_offset;
797 		msg->insize = sizeof(ec->features);
798 
799 		ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
800 		if (ret < 0) {
801 			dev_warn(ec->dev, "cannot get EC features: %d/%d\n",
802 				 ret, msg->result);
803 			memset(ec->features, 0, sizeof(ec->features));
804 		} else {
805 			memcpy(ec->features, msg->data, sizeof(ec->features));
806 		}
807 
808 		dev_dbg(ec->dev, "EC features %08x %08x\n",
809 			ec->features[0], ec->features[1]);
810 
811 		kfree(msg);
812 	}
813 
814 	return ec->features[feature / 32] & EC_FEATURE_MASK_0(feature);
815 }
816 EXPORT_SYMBOL_GPL(cros_ec_check_features);
817 
818 /**
819  * cros_ec_get_sensor_count() - Return the number of MEMS sensors supported.
820  *
821  * @ec: EC device, does not have to be connected directly to the AP,
822  *      can be daisy chained through another device.
823  * Return: < 0 in case of error.
824  */
825 int cros_ec_get_sensor_count(struct cros_ec_dev *ec)
826 {
827 	/*
828 	 * Issue a command to get the number of sensor reported.
829 	 * If not supported, check for legacy mode.
830 	 */
831 	int ret, sensor_count;
832 	struct ec_params_motion_sense *params;
833 	struct ec_response_motion_sense *resp;
834 	struct cros_ec_command *msg;
835 	struct cros_ec_device *ec_dev = ec->ec_dev;
836 	u8 status;
837 
838 	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*resp)),
839 		      GFP_KERNEL);
840 	if (!msg)
841 		return -ENOMEM;
842 
843 	msg->version = 1;
844 	msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
845 	msg->outsize = sizeof(*params);
846 	msg->insize = sizeof(*resp);
847 
848 	params = (struct ec_params_motion_sense *)msg->data;
849 	params->cmd = MOTIONSENSE_CMD_DUMP;
850 
851 	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
852 	if (ret < 0) {
853 		sensor_count = ret;
854 	} else if (msg->result != EC_RES_SUCCESS) {
855 		sensor_count = -EPROTO;
856 	} else {
857 		resp = (struct ec_response_motion_sense *)msg->data;
858 		sensor_count = resp->dump.sensor_count;
859 	}
860 	kfree(msg);
861 
862 	/*
863 	 * Check legacy mode: Let's find out if sensors are accessible
864 	 * via LPC interface.
865 	 */
866 	if (sensor_count == -EPROTO &&
867 	    ec->cmd_offset == 0 &&
868 	    ec_dev->cmd_readmem) {
869 		ret = ec_dev->cmd_readmem(ec_dev, EC_MEMMAP_ACC_STATUS,
870 				1, &status);
871 		if (ret >= 0 &&
872 		    (status & EC_MEMMAP_ACC_STATUS_PRESENCE_BIT)) {
873 			/*
874 			 * We have 2 sensors, one in the lid, one in the base.
875 			 */
876 			sensor_count = 2;
877 		} else {
878 			/*
879 			 * EC uses LPC interface and no sensors are presented.
880 			 */
881 			sensor_count = 0;
882 		}
883 	} else if (sensor_count == -EPROTO) {
884 		/* EC responded, but does not understand DUMP command. */
885 		sensor_count = 0;
886 	}
887 	return sensor_count;
888 }
889 EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);
890