static int google_chromeec_set_s0ix_lazy_wake_mask(uint64_t mask) { printk(BIOS_DEBUG, "Chrome EC: Set S0iX LAZY WAKE mask to 0x%016llx\n", mask); return google_chromeec_set_mask (EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX, mask); }
int google_chromeec_set_wake_mask(u32 mask) { printk(BIOS_DEBUG, "Chrome EC: Set WAKE mask to 0x%08x\n", mask); return google_chromeec_set_mask( EC_CMD_HOST_EVENT_SET_WAKE_MASK, mask); }
int google_chromeec_set_smi_mask(u32 mask) { printk(BIOS_DEBUG, "Chrome EC: Set SMI mask to 0x%08x\n", mask); return google_chromeec_set_mask( EC_CMD_HOST_EVENT_SET_SMI_MASK, mask); }
int google_chromeec_clear_events_b(u32 mask) { printk(BIOS_DEBUG, "Chrome EC: clear events_b mask to 0x%08x\n", mask); return google_chromeec_set_mask( EC_CMD_HOST_EVENT_CLEAR_B, mask); }
int google_chromeec_set_wake_mask(uint64_t mask) { printk(BIOS_DEBUG, "Chrome EC: Set WAKE mask to 0x%016llx\n", mask); return google_chromeec_set_mask (EC_HOST_EVENT_ACTIVE_WAKE_MASK, mask); }
int google_chromeec_reboot(int dev_idx, enum ec_reboot_cmd type, uint8_t flags) { struct ec_params_reboot_ec reboot_ec = { .cmd = type, .flags = flags, }; struct ec_response_get_version cec_resp = { }; struct chromeec_command cec_cmd = { .cmd_code = EC_CMD_REBOOT_EC, .cmd_version = 0, .cmd_data_in = &reboot_ec, .cmd_data_out = &cec_resp, .cmd_size_in = sizeof(reboot_ec), .cmd_size_out = 0, /* ignore response, if any */ .cmd_dev_index = dev_idx, }; return google_chromeec_command(&cec_cmd); } static int cbi_get_uint32(uint32_t *id, uint32_t tag) { struct chromeec_command cmd; struct ec_params_get_cbi p; uint32_t r = 0; int rv; p.tag = tag; cmd.cmd_code = EC_CMD_GET_CROS_BOARD_INFO; cmd.cmd_version = 0; cmd.cmd_data_in = &p; cmd.cmd_data_out = &r; cmd.cmd_size_in = sizeof(p); cmd.cmd_size_out = sizeof(r); cmd.cmd_dev_index = 0; rv = google_chromeec_command(&cmd); if (rv < 0) return rv; *id = r; return 0; } int google_chromeec_cbi_get_sku_id(uint32_t *id) { return cbi_get_uint32(id, CBI_TAG_SKU_ID); } int google_chromeec_cbi_get_oem_id(uint32_t *id) { return cbi_get_uint32(id, CBI_TAG_OEM_ID); } static int cbi_get_string(char *buf, size_t bufsize, uint32_t tag) { struct ec_params_get_cbi p = { .tag = tag, }; struct chromeec_command cmd = { .cmd_code = EC_CMD_GET_CROS_BOARD_INFO, .cmd_version = 0, .cmd_data_in = &p, .cmd_data_out = buf, .cmd_size_in = sizeof(p), .cmd_size_out = bufsize, }; int rv; rv = google_chromeec_command(&cmd); if (rv < 0) return rv; /* Ensure NUL termination. */ buf[bufsize - 1] = '\0'; return 0; } int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize) { return cbi_get_string(buf, bufsize, CBI_TAG_DRAM_PART_NUM); } int google_chromeec_cbi_get_oem_name(char *buf, size_t bufsize) { return cbi_get_string(buf, bufsize, CBI_TAG_OEM_NAME); } int google_chromeec_get_board_version(uint32_t *version) { struct chromeec_command cmd; struct ec_response_board_version board_v; cmd.cmd_code = EC_CMD_GET_BOARD_VERSION; cmd.cmd_version = 0; cmd.cmd_size_in = 0; cmd.cmd_size_out = sizeof(board_v); cmd.cmd_data_out = &board_v; cmd.cmd_dev_index = 0; if (google_chromeec_command(&cmd)) return -1; *version = board_v.board_version; return 0; } u32 google_chromeec_get_sku_id(void) { struct chromeec_command cmd; struct ec_sku_id_info sku_v; cmd.cmd_code = EC_CMD_GET_SKU_ID; cmd.cmd_version = 0; cmd.cmd_size_in = 0; cmd.cmd_size_out = sizeof(sku_v); cmd.cmd_data_out = &sku_v; cmd.cmd_dev_index = 0; if (google_chromeec_command(&cmd) != 0) return 0; return sku_v.sku_id; } int google_chromeec_vbnv_context(int is_read, uint8_t *data, int len) { struct chromeec_command cec_cmd; struct ec_params_vbnvcontext cmd_vbnvcontext; struct ec_response_vbnvcontext rsp_vbnvcontext; int retries = 3; if (len != EC_VBNV_BLOCK_SIZE) return -1; retry: cec_cmd.cmd_code = EC_CMD_VBNV_CONTEXT; cec_cmd.cmd_version = EC_VER_VBNV_CONTEXT; cec_cmd.cmd_data_in = &cmd_vbnvcontext; cec_cmd.cmd_data_out = &rsp_vbnvcontext; cec_cmd.cmd_size_in = sizeof(cmd_vbnvcontext); cec_cmd.cmd_size_out = is_read ? sizeof(rsp_vbnvcontext) : 0; cec_cmd.cmd_dev_index = 0; cmd_vbnvcontext.op = is_read ? EC_VBNV_CONTEXT_OP_READ : EC_VBNV_CONTEXT_OP_WRITE; if (!is_read) memcpy(&cmd_vbnvcontext.block, data, EC_VBNV_BLOCK_SIZE); if (google_chromeec_command(&cec_cmd)) { printk(BIOS_ERR, "ERROR: failed to %s vbnv_ec context: %d\n", is_read ? "read" : "write", (int)cec_cmd.cmd_code); mdelay(10); /* just in case */ if (--retries) goto retry; } if (is_read) memcpy(data, &rsp_vbnvcontext.block, EC_VBNV_BLOCK_SIZE); return cec_cmd.cmd_code; } #ifndef __PRE_RAM__ int google_chromeec_i2c_xfer(uint8_t chip, uint8_t addr, int alen, uint8_t *buffer, int len, int is_read) { union { struct ec_params_i2c_passthru p; uint8_t outbuf[EC_HOST_PARAM_SIZE]; } params; union { struct ec_response_i2c_passthru r; uint8_t inbuf[EC_HOST_PARAM_SIZE]; } response; struct ec_params_i2c_passthru *p = ¶ms.p; struct ec_response_i2c_passthru *r = &response.r; struct ec_params_i2c_passthru_msg *msg = p->msg; struct chromeec_command cmd; uint8_t *pdata; int read_len, write_len; int size; int rv; p->port = 0; if (alen != 1) { printk(BIOS_ERR, "Unsupported address length %d\n", alen); return -1; } if (is_read) { read_len = len; write_len = alen; p->num_msgs = 2; } else { read_len = 0; write_len = alen + len; p->num_msgs = 1; } size = sizeof(*p) + p->num_msgs * sizeof(*msg); if (size + write_len > sizeof(params)) { printk(BIOS_ERR, "Params too large for buffer\n"); return -1; } if (sizeof(*r) + read_len > sizeof(response)) { printk(BIOS_ERR, "Read length too big for buffer\n"); return -1; } /* Create a message to write the register address and optional data */ pdata = (uint8_t *)p + size; msg->addr_flags = chip; msg->len = write_len; pdata[0] = addr; if (!is_read) memcpy(pdata + 1, buffer, len); msg++; if (read_len) { msg->addr_flags = chip | EC_I2C_FLAG_READ; msg->len = read_len; } cmd.cmd_code = EC_CMD_I2C_PASSTHRU; cmd.cmd_version = 0; cmd.cmd_data_in = p; cmd.cmd_size_in = size + write_len; cmd.cmd_data_out = r; cmd.cmd_size_out = sizeof(*r) + read_len; cmd.cmd_dev_index = 0; rv = google_chromeec_command(&cmd); if (rv != 0) return rv; /* Parse response */ if (r->i2c_status & EC_I2C_STATUS_ERROR) { printk(BIOS_ERR, "Transfer failed with status=0x%x\n", r->i2c_status); return -1; } if (cmd.cmd_size_out < sizeof(*r) + read_len) { printk(BIOS_ERR, "Truncated read response\n"); return -1; } if (read_len) memcpy(buffer, r->data, read_len); return 0; } int google_chromeec_set_sci_mask(uint64_t mask) { printk(BIOS_DEBUG, "Chrome EC: Set SCI mask to 0x%016llx\n", mask); return google_chromeec_set_mask(EC_HOST_EVENT_SCI_MASK, mask); } int google_chromeec_set_smi_mask(uint64_t mask) { printk(BIOS_DEBUG, "Chrome EC: Set SMI mask to 0x%016llx\n", mask); return google_chromeec_set_mask(EC_HOST_EVENT_SMI_MASK, mask); }