|
@@ -8,6 +8,7 @@
|
|
|
|
|
|
#include <common.h>
|
|
|
#include <cros_ec.h>
|
|
|
+#include <dm.h>
|
|
|
#include <ec_commands.h>
|
|
|
#include <errno.h>
|
|
|
#include <hash.h>
|
|
@@ -85,7 +86,7 @@ struct ec_state {
|
|
|
struct ec_keymatrix_entry *matrix; /* the key matrix info */
|
|
|
uint8_t keyscan[KEYBOARD_COLS];
|
|
|
bool recovery_req;
|
|
|
-} s_state, *state;
|
|
|
+} s_state, *g_state;
|
|
|
|
|
|
/**
|
|
|
* cros_ec_read_state() - read the sandbox EC state from the state file
|
|
@@ -138,7 +139,7 @@ static int cros_ec_read_state(const void *blob, int node)
|
|
|
*/
|
|
|
static int cros_ec_write_state(void *blob, int node)
|
|
|
{
|
|
|
- struct ec_state *ec = &s_state;
|
|
|
+ struct ec_state *ec = g_state;
|
|
|
|
|
|
/* We are guaranteed enough space to write basic properties */
|
|
|
fdt_setprop_u32(blob, node, "current-image", ec->current_image);
|
|
@@ -369,7 +370,7 @@ static int process_cmd(struct ec_state *ec,
|
|
|
struct fmap_entry *entry;
|
|
|
int ret, size;
|
|
|
|
|
|
- entry = &state->ec_config.region[EC_FLASH_REGION_RW];
|
|
|
+ entry = &ec->ec_config.region[EC_FLASH_REGION_RW];
|
|
|
|
|
|
switch (req->cmd) {
|
|
|
case EC_VBOOT_HASH_RECALC:
|
|
@@ -426,7 +427,7 @@ static int process_cmd(struct ec_state *ec,
|
|
|
case EC_FLASH_REGION_RO:
|
|
|
case EC_FLASH_REGION_RW:
|
|
|
case EC_FLASH_REGION_WP_RO:
|
|
|
- entry = &state->ec_config.region[req->region];
|
|
|
+ entry = &ec->ec_config.region[req->region];
|
|
|
resp->offset = entry->offset;
|
|
|
resp->size = entry->length;
|
|
|
len = sizeof(*resp);
|
|
@@ -466,16 +467,24 @@ static int process_cmd(struct ec_state *ec,
|
|
|
return len;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_DM_CROS_EC
|
|
|
+int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
|
|
|
+{
|
|
|
+ struct cros_ec_dev *dev = udev->uclass_priv;
|
|
|
+ struct ec_state *ec = dev_get_priv(dev->dev);
|
|
|
+#else
|
|
|
int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
|
|
|
int in_bytes)
|
|
|
{
|
|
|
+ struct ec_state *ec = &s_state;
|
|
|
+#endif
|
|
|
struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout;
|
|
|
const void *req_data = req_hdr + 1;
|
|
|
struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din;
|
|
|
void *resp_data = resp_hdr + 1;
|
|
|
int len;
|
|
|
|
|
|
- len = process_cmd(&s_state, req_hdr, req_data, resp_hdr, resp_data);
|
|
|
+ len = process_cmd(ec, req_hdr, req_data, resp_hdr, resp_data);
|
|
|
if (len < 0)
|
|
|
return len;
|
|
|
|
|
@@ -498,7 +507,11 @@ int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob)
|
|
|
|
|
|
void cros_ec_check_keyboard(struct cros_ec_dev *dev)
|
|
|
{
|
|
|
+#ifdef CONFIG_DM_CROS_EC
|
|
|
+ struct ec_state *ec = dev_get_priv(dev->dev);
|
|
|
+#else
|
|
|
struct ec_state *ec = &s_state;
|
|
|
+#endif
|
|
|
ulong start;
|
|
|
|
|
|
printf("Press keys for EC to detect on reset (ESC=recovery)...");
|
|
@@ -512,6 +525,52 @@ void cros_ec_check_keyboard(struct cros_ec_dev *dev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_DM_CROS_EC
|
|
|
+int cros_ec_probe(struct udevice *dev)
|
|
|
+{
|
|
|
+ struct ec_state *ec = dev->priv;
|
|
|
+ struct cros_ec_dev *cdev = dev->uclass_priv;
|
|
|
+ const void *blob = gd->fdt_blob;
|
|
|
+ int node;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ memcpy(ec, &s_state, sizeof(*ec));
|
|
|
+ err = cros_ec_decode_ec_flash(blob, dev->of_offset, &ec->ec_config);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
|
|
|
+ if (node < 0) {
|
|
|
+ debug("%s: No cros_ec keyboard found\n", __func__);
|
|
|
+ } else if (keyscan_read_fdt_matrix(ec, blob, node)) {
|
|
|
+ debug("%s: Could not read key matrix\n", __func__);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If we loaded EC data, check that the length matches */
|
|
|
+ if (ec->flash_data &&
|
|
|
+ ec->flash_data_len != ec->ec_config.flash.length) {
|
|
|
+ printf("EC data length is %x, expected %x, discarding data\n",
|
|
|
+ ec->flash_data_len, ec->ec_config.flash.length);
|
|
|
+ os_free(ec->flash_data);
|
|
|
+ ec->flash_data = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Otherwise allocate the memory */
|
|
|
+ if (!ec->flash_data) {
|
|
|
+ ec->flash_data_len = ec->ec_config.flash.length;
|
|
|
+ ec->flash_data = os_malloc(ec->flash_data_len);
|
|
|
+ if (!ec->flash_data)
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cdev->dev = dev;
|
|
|
+ g_state = ec;
|
|
|
+ return cros_ec_register(dev);
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
/**
|
|
|
* Initialize sandbox EC emulation.
|
|
|
*
|
|
@@ -562,3 +621,24 @@ int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_DM_CROS_EC
|
|
|
+struct dm_cros_ec_ops cros_ec_ops = {
|
|
|
+ .packet = cros_ec_sandbox_packet,
|
|
|
+};
|
|
|
+
|
|
|
+static const struct udevice_id cros_ec_ids[] = {
|
|
|
+ { .compatible = "google,cros-ec" },
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+U_BOOT_DRIVER(cros_ec_sandbox) = {
|
|
|
+ .name = "cros_ec",
|
|
|
+ .id = UCLASS_CROS_EC,
|
|
|
+ .of_match = cros_ec_ids,
|
|
|
+ .probe = cros_ec_probe,
|
|
|
+ .priv_auto_alloc_size = sizeof(struct ec_state),
|
|
|
+ .ops = &cros_ec_ops,
|
|
|
+};
|
|
|
+#endif
|