1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Chromium OS cros_ec driver - sandbox emulation 4 * 5 * Copyright (c) 2013 The Chromium OS Authors. 6 */ 7 8#define LOG_CATEGORY UCLASS_CROS_EC 9 10#include <common.h> 11#include <cros_ec.h> 12#include <dm.h> 13#include <ec_commands.h> 14#include <errno.h> 15#include <hash.h> 16#include <log.h> 17#include <os.h> 18#include <u-boot/sha256.h> 19#include <spi.h> 20#include <asm/malloc.h> 21#include <asm/state.h> 22#include <asm/sdl.h> 23#include <asm/test.h> 24#include <linux/input.h> 25 26/* 27 * Ultimately it shold be possible to connect an Chrome OS EC emulation 28 * to U-Boot and remove all of this code. But this provides a test 29 * environment for bringing up chromeos_sandbox and demonstrating its 30 * utility. 31 * 32 * This emulation includes the following: 33 * 34 * 1. Emulation of the keyboard, by converting keypresses received from SDL 35 * into key scan data, passed back from the EC as key scan messages. The 36 * key layout is read from the device tree. 37 * 38 * 2. Emulation of vboot context - so this can be read/written as required. 39 * 40 * 3. Save/restore of EC state, so that the vboot context, flash memory 41 * contents and current image can be preserved across boots. This is important 42 * since the EC is supposed to continue running even if the AP resets. 43 * 44 * 4. Some event support, in particular allowing Escape to be pressed on boot 45 * to enter recovery mode. The EC passes this to U-Boot through the normal 46 * event message. 47 * 48 * 5. Flash read/write/erase support, so that software sync works. The 49 * protect messages are supported but no protection is implemented. 50 * 51 * 6. Hashing of the EC image, again to support software sync. 52 * 53 * Other features can be added, although a better path is probably to link 54 * the EC image in with U-Boot (Vic has demonstrated a prototype for this). 55 */ 56 57#define KEYBOARD_ROWS 8 58#define KEYBOARD_COLS 13 59 60/* A single entry of the key matrix */ 61struct ec_keymatrix_entry { 62 int row; /* key matrix row */ 63 int col; /* key matrix column */ 64 int keycode; /* corresponding linux key code */ 65}; 66 67enum { 68 VSTORE_SLOT_COUNT = 4, 69 PWM_CHANNEL_COUNT = 4, 70}; 71 72struct vstore_slot { 73 bool locked; 74 u8 data[EC_VSTORE_SLOT_SIZE]; 75}; 76 77struct ec_pwm_channel { 78 uint duty; /* not ns, EC_PWM_MAX_DUTY = 100% */ 79}; 80 81/** 82 * struct ec_state - Information about the EC state 83 * 84 * @valid: true if this struct contains valid state data 85 * @vbnv_context: Vboot context data stored by EC 86 * @ec_config: FDT config information about the EC (e.g. flashmap) 87 * @flash_data: Contents of flash memory 88 * @flash_data_len: Size of flash memory 89 * @current_image: Current image the EC is running 90 * @matrix_count: Number of keys to decode in matrix 91 * @matrix: Information about keyboard matrix 92 * @keyscan: Current keyscan information (bit set for each row/column pressed) 93 * @recovery_req: Keyboard recovery requested 94 * @test_flags: Flags that control behaviour for tests 95 * @slot_locked: Locked vstore slots (mask) 96 * @pwm: Information per PWM channel 97 */ 98struct ec_state { 99 bool valid; 100 u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2]; 101 struct fdt_cros_ec ec_config; 102 uint8_t *flash_data; 103 int flash_data_len; 104 enum ec_current_image current_image; 105 int matrix_count; 106 struct ec_keymatrix_entry *matrix; /* the key matrix info */ 107 uint8_t keyscan[KEYBOARD_COLS]; 108 bool recovery_req; 109 uint test_flags; 110 struct vstore_slot slot[VSTORE_SLOT_COUNT]; 111 struct ec_pwm_channel pwm[PWM_CHANNEL_COUNT]; 112} s_state, *g_state; 113 114/** 115 * cros_ec_read_state() - read the sandbox EC state from the state file 116 * 117 * If data is available, then blob and node will provide access to it. If 118 * not this function sets up an empty EC. 119 * 120 * @param blob: Pointer to device tree blob, or NULL if no data to read 121 * @param node: Node offset to read from 122 */ 123static int cros_ec_read_state(const void *blob, int node) 124{ 125 struct ec_state *ec = &s_state; 126 const char *prop; 127 int len; 128 129 /* Set everything to defaults */ 130 ec->current_image = EC_IMAGE_RO; 131 if (!blob) 132 return 0; 133 134 /* Read the data if available */ 135 ec->current_image = fdtdec_get_int(blob, node, "current-image", 136 EC_IMAGE_RO); 137 prop = fdt_getprop(blob, node, "vbnv-context", &len); 138 if (prop && len == sizeof(ec->vbnv_context)) 139 memcpy(ec->vbnv_context, prop, len); 140 141 prop = fdt_getprop(blob, node, "flash-data", &len); 142 if (prop) { 143 ec->flash_data_len = len; 144 ec->flash_data = malloc(len); 145 if (!ec->flash_data) 146 return -ENOMEM; 147 memcpy(ec->flash_data, prop, len); 148 debug("%s: Loaded EC flash data size %#x\n", __func__, len); 149 } 150 ec->valid = true; 151 152 return 0; 153} 154 155/** 156 * cros_ec_write_state() - Write out our state to the state file 157 * 158 * The caller will ensure that there is a node ready for the state. The node 159 * may already contain the old state, in which case it is overridden. 160 * 161 * @param blob: Device tree blob holding state 162 * @param node: Node to write our state into 163 */ 164static int cros_ec_write_state(void *blob, int node) 165{ 166 struct ec_state *ec = g_state; 167 168 if (!g_state) 169 return 0; 170 171 /* We are guaranteed enough space to write basic properties */ 172 fdt_setprop_u32(blob, node, "current-image", ec->current_image); 173 fdt_setprop(blob, node, "vbnv-context", ec->vbnv_context, 174 sizeof(ec->vbnv_context)); 175 176 return state_setprop(node, "flash-data", ec->flash_data, 177 ec->ec_config.flash.length); 178} 179 180SANDBOX_STATE_IO(cros_ec, "google,cros-ec", cros_ec_read_state, 181 cros_ec_write_state); 182 183/** 184 * Return the number of bytes used in the specified image. 185 * 186 * This is the actual size of code+data in the image, as opposed to the 187 * amount of space reserved in flash for that image. This code is similar to 188 * that used by the real EC code base. 189 * 190 * @param ec Current emulated EC state 191 * @param entry Flash map entry containing the image to check 192 * Return: actual image size in bytes, 0 if the image contains no content or 193 * error. 194 */ 195static int get_image_used(struct ec_state *ec, struct fmap_entry *entry) 196{ 197 int size; 198 199 /* 200 * Scan backwards looking for 0xea byte, which is by definition the 201 * last byte of the image. See ec.lds.S for how this is inserted at 202 * the end of the image. 203 */ 204 for (size = entry->length - 1; 205 size > 0 && ec->flash_data[entry->offset + size] != 0xea; 206 size--) 207 ; 208 209 return size ? size + 1 : 0; /* 0xea byte IS part of the image */ 210} 211 212/** 213 * Read the key matrix from the device tree 214 * 215 * Keymap entries in the fdt take the form of 0xRRCCKKKK where 216 * RR=Row CC=Column KKKK=Key Code 217 * 218 * @param ec Current emulated EC state 219 * @param node Keyboard node of device tree containing keyscan information 220 * Return: 0 if ok, -1 on error 221 */ 222static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node) 223{ 224 const u32 *cell; 225 int upto; 226 int len; 227 228 cell = ofnode_get_property(node, "linux,keymap", &len); 229 if (!cell) 230 return log_msg_ret("prop", -EINVAL); 231 ec->matrix_count = len / 4; 232 ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix)); 233 if (!ec->matrix) { 234 return log_msg_ret("mem", -ENOMEM); 235 } 236 237 /* Now read the data */ 238 for (upto = 0; upto < ec->matrix_count; upto++) { 239 struct ec_keymatrix_entry *matrix = &ec->matrix[upto]; 240 u32 word; 241 242 word = fdt32_to_cpu(*cell++); 243 matrix->row = word >> 24; 244 matrix->col = (word >> 16) & 0xff; 245 matrix->keycode = word & 0xffff; 246 247 /* Hard-code some sanity limits for now */ 248 if (matrix->row >= KEYBOARD_ROWS || 249 matrix->col >= KEYBOARD_COLS) { 250 debug("%s: Matrix pos out of range (%d,%d)\n", 251 __func__, matrix->row, matrix->col); 252 return log_msg_ret("matrix", -ERANGE); 253 } 254 } 255 256 if (upto != ec->matrix_count) { 257 return log_msg_ret("matrix", -E2BIG); 258 } 259 260 return 0; 261} 262 263/** 264 * Return the next keyscan message contents 265 * 266 * @param ec Current emulated EC state 267 * @param scan Place to put keyscan bytes for the keyscan message (must hold 268 * enough space for a full keyscan) 269 * Return: number of bytes of valid scan data 270 */ 271static int cros_ec_keyscan(struct ec_state *ec, uint8_t *scan) 272{ 273 const struct ec_keymatrix_entry *matrix; 274 int bytes = KEYBOARD_COLS; 275 int key[8]; /* allow up to 8 keys to be pressed at once */ 276 int count; 277 int i; 278 279 memset(ec->keyscan, '\0', bytes); 280 count = sandbox_sdl_scan_keys(key, ARRAY_SIZE(key)); 281 282 /* Look up keycode in matrix */ 283 for (i = 0, matrix = ec->matrix; i < ec->matrix_count; i++, matrix++) { 284 bool found; 285 int j; 286 287 for (found = false, j = 0; j < count; j++) { 288 if (matrix->keycode == key[j]) 289 found = true; 290 } 291 292 if (found) { 293 debug("%d: %d,%d\n", matrix->keycode, matrix->row, 294 matrix->col); 295 ec->keyscan[matrix->col] |= 1 << matrix->row; 296 } 297 } 298 299 memcpy(scan, ec->keyscan, bytes); 300 return bytes; 301} 302 303/** 304 * Process an emulated EC command 305 * 306 * @param ec Current emulated EC state 307 * @param req_hdr Pointer to request header 308 * @param req_data Pointer to body of request 309 * @param resp_hdr Pointer to place to put response header 310 * @param resp_data Pointer to place to put response data, if any 311 * Return: length of response data, or 0 for no response data, or -1 on error 312 */ 313static int process_cmd(struct ec_state *ec, 314 struct ec_host_request *req_hdr, const void *req_data, 315 struct ec_host_response *resp_hdr, void *resp_data) 316{ 317 int len; 318 319 /* TODO(sjg@chromium.org): Check checksums */ 320 debug("EC command %#0x\n", req_hdr->command); 321 322 switch (req_hdr->command) { 323 case EC_CMD_HELLO: { 324 const struct ec_params_hello *req = req_data; 325 struct ec_response_hello *resp = resp_data; 326 327 resp->out_data = req->in_data + 0x01020304; 328 if (ec->test_flags & CROSECT_BREAK_HELLO) 329 resp->out_data++; 330 len = sizeof(*resp); 331 break; 332 } 333 case EC_CMD_GET_VERSION: { 334 struct ec_response_get_version *resp = resp_data; 335 336 strcpy(resp->version_string_ro, "sandbox_ro"); 337 strcpy(resp->version_string_rw, "sandbox_rw"); 338 resp->current_image = ec->current_image; 339 debug("Current image %d\n", resp->current_image); 340 len = sizeof(*resp); 341 break; 342 } 343 case EC_CMD_VBNV_CONTEXT: { 344 const struct ec_params_vbnvcontext *req = req_data; 345 struct ec_response_vbnvcontext *resp = resp_data; 346 347 switch (req->op) { 348 case EC_VBNV_CONTEXT_OP_READ: 349 memcpy(resp->block, ec->vbnv_context, 350 EC_VBNV_BLOCK_SIZE_V2); 351 len = EC_VBNV_BLOCK_SIZE_V2; 352 break; 353 case EC_VBNV_CONTEXT_OP_WRITE: 354 memcpy(ec->vbnv_context, req->block, 355 EC_VBNV_BLOCK_SIZE_V2); 356 len = 0; 357 break; 358 default: 359 printf(" ** Unknown vbnv_context command %#02x\n", 360 req->op); 361 return -1; 362 } 363 break; 364 } 365 case EC_CMD_REBOOT_EC: { 366 const struct ec_params_reboot_ec *req = req_data; 367 368 printf("Request reboot type %d\n", req->cmd); 369 switch (req->cmd) { 370 case EC_REBOOT_DISABLE_JUMP: 371 len = 0; 372 break; 373 case EC_REBOOT_JUMP_RW: 374 ec->current_image = EC_IMAGE_RW; 375 len = 0; 376 break; 377 default: 378 puts(" ** Unknown type"); 379 return -1; 380 } 381 break; 382 } 383 case EC_CMD_HOST_EVENT_GET_B: { 384 struct ec_response_host_event_mask *resp = resp_data; 385 386 resp->mask = 0; 387 if (ec->recovery_req) { 388 resp->mask |= EC_HOST_EVENT_MASK( 389 EC_HOST_EVENT_KEYBOARD_RECOVERY); 390 } 391 if (ec->test_flags & CROSECT_LID_OPEN) 392 resp->mask |= 393 EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN); 394 len = sizeof(*resp); 395 break; 396 } 397 case EC_CMD_HOST_EVENT_CLEAR_B: { 398 const struct ec_params_host_event_mask *req = req_data; 399 400 if (req->mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)) 401 ec->test_flags &= ~CROSECT_LID_OPEN; 402 len = 0; 403 break; 404 } 405 case EC_CMD_VBOOT_HASH: { 406 const struct ec_params_vboot_hash *req = req_data; 407 struct ec_response_vboot_hash *resp = resp_data; 408 struct fmap_entry *entry; 409 int ret, size; 410 411 entry = &ec->ec_config.region[EC_FLASH_REGION_ACTIVE]; 412 413 switch (req->cmd) { 414 case EC_VBOOT_HASH_RECALC: 415 case EC_VBOOT_HASH_GET: 416 size = SHA256_SUM_LEN; 417 len = get_image_used(ec, entry); 418 ret = hash_block("sha256", 419 ec->flash_data + entry->offset, 420 len, resp->hash_digest, &size); 421 if (ret) { 422 printf(" ** hash_block() failed\n"); 423 return -1; 424 } 425 resp->status = EC_VBOOT_HASH_STATUS_DONE; 426 resp->hash_type = EC_VBOOT_HASH_TYPE_SHA256; 427 resp->digest_size = size; 428 resp->reserved0 = 0; 429 resp->offset = entry->offset; 430 resp->size = len; 431 len = sizeof(*resp); 432 break; 433 default: 434 printf(" ** EC_CMD_VBOOT_HASH: Unknown command %d\n", 435 req->cmd); 436 return -1; 437 } 438 break; 439 } 440 case EC_CMD_FLASH_PROTECT: { 441 const struct ec_params_flash_protect *req = req_data; 442 struct ec_response_flash_protect *resp = resp_data; 443 uint32_t expect = EC_FLASH_PROTECT_ALL_NOW | 444 EC_FLASH_PROTECT_ALL_AT_BOOT; 445 446 printf("mask=%#x, flags=%#x\n", req->mask, req->flags); 447 if (req->flags == expect || req->flags == 0) { 448 resp->flags = req->flags ? EC_FLASH_PROTECT_ALL_NOW : 449 0; 450 resp->valid_flags = EC_FLASH_PROTECT_ALL_NOW; 451 resp->writable_flags = 0; 452 len = sizeof(*resp); 453 } else { 454 puts(" ** unexpected flash protect request\n"); 455 return -1; 456 } 457 break; 458 } 459 case EC_CMD_FLASH_REGION_INFO: { 460 const struct ec_params_flash_region_info *req = req_data; 461 struct ec_response_flash_region_info *resp = resp_data; 462 struct fmap_entry *entry; 463 464 switch (req->region) { 465 case EC_FLASH_REGION_RO: 466 case EC_FLASH_REGION_ACTIVE: 467 case EC_FLASH_REGION_WP_RO: 468 entry = &ec->ec_config.region[req->region]; 469 resp->offset = entry->offset; 470 resp->size = entry->length; 471 len = sizeof(*resp); 472 printf("EC flash region %d: offset=%#x, size=%#x\n", 473 req->region, resp->offset, resp->size); 474 break; 475 default: 476 printf("** Unknown flash region %d\n", req->region); 477 return -1; 478 } 479 break; 480 } 481 case EC_CMD_FLASH_ERASE: { 482 const struct ec_params_flash_erase *req = req_data; 483 484 memset(ec->flash_data + req->offset, 485 ec->ec_config.flash_erase_value, 486 req->size); 487 len = 0; 488 break; 489 } 490 case EC_CMD_FLASH_WRITE: { 491 const struct ec_params_flash_write *req = req_data; 492 493 memcpy(ec->flash_data + req->offset, req + 1, req->size); 494 len = 0; 495 break; 496 } 497 case EC_CMD_MKBP_STATE: 498 len = cros_ec_keyscan(ec, resp_data); 499 break; 500 case EC_CMD_GET_NEXT_EVENT: { 501 struct ec_response_get_next_event *resp = resp_data; 502 503 resp->event_type = EC_MKBP_EVENT_KEY_MATRIX; 504 cros_ec_keyscan(ec, resp->data.key_matrix); 505 len = sizeof(*resp); 506 break; 507 } 508 case EC_CMD_GET_SKU_ID: { 509 struct ec_sku_id_info *resp = resp_data; 510 511 resp->sku_id = 1234; 512 len = sizeof(*resp); 513 break; 514 } 515 case EC_CMD_GET_FEATURES: { 516 struct ec_response_get_features *resp = resp_data; 517 518 resp->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FLASH) | 519 EC_FEATURE_MASK_0(EC_FEATURE_I2C) | 520 EC_FEATURE_MASK_0(EC_FEATURE_VSTORE); 521 resp->flags[1] = 522 EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS) | 523 EC_FEATURE_MASK_1(EC_FEATURE_ISH); 524 len = sizeof(*resp); 525 break; 526 } 527 case EC_CMD_VSTORE_INFO: { 528 struct ec_response_vstore_info *resp = resp_data; 529 int i; 530 531 resp->slot_count = VSTORE_SLOT_COUNT; 532 resp->slot_locked = 0; 533 for (i = 0; i < VSTORE_SLOT_COUNT; i++) { 534 if (ec->slot[i].locked) 535 resp->slot_locked |= 1 << i; 536 } 537 len = sizeof(*resp); 538 break; 539 }; 540 case EC_CMD_VSTORE_WRITE: { 541 const struct ec_params_vstore_write *req = req_data; 542 struct vstore_slot *slot; 543 544 if (req->slot >= EC_VSTORE_SLOT_MAX) 545 return -EINVAL; 546 slot = &ec->slot[req->slot]; 547 slot->locked = true; 548 memcpy(slot->data, req->data, EC_VSTORE_SLOT_SIZE); 549 len = 0; 550 break; 551 } 552 case EC_CMD_VSTORE_READ: { 553 const struct ec_params_vstore_read *req = req_data; 554 struct ec_response_vstore_read *resp = resp_data; 555 struct vstore_slot *slot; 556 557 if (req->slot >= EC_VSTORE_SLOT_MAX) 558 return -EINVAL; 559 slot = &ec->slot[req->slot]; 560 memcpy(resp->data, slot->data, EC_VSTORE_SLOT_SIZE); 561 len = sizeof(*resp); 562 break; 563 } 564 case EC_CMD_PWM_GET_DUTY: { 565 const struct ec_params_pwm_get_duty *req = req_data; 566 struct ec_response_pwm_get_duty *resp = resp_data; 567 struct ec_pwm_channel *pwm; 568 569 if (req->pwm_type != EC_PWM_TYPE_GENERIC) 570 return -EINVAL; 571 if (req->index >= PWM_CHANNEL_COUNT) 572 return -EINVAL; 573 pwm = &ec->pwm[req->index]; 574 resp->duty = pwm->duty; 575 len = sizeof(*resp); 576 break; 577 } 578 case EC_CMD_PWM_SET_DUTY: { 579 const struct ec_params_pwm_set_duty *req = req_data; 580 struct ec_pwm_channel *pwm; 581 582 if (req->pwm_type != EC_PWM_TYPE_GENERIC) 583 return -EINVAL; 584 if (req->index >= PWM_CHANNEL_COUNT) 585 return -EINVAL; 586 pwm = &ec->pwm[req->index]; 587 pwm->duty = req->duty; 588 len = 0; 589 break; 590 } 591 default: 592 printf(" ** Unknown EC command %#02x\n", req_hdr->command); 593 return -1; 594 } 595 debug(" - EC command %#0x, result %d\n", req_hdr->command, len); 596 597 return len; 598} 599 600int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes) 601{ 602 struct cros_ec_dev *dev = dev_get_uclass_priv(udev); 603 struct ec_state *ec = dev_get_priv(dev->dev); 604 struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout; 605 const void *req_data = req_hdr + 1; 606 struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din; 607 void *resp_data = resp_hdr + 1; 608 int len; 609 610 len = process_cmd(ec, req_hdr, req_data, resp_hdr, resp_data); 611 if (len < 0) 612 return len; 613 614 resp_hdr->struct_version = 3; 615 resp_hdr->result = EC_RES_SUCCESS; 616 resp_hdr->data_len = len; 617 resp_hdr->reserved = 0; 618 len += sizeof(*resp_hdr); 619 resp_hdr->checksum = 0; 620 resp_hdr->checksum = (uint8_t) 621 -cros_ec_calc_checksum((const uint8_t *)resp_hdr, len); 622 623 return in_bytes; 624} 625 626void cros_ec_check_keyboard(struct udevice *dev) 627{ 628 struct ec_state *ec = dev_get_priv(dev); 629 ulong start; 630 631 printf("\nPress keys for EC to detect on reset (ESC=recovery)..."); 632 start = get_timer(0); 633 while (get_timer(start) < 2000) { 634 if (tstc()) { 635 int ch = getchar(); 636 637 if (ch == 0x1b) { 638 ec->recovery_req = true; 639 printf("EC requests recovery"); 640 } 641 } 642 } 643 putc('\n'); 644} 645 646/* Return the byte of EC switch states */ 647static int cros_ec_sandbox_get_switches(struct udevice *dev) 648{ 649 struct ec_state *ec = dev_get_priv(dev); 650 651 return ec->test_flags & CROSECT_LID_OPEN ? EC_SWITCH_LID_OPEN : 0; 652} 653 654void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags) 655{ 656 struct ec_state *ec = dev_get_priv(dev); 657 658 ec->test_flags = flags; 659} 660 661int sandbox_cros_ec_get_pwm_duty(struct udevice *dev, uint index, uint *duty) 662{ 663 struct ec_state *ec = dev_get_priv(dev); 664 struct ec_pwm_channel *pwm; 665 666 if (index >= PWM_CHANNEL_COUNT) 667 return -ENOSPC; 668 pwm = &ec->pwm[index]; 669 *duty = pwm->duty; 670 671 return 0; 672} 673 674int cros_ec_probe(struct udevice *dev) 675{ 676 struct ec_state *ec = dev_get_priv(dev); 677 struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); 678 struct udevice *keyb_dev; 679 ofnode node; 680 int err; 681 682 if (s_state.valid) 683 memcpy(ec, &s_state, sizeof(*ec)); 684 else 685 ec->current_image = EC_IMAGE_RO; 686 err = cros_ec_decode_ec_flash(dev, &ec->ec_config); 687 if (err) { 688 debug("%s: Cannot device EC flash\n", __func__); 689 return err; 690 } 691 692 node = ofnode_null(); 693 for (device_find_first_child(dev, &keyb_dev); 694 keyb_dev; 695 device_find_next_child(&keyb_dev)) { 696 if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) { 697 node = dev_ofnode(keyb_dev); 698 break; 699 } 700 } 701 if (!ofnode_valid(node)) { 702 debug("%s: No cros_ec keyboard found\n", __func__); 703 } else if (keyscan_read_fdt_matrix(ec, node)) { 704 debug("%s: Could not read key matrix\n", __func__); 705 return -1; 706 } 707 708 /* If we loaded EC data, check that the length matches */ 709 if (ec->flash_data && 710 ec->flash_data_len != ec->ec_config.flash.length) { 711 printf("EC data length is %x, expected %x, discarding data\n", 712 ec->flash_data_len, ec->ec_config.flash.length); 713 free(ec->flash_data); 714 ec->flash_data = NULL; 715 } 716 717 /* Otherwise allocate the memory */ 718 if (!ec->flash_data) { 719 ec->flash_data_len = ec->ec_config.flash.length; 720 ec->flash_data = malloc(ec->flash_data_len); 721 if (!ec->flash_data) 722 return -ENOMEM; 723 } 724 725 cdev->dev = dev; 726 g_state = ec; 727 return cros_ec_register(dev); 728} 729 730struct dm_cros_ec_ops cros_ec_ops = { 731 .packet = cros_ec_sandbox_packet, 732 .get_switches = cros_ec_sandbox_get_switches, 733}; 734 735static const struct udevice_id cros_ec_ids[] = { 736 { .compatible = "google,cros-ec-sandbox" }, 737 { } 738}; 739 740U_BOOT_DRIVER(google_cros_ec_sandbox) = { 741 .name = "google_cros_ec_sandbox", 742 .id = UCLASS_CROS_EC, 743 .of_match = cros_ec_ids, 744 .probe = cros_ec_probe, 745 .priv_auto = sizeof(struct ec_state), 746 .ops = &cros_ec_ops, 747}; 748