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