aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/cros_ec_sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cros_ec_sandbox.c')
-rw-r--r--drivers/misc/cros_ec_sandbox.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 9fd6cc2086..cb8adc4495 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -18,6 +18,7 @@
#include <asm/malloc.h>
#include <asm/state.h>
#include <asm/sdl.h>
+#include <asm/test.h>
#include <linux/input.h>
/*
@@ -61,6 +62,15 @@ struct ec_keymatrix_entry {
int keycode; /* corresponding linux key code */
};
+enum {
+ VSTORE_SLOT_COUNT = 4,
+};
+
+struct vstore_slot {
+ bool locked;
+ u8 data[EC_VSTORE_SLOT_SIZE];
+};
+
/**
* struct ec_state - Information about the EC state
*
@@ -73,6 +83,8 @@ struct ec_keymatrix_entry {
* @matrix: Information about keyboard matrix
* @keyscan: Current keyscan information (bit set for each row/column pressed)
* @recovery_req: Keyboard recovery requested
+ * @test_flags: Flags that control behaviour for tests
+ * @slot_locked: Locked vstore slots (mask)
*/
struct ec_state {
u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
@@ -84,6 +96,8 @@ struct ec_state {
struct ec_keymatrix_entry *matrix; /* the key matrix info */
uint8_t keyscan[KEYBOARD_COLS];
bool recovery_req;
+ uint test_flags;
+ struct vstore_slot slot[VSTORE_SLOT_COUNT];
} s_state, *g_state;
/**
@@ -295,6 +309,8 @@ static int process_cmd(struct ec_state *ec,
struct ec_response_hello *resp = resp_data;
resp->out_data = req->in_data + 0x01020304;
+ if (ec->test_flags & CROSECT_BREAK_HELLO)
+ resp->out_data++;
len = sizeof(*resp);
break;
}
@@ -358,10 +374,20 @@ static int process_cmd(struct ec_state *ec,
resp->mask |= EC_HOST_EVENT_MASK(
EC_HOST_EVENT_KEYBOARD_RECOVERY);
}
-
+ if (ec->test_flags & CROSECT_LID_OPEN)
+ resp->mask |=
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN);
len = sizeof(*resp);
break;
}
+ case EC_CMD_HOST_EVENT_CLEAR_B: {
+ const struct ec_params_host_event_mask *req = req_data;
+
+ if (req->mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN))
+ ec->test_flags &= ~CROSECT_LID_OPEN;
+ len = 0;
+ break;
+ }
case EC_CMD_VBOOT_HASH: {
const struct ec_params_vboot_hash *req = req_data;
struct ec_response_vboot_hash *resp = resp_data;
@@ -468,6 +494,62 @@ static int process_cmd(struct ec_state *ec,
len = sizeof(*resp);
break;
}
+ case EC_CMD_GET_SKU_ID: {
+ struct ec_sku_id_info *resp = resp_data;
+
+ resp->sku_id = 1234;
+ len = sizeof(*resp);
+ break;
+ }
+ case EC_CMD_GET_FEATURES: {
+ struct ec_response_get_features *resp = resp_data;
+
+ resp->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FLASH) |
+ EC_FEATURE_MASK_0(EC_FEATURE_I2C) |
+ EC_FEATURE_MASK_0(EC_FEATURE_VSTORE);
+ resp->flags[1] =
+ EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS) |
+ EC_FEATURE_MASK_1(EC_FEATURE_ISH);
+ len = sizeof(*resp);
+ break;
+ }
+ case EC_CMD_VSTORE_INFO: {
+ struct ec_response_vstore_info *resp = resp_data;
+ int i;
+
+ resp->slot_count = VSTORE_SLOT_COUNT;
+ resp->slot_locked = 0;
+ for (i = 0; i < VSTORE_SLOT_COUNT; i++) {
+ if (ec->slot[i].locked)
+ resp->slot_locked |= 1 << i;
+ }
+ len = sizeof(*resp);
+ break;
+ };
+ case EC_CMD_VSTORE_WRITE: {
+ const struct ec_params_vstore_write *req = req_data;
+ struct vstore_slot *slot;
+
+ if (req->slot >= EC_VSTORE_SLOT_MAX)
+ return -EINVAL;
+ slot = &ec->slot[req->slot];
+ slot->locked = true;
+ memcpy(slot->data, req->data, EC_VSTORE_SLOT_SIZE);
+ len = 0;
+ break;
+ }
+ case EC_CMD_VSTORE_READ: {
+ const struct ec_params_vstore_read *req = req_data;
+ struct ec_response_vstore_read *resp = resp_data;
+ struct vstore_slot *slot;
+
+ if (req->slot >= EC_VSTORE_SLOT_MAX)
+ return -EINVAL;
+ slot = &ec->slot[req->slot];
+ memcpy(resp->data, slot->data, EC_VSTORE_SLOT_SIZE);
+ len = sizeof(*resp);
+ break;
+ }
default:
printf(" ** Unknown EC command %#02x\n", req_hdr->command);
return -1;
@@ -518,6 +600,21 @@ void cros_ec_check_keyboard(struct udevice *dev)
}
}
+/* Return the byte of EC switch states */
+static int cros_ec_sandbox_get_switches(struct udevice *dev)
+{
+ struct ec_state *ec = dev_get_priv(dev);
+
+ return ec->test_flags & CROSECT_LID_OPEN ? EC_SWITCH_LID_OPEN : 0;
+}
+
+void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags)
+{
+ struct ec_state *ec = dev_get_priv(dev);
+
+ ec->test_flags = flags;
+}
+
int cros_ec_probe(struct udevice *dev)
{
struct ec_state *ec = dev_get_priv(dev);
@@ -573,6 +670,7 @@ int cros_ec_probe(struct udevice *dev)
struct dm_cros_ec_ops cros_ec_ops = {
.packet = cros_ec_sandbox_packet,
+ .get_switches = cros_ec_sandbox_get_switches,
};
static const struct udevice_id cros_ec_ids[] = {