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/mfd/cros_ec.h> 7 #include <linux/delay.h> 8 #include <linux/device.h> 9 #include <linux/module.h> 10 #include <linux/slab.h> 11 #include <asm/unaligned.h> 12 13 #include "cros_ec_trace.h" 14 15 #define EC_COMMAND_RETRIES 50 16 17 static int prepare_packet(struct cros_ec_device *ec_dev, 18 struct cros_ec_command *msg) 19 { 20 struct ec_host_request *request; 21 u8 *out; 22 int i; 23 u8 csum = 0; 24 25 BUG_ON(ec_dev->proto_version != EC_HOST_REQUEST_VERSION); 26 BUG_ON(msg->outsize + sizeof(*request) > ec_dev->dout_size); 27 28 out = ec_dev->dout; 29 request = (struct ec_host_request *)out; 30 request->struct_version = EC_HOST_REQUEST_VERSION; 31 request->checksum = 0; 32 request->command = msg->command; 33 request->command_version = msg->version; 34 request->reserved = 0; 35 request->data_len = msg->outsize; 36 37 for (i = 0; i < sizeof(*request); i++) 38 csum += out[i]; 39 40 /* Copy data and update checksum */ 41 memcpy(out + sizeof(*request), msg->data, msg->outsize); 42 for (i = 0; i < msg->outsize; i++) 43 csum += msg->data[i]; 44 45 request->checksum = -csum; 46 47 return sizeof(*request) + msg->outsize; 48 } 49 50 static int send_command(struct cros_ec_device *ec_dev, 51 struct cros_ec_command *msg) 52 { 53 int ret; 54 int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg); 55 56 trace_cros_ec_cmd(msg); 57 58 if (ec_dev->proto_version > 2) 59 xfer_fxn = ec_dev->pkt_xfer; 60 else 61 xfer_fxn = ec_dev->cmd_xfer; 62 63 if (!xfer_fxn) { 64 /* 65 * This error can happen if a communication error happened and 66 * the EC is trying to use protocol v2, on an underlying 67 * communication mechanism that does not support v2. 68 */ 69 dev_err_once(ec_dev->dev, 70 "missing EC transfer API, cannot send command\n"); 71 return -EIO; 72 } 73 74 ret = (*xfer_fxn)(ec_dev, msg); 75 if (msg->result == EC_RES_IN_PROGRESS) { 76 int i; 77 struct cros_ec_command *status_msg; 78 struct ec_response_get_comms_status *status; 79 80 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status), 81 GFP_KERNEL); 82 if (!status_msg) 83 return -ENOMEM; 84 85 status_msg->version = 0; 86 status_msg->command = EC_CMD_GET_COMMS_STATUS; 87 status_msg->insize = sizeof(*status); 88 status_msg->outsize = 0; 89 90 /* 91 * Query the EC's status until it's no longer busy or 92 * we encounter an error. 93 */ 94 for (i = 0; i < EC_COMMAND_RETRIES; i++) { 95 usleep_range(10000, 11000); 96 97 ret = (*xfer_fxn)(ec_dev, status_msg); 98 if (ret == -EAGAIN) 99 continue; 100 if (ret < 0) 101 break; 102 103 msg->result = status_msg->result; 104 if (status_msg->result != EC_RES_SUCCESS) 105 break; 106 107 status = (struct ec_response_get_comms_status *) 108 status_msg->data; 109 if (!(status->flags & EC_COMMS_STATUS_PROCESSING)) 110 break; 111 } 112 113 kfree(status_msg); 114 } 115 116 return ret; 117 } 118 119 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, 120 struct cros_ec_command *msg) 121 { 122 u8 *out; 123 u8 csum; 124 int i; 125 126 if (ec_dev->proto_version > 2) 127 return prepare_packet(ec_dev, msg); 128 129 BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE); 130 out = ec_dev->dout; 131 out[0] = EC_CMD_VERSION0 + msg->version; 132 out[1] = msg->command; 133 out[2] = msg->outsize; 134 csum = out[0] + out[1] + out[2]; 135 for (i = 0; i < msg->outsize; i++) 136 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i]; 137 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum; 138 139 return EC_MSG_TX_PROTO_BYTES + msg->outsize; 140 } 141 EXPORT_SYMBOL(cros_ec_prepare_tx); 142 143 int cros_ec_check_result(struct cros_ec_device *ec_dev, 144 struct cros_ec_command *msg) 145 { 146 switch (msg->result) { 147 case EC_RES_SUCCESS: 148 return 0; 149 case EC_RES_IN_PROGRESS: 150 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n", 151 msg->command); 152 return -EAGAIN; 153 default: 154 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n", 155 msg->command, msg->result); 156 return 0; 157 } 158 } 159 EXPORT_SYMBOL(cros_ec_check_result); 160 161 /* 162 * cros_ec_get_host_event_wake_mask 163 * 164 * Get the mask of host events that cause wake from suspend. 165 * 166 * @ec_dev: EC device to call 167 * @msg: message structure to use 168 * @mask: result when function returns >=0. 169 * 170 * LOCKING: 171 * the caller has ec_dev->lock mutex, or the caller knows there is 172 * no other command in progress. 173 */ 174 static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev, 175 struct cros_ec_command *msg, 176 uint32_t *mask) 177 { 178 struct ec_response_host_event_mask *r; 179 int ret; 180 181 msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK; 182 msg->version = 0; 183 msg->outsize = 0; 184 msg->insize = sizeof(*r); 185 186 ret = send_command(ec_dev, msg); 187 if (ret > 0) { 188 r = (struct ec_response_host_event_mask *)msg->data; 189 *mask = r->mask; 190 } 191 192 return ret; 193 } 194 195 static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev, 196 int devidx, 197 struct cros_ec_command *msg) 198 { 199 /* 200 * Try using v3+ to query for supported protocols. If this 201 * command fails, fall back to v2. Returns the highest protocol 202 * supported by the EC. 203 * Also sets the max request/response/passthru size. 204 */ 205 int ret; 206 207 if (!ec_dev->pkt_xfer) 208 return -EPROTONOSUPPORT; 209 210 memset(msg, 0, sizeof(*msg)); 211 msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO; 212 msg->insize = sizeof(struct ec_response_get_protocol_info); 213 214 ret = send_command(ec_dev, msg); 215 216 if (ret < 0) { 217 dev_dbg(ec_dev->dev, 218 "failed to check for EC[%d] protocol version: %d\n", 219 devidx, ret); 220 return ret; 221 } 222 223 if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND) 224 return -ENODEV; 225 else if (msg->result != EC_RES_SUCCESS) 226 return msg->result; 227 228 return 0; 229 } 230 231 static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev) 232 { 233 struct cros_ec_command *msg; 234 struct ec_params_hello *hello_params; 235 struct ec_response_hello *hello_response; 236 int ret; 237 int len = max(sizeof(*hello_params), sizeof(*hello_response)); 238 239 msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL); 240 if (!msg) 241 return -ENOMEM; 242 243 msg->version = 0; 244 msg->command = EC_CMD_HELLO; 245 hello_params = (struct ec_params_hello *)msg->data; 246 msg->outsize = sizeof(*hello_params); 247 hello_response = (struct ec_response_hello *)msg->data; 248 msg->insize = sizeof(*hello_response); 249 250 hello_params->in_data = 0xa0b0c0d0; 251 252 ret = send_command(ec_dev, msg); 253 254 if (ret < 0) { 255 dev_dbg(ec_dev->dev, 256 "EC failed to respond to v2 hello: %d\n", 257 ret); 258 goto exit; 259 } else if (msg->result != EC_RES_SUCCESS) { 260 dev_err(ec_dev->dev, 261 "EC responded to v2 hello with error: %d\n", 262 msg->result); 263 ret = msg->result; 264 goto exit; 265 } else if (hello_response->out_data != 0xa1b2c3d4) { 266 dev_err(ec_dev->dev, 267 "EC responded to v2 hello with bad result: %u\n", 268 hello_response->out_data); 269 ret = -EBADMSG; 270 goto exit; 271 } 272 273 ret = 0; 274 275 exit: 276 kfree(msg); 277 return ret; 278 } 279 280 /* 281 * cros_ec_get_host_command_version_mask 282 * 283 * Get the version mask of a given command. 284 * 285 * @ec_dev: EC device to call 286 * @msg: message structure to use 287 * @cmd: command to get the version of. 288 * @mask: result when function returns 0. 289 * 290 * @return 0 on success, error code otherwise 291 * 292 * LOCKING: 293 * the caller has ec_dev->lock mutex or the caller knows there is 294 * no other command in progress. 295 */ 296 static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, 297 u16 cmd, u32 *mask) 298 { 299 struct ec_params_get_cmd_versions *pver; 300 struct ec_response_get_cmd_versions *rver; 301 struct cros_ec_command *msg; 302 int ret; 303 304 msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)), 305 GFP_KERNEL); 306 if (!msg) 307 return -ENOMEM; 308 309 msg->version = 0; 310 msg->command = EC_CMD_GET_CMD_VERSIONS; 311 msg->insize = sizeof(*rver); 312 msg->outsize = sizeof(*pver); 313 314 pver = (struct ec_params_get_cmd_versions *)msg->data; 315 pver->cmd = cmd; 316 317 ret = send_command(ec_dev, msg); 318 if (ret > 0) { 319 rver = (struct ec_response_get_cmd_versions *)msg->data; 320 *mask = rver->version_mask; 321 } 322 323 kfree(msg); 324 325 return ret; 326 } 327 328 int cros_ec_query_all(struct cros_ec_device *ec_dev) 329 { 330 struct device *dev = ec_dev->dev; 331 struct cros_ec_command *proto_msg; 332 struct ec_response_get_protocol_info *proto_info; 333 u32 ver_mask = 0; 334 int ret; 335 336 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info), 337 GFP_KERNEL); 338 if (!proto_msg) 339 return -ENOMEM; 340 341 /* First try sending with proto v3. */ 342 ec_dev->proto_version = 3; 343 ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg); 344 345 if (ret == 0) { 346 proto_info = (struct ec_response_get_protocol_info *) 347 proto_msg->data; 348 ec_dev->max_request = proto_info->max_request_packet_size - 349 sizeof(struct ec_host_request); 350 ec_dev->max_response = proto_info->max_response_packet_size - 351 sizeof(struct ec_host_response); 352 ec_dev->proto_version = 353 min(EC_HOST_REQUEST_VERSION, 354 fls(proto_info->protocol_versions) - 1); 355 dev_dbg(ec_dev->dev, 356 "using proto v%u\n", 357 ec_dev->proto_version); 358 359 ec_dev->din_size = ec_dev->max_response + 360 sizeof(struct ec_host_response) + 361 EC_MAX_RESPONSE_OVERHEAD; 362 ec_dev->dout_size = ec_dev->max_request + 363 sizeof(struct ec_host_request) + 364 EC_MAX_REQUEST_OVERHEAD; 365 366 /* 367 * Check for PD 368 */ 369 ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg); 370 371 if (ret) { 372 dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret); 373 ec_dev->max_passthru = 0; 374 } else { 375 dev_dbg(ec_dev->dev, "found PD chip\n"); 376 ec_dev->max_passthru = 377 proto_info->max_request_packet_size - 378 sizeof(struct ec_host_request); 379 } 380 } else { 381 /* Try querying with a v2 hello message. */ 382 ec_dev->proto_version = 2; 383 ret = cros_ec_host_command_proto_query_v2(ec_dev); 384 385 if (ret == 0) { 386 /* V2 hello succeeded. */ 387 dev_dbg(ec_dev->dev, "falling back to proto v2\n"); 388 389 ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE; 390 ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE; 391 ec_dev->max_passthru = 0; 392 ec_dev->pkt_xfer = NULL; 393 ec_dev->din_size = EC_PROTO2_MSG_BYTES; 394 ec_dev->dout_size = EC_PROTO2_MSG_BYTES; 395 } else { 396 /* 397 * It's possible for a test to occur too early when 398 * the EC isn't listening. If this happens, we'll 399 * test later when the first command is run. 400 */ 401 ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN; 402 dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret); 403 goto exit; 404 } 405 } 406 407 devm_kfree(dev, ec_dev->din); 408 devm_kfree(dev, ec_dev->dout); 409 410 ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); 411 if (!ec_dev->din) { 412 ret = -ENOMEM; 413 goto exit; 414 } 415 416 ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL); 417 if (!ec_dev->dout) { 418 devm_kfree(dev, ec_dev->din); 419 ret = -ENOMEM; 420 goto exit; 421 } 422 423 /* Probe if MKBP event is supported */ 424 ret = cros_ec_get_host_command_version_mask(ec_dev, 425 EC_CMD_GET_NEXT_EVENT, 426 &ver_mask); 427 if (ret < 0 || ver_mask == 0) 428 ec_dev->mkbp_event_supported = 0; 429 else 430 ec_dev->mkbp_event_supported = 1; 431 432 /* Probe if host sleep v1 is supported for S0ix failure detection. */ 433 ret = cros_ec_get_host_command_version_mask(ec_dev, 434 EC_CMD_HOST_SLEEP_EVENT, 435 &ver_mask); 436 ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1))); 437 438 /* 439 * Get host event wake mask, assume all events are wake events 440 * if unavailable. 441 */ 442 ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg, 443 &ec_dev->host_event_wake_mask); 444 if (ret < 0) 445 ec_dev->host_event_wake_mask = U32_MAX; 446 447 ret = 0; 448 449 exit: 450 kfree(proto_msg); 451 return ret; 452 } 453 EXPORT_SYMBOL(cros_ec_query_all); 454 455 int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, 456 struct cros_ec_command *msg) 457 { 458 int ret; 459 460 mutex_lock(&ec_dev->lock); 461 if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) { 462 ret = cros_ec_query_all(ec_dev); 463 if (ret) { 464 dev_err(ec_dev->dev, 465 "EC version unknown and query failed; aborting command\n"); 466 mutex_unlock(&ec_dev->lock); 467 return ret; 468 } 469 } 470 471 if (msg->insize > ec_dev->max_response) { 472 dev_dbg(ec_dev->dev, "clamping message receive buffer\n"); 473 msg->insize = ec_dev->max_response; 474 } 475 476 if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) { 477 if (msg->outsize > ec_dev->max_request) { 478 dev_err(ec_dev->dev, 479 "request of size %u is too big (max: %u)\n", 480 msg->outsize, 481 ec_dev->max_request); 482 mutex_unlock(&ec_dev->lock); 483 return -EMSGSIZE; 484 } 485 } else { 486 if (msg->outsize > ec_dev->max_passthru) { 487 dev_err(ec_dev->dev, 488 "passthru rq of size %u is too big (max: %u)\n", 489 msg->outsize, 490 ec_dev->max_passthru); 491 mutex_unlock(&ec_dev->lock); 492 return -EMSGSIZE; 493 } 494 } 495 ret = send_command(ec_dev, msg); 496 mutex_unlock(&ec_dev->lock); 497 498 return ret; 499 } 500 EXPORT_SYMBOL(cros_ec_cmd_xfer); 501 502 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, 503 struct cros_ec_command *msg) 504 { 505 int ret; 506 507 ret = cros_ec_cmd_xfer(ec_dev, msg); 508 if (ret < 0) { 509 dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret); 510 } else if (msg->result != EC_RES_SUCCESS) { 511 dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result); 512 return -EPROTO; 513 } 514 515 return ret; 516 } 517 EXPORT_SYMBOL(cros_ec_cmd_xfer_status); 518 519 static int get_next_event_xfer(struct cros_ec_device *ec_dev, 520 struct cros_ec_command *msg, 521 int version, uint32_t size) 522 { 523 int ret; 524 525 msg->version = version; 526 msg->command = EC_CMD_GET_NEXT_EVENT; 527 msg->insize = size; 528 msg->outsize = 0; 529 530 ret = cros_ec_cmd_xfer(ec_dev, msg); 531 if (ret > 0) { 532 ec_dev->event_size = ret - 1; 533 memcpy(&ec_dev->event_data, msg->data, ret); 534 } 535 536 return ret; 537 } 538 539 static int get_next_event(struct cros_ec_device *ec_dev) 540 { 541 u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; 542 struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; 543 static int cmd_version = 1; 544 int ret; 545 546 if (ec_dev->suspended) { 547 dev_dbg(ec_dev->dev, "Device suspended.\n"); 548 return -EHOSTDOWN; 549 } 550 551 if (cmd_version == 1) { 552 ret = get_next_event_xfer(ec_dev, msg, cmd_version, 553 sizeof(struct ec_response_get_next_event_v1)); 554 if (ret < 0 || msg->result != EC_RES_INVALID_VERSION) 555 return ret; 556 557 /* Fallback to version 0 for future send attempts */ 558 cmd_version = 0; 559 } 560 561 ret = get_next_event_xfer(ec_dev, msg, cmd_version, 562 sizeof(struct ec_response_get_next_event)); 563 564 return ret; 565 } 566 567 static int get_keyboard_state_event(struct cros_ec_device *ec_dev) 568 { 569 u8 buffer[sizeof(struct cros_ec_command) + 570 sizeof(ec_dev->event_data.data)]; 571 struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; 572 573 msg->version = 0; 574 msg->command = EC_CMD_MKBP_STATE; 575 msg->insize = sizeof(ec_dev->event_data.data); 576 msg->outsize = 0; 577 578 ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg); 579 ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX; 580 memcpy(&ec_dev->event_data.data, msg->data, 581 sizeof(ec_dev->event_data.data)); 582 583 return ec_dev->event_size; 584 } 585 586 int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event) 587 { 588 u8 event_type; 589 u32 host_event; 590 int ret; 591 592 if (!ec_dev->mkbp_event_supported) { 593 ret = get_keyboard_state_event(ec_dev); 594 if (ret <= 0) 595 return ret; 596 597 if (wake_event) 598 *wake_event = true; 599 600 return ret; 601 } 602 603 ret = get_next_event(ec_dev); 604 if (ret <= 0) 605 return ret; 606 607 if (wake_event) { 608 event_type = ec_dev->event_data.event_type; 609 host_event = cros_ec_get_host_event(ec_dev); 610 611 /* 612 * Sensor events need to be parsed by the sensor sub-device. 613 * Defer them, and don't report the wakeup here. 614 */ 615 if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) 616 *wake_event = false; 617 /* Masked host-events should not count as wake events. */ 618 else if (host_event && 619 !(host_event & ec_dev->host_event_wake_mask)) 620 *wake_event = false; 621 /* Consider all other events as wake events. */ 622 else 623 *wake_event = true; 624 } 625 626 return ret; 627 } 628 EXPORT_SYMBOL(cros_ec_get_next_event); 629 630 u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev) 631 { 632 u32 host_event; 633 634 BUG_ON(!ec_dev->mkbp_event_supported); 635 636 if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT) 637 return 0; 638 639 if (ec_dev->event_size != sizeof(host_event)) { 640 dev_warn(ec_dev->dev, "Invalid host event size\n"); 641 return 0; 642 } 643 644 host_event = get_unaligned_le32(&ec_dev->event_data.data.host_event); 645 646 return host_event; 647 } 648 EXPORT_SYMBOL(cros_ec_get_host_event); 649