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