cros_ec: Add a function for the hello message
authorSimon Glass <sjg@chromium.org>
Sat, 16 Jan 2021 21:52:22 +0000 (14:52 -0700)
committerSimon Glass <sjg@chromium.org>
Sat, 30 Jan 2021 21:25:41 +0000 (14:25 -0700)
This is used several times in this file. Put it in a function to avoid
code duplication.

Also add a test for this function. There are no cros_ec tests at present,
so it is time to update the code.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/sandbox/include/asm/test.h
drivers/misc/cros_ec.c
drivers/misc/cros_ec_sandbox.c
include/cros_ec.h
test/dm/Makefile
test/dm/cros_ec.c [new file with mode: 0644]

index 05f66f700ca364bfac804c7dd39e3bcf07c94b88..8363ca73195c1fec030ad8daf6068a089e4db4b9 100644 (file)
@@ -57,6 +57,12 @@ enum {
        SYSCON_COUNT
 };
 
+/**
+ */
+enum cros_ec_test_t {
+       CROSECT_BREAK_HELLO     = BIT(1),
+};
+
 /**
  * sandbox_i2c_set_test_mode() - set test mode for running unit tests
  *
@@ -260,4 +266,12 @@ uint sandbox_pci_read_bar(u32 barval, int type, uint size);
  */
 void sandbox_set_enable_memio(bool enable);
 
+/**
+ * sandbox_cros_ec_set_test_flags() - Set behaviour for testing purposes
+ *
+ * @dev: Device to check
+ * @flags: Flags to control behaviour (CROSECT_...)
+ */
+void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags);
+
 #endif
index f03b7d55d649803a63fe15852d456b90aaed5610..013c67e04648fa60a1959baadb1a309d2a561003 100644 (file)
@@ -591,6 +591,25 @@ static int cros_ec_invalidate_hash(struct udevice *dev)
        return 0;
 }
 
+int cros_ec_hello(struct udevice *dev, uint *handshakep)
+{
+       struct ec_params_hello req;
+       struct ec_response_hello *resp;
+
+       req.in_data = 0x12345678;
+       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
+                            (uint8_t **)&resp, sizeof(*resp)) < 0)
+               return -EIO;
+       if (resp->out_data != req.in_data + 0x01020304) {
+               printf("Received invalid handshake %x\n", resp->out_data);
+               if (handshakep)
+                       *handshakep = req.in_data;
+               return -ENOTSYNC;
+       }
+
+       return 0;
+}
+
 int cros_ec_reboot(struct udevice *dev, enum ec_reboot_cmd cmd, uint8_t flags)
 {
        struct ec_params_reboot_ec p;
@@ -738,7 +757,6 @@ static int cros_ec_check_version(struct udevice *dev)
 {
        struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
        struct ec_params_hello req;
-       struct ec_response_hello *resp;
 
        struct dm_cros_ec_ops *ops;
        int ret;
@@ -767,14 +785,14 @@ static int cros_ec_check_version(struct udevice *dev)
        /* Try sending a version 3 packet */
        cdev->protocol_version = 3;
        req.in_data = 0;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                            (uint8_t **)&resp, sizeof(*resp)) > 0)
+       ret = cros_ec_hello(dev, NULL);
+       if (!ret || ret == -ENOTSYNC)
                return 0;
 
        /* Try sending a version 2 packet */
        cdev->protocol_version = 2;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                            (uint8_t **)&resp, sizeof(*resp)) > 0)
+       ret = cros_ec_hello(dev, NULL);
+       if (!ret || ret == -ENOTSYNC)
                return 0;
 
        /*
@@ -790,18 +808,16 @@ static int cros_ec_check_version(struct udevice *dev)
 
 int cros_ec_test(struct udevice *dev)
 {
-       struct ec_params_hello req;
-       struct ec_response_hello *resp;
+       uint out_data;
+       int ret;
 
-       req.in_data = 0x12345678;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                      (uint8_t **)&resp, sizeof(*resp)) < sizeof(*resp)) {
+       ret = cros_ec_hello(dev, &out_data);
+       if (ret == -ENOTSYNC) {
+               printf("Received invalid handshake %x\n", out_data);
+               return ret;
+       } else if (ret) {
                printf("ec_command_inptr() returned error\n");
-               return -1;
-       }
-       if (resp->out_data != req.in_data + 0x01020304) {
-               printf("Received invalid handshake %x\n", resp->out_data);
-               return -1;
+               return ret;
        }
 
        return 0;
index 9fd6cc2086ccab1b50c18700f0f2a593848e3f24..1922a9c1b966d2033b11786ce76807739af841ba 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/malloc.h>
 #include <asm/state.h>
 #include <asm/sdl.h>
+#include <asm/test.h>
 #include <linux/input.h>
 
 /*
@@ -73,6 +74,7 @@ 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
  */
 struct ec_state {
        u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
@@ -84,6 +86,7 @@ struct ec_state {
        struct ec_keymatrix_entry *matrix;      /* the key matrix info */
        uint8_t keyscan[KEYBOARD_COLS];
        bool recovery_req;
+       uint test_flags;
 } s_state, *g_state;
 
 /**
@@ -295,6 +298,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;
        }
@@ -518,6 +523,13 @@ void cros_ec_check_keyboard(struct udevice *dev)
        }
 }
 
+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);
index f187bd0d4b5bc5d67e7cbb2e1014a044d87256c6..f57e0cc45017f6e996c396b0c3e648f635095c1d 100644 (file)
@@ -497,4 +497,15 @@ int cros_ec_get_lid_shutdown_mask(struct udevice *dev);
  */
 int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable);
 
+/**
+ * cros_ec_hello() - Send a hello message
+ *
+ * Sends a message with a fixed input value and checks that the expected output
+ * value is received
+ *
+ * @dev: CROS-EC device
+ * @handshakep: If non-NULL, returns received handshake value on error
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_hello(struct udevice *dev, uint *handshakep);
 #endif
index 46e076ed099d2cf0bdc1f6ca45f35e6233033b42..afcabfacc1bd7a2b5ff1ba8bd794f0bca4da9acb 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BUTTON) += button.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
 obj-$(CONFIG_CLK) += clk.o clk_ccf.o
+obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-$(CONFIG_DEVRES) += devres.o
 obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
 obj-$(CONFIG_DM_ETH) += eth.o
diff --git a/test/dm/cros_ec.c b/test/dm/cros_ec.c
new file mode 100644 (file)
index 0000000..823245c
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <cros_ec.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_cros_ec_hello(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       uint val;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+
+       ut_assertok(cros_ec_hello(dev, NULL));
+
+       val = 0xdead1357;
+       ut_assertok(cros_ec_hello(dev, &val));
+       ut_asserteq(0xdead1357, val);
+
+       sandbox_cros_ec_set_test_flags(dev, CROSECT_BREAK_HELLO);
+       ut_asserteq(-ENOTSYNC, cros_ec_hello(dev, &val));
+       ut_asserteq(0x12345678, val);
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_hello, UT_TESTF_SCAN_FDT);