summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Honscheid <honscheid@google.com>2022-09-22 16:27:56 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-28 22:24:54 +0000
commit457ac8c4c99c114e697a1faf3c52cff2abc9d744 (patch)
treee7e29a548a411d1c586fcb7d59158b46e7f1b654
parent2d7186b81d446689e800c92c549c7252e269d4ac (diff)
downloadchrome-ec-457ac8c4c99c114e697a1faf3c52cff2abc9d744.tar.gz
zephyr: tests: I2C controller i2c_read32 and i2c_write32
Add tests for the functions `i2c_read32()` and `i2c_write32()` in `common/i2c_controller.c`. Also add a very basic I2C emulator for testing raw reads and writes. BRANCH=None BUG=b:248311206 TEST=./twister Signed-off-by: Tristan Honscheid <honscheid@google.com> Change-Id: Id41cbb853e76c456c0fb141bdb97c939687507f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3916557 Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Reviewed-by: Aaron Massey <aaronmassey@google.com>
-rw-r--r--zephyr/test/drivers/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/Kconfig3
-rw-r--r--zephyr/test/drivers/i2c_controller/CMakeLists.txt10
-rw-r--r--zephyr/test/drivers/i2c_controller/i2c.dts13
-rw-r--r--zephyr/test/drivers/i2c_controller/include/basic_i2c_device_emul.h24
-rw-r--r--zephyr/test/drivers/i2c_controller/src/basic_i2c_device_emul.c89
-rw-r--r--zephyr/test/drivers/i2c_controller/src/i2c_controller.c114
-rw-r--r--zephyr/test/drivers/testcase.yaml4
8 files changed, 258 insertions, 0 deletions
diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt
index 92b690a40a..41fe7ca7f7 100644
--- a/zephyr/test/drivers/CMakeLists.txt
+++ b/zephyr/test/drivers/CMakeLists.txt
@@ -48,6 +48,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_DEFAULT default)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_AP_MUX_CONTROL ap_mux_control)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_CHARGESPLASH chargesplash)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ISL923X isl923x)
+add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_I2C_CONTROLLER i2c_controller)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_KEYBOARD_SCAN keyboard_scan)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_LED_DRIVER led_driver)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_MKBP mkbp)
diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig
index bcaec2a8f2..900900dc56 100644
--- a/zephyr/test/drivers/Kconfig
+++ b/zephyr/test/drivers/Kconfig
@@ -17,6 +17,9 @@ config LINK_TEST_SUITE_HOST_COMMANDS
config LINK_TEST_SUITE_ISL923X
bool "Link and test the isl923x tests"
+config LINK_TEST_SUITE_I2C_CONTROLLER
+ bool "Link and test the i2c_controller tests"
+
config LINK_TEST_SUITE_KEYBOARD_SCAN
bool "Link and test the keyboard_scan tests"
diff --git a/zephyr/test/drivers/i2c_controller/CMakeLists.txt b/zephyr/test/drivers/i2c_controller/CMakeLists.txt
new file mode 100644
index 0000000000..995146f493
--- /dev/null
+++ b/zephyr/test/drivers/i2c_controller/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright 2022 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+
+target_sources(app PRIVATE
+ src/basic_i2c_device_emul.c
+ src/i2c_controller.c
+)
diff --git a/zephyr/test/drivers/i2c_controller/i2c.dts b/zephyr/test/drivers/i2c_controller/i2c.dts
new file mode 100644
index 0000000000..e36a6484c8
--- /dev/null
+++ b/zephyr/test/drivers/i2c_controller/i2c.dts
@@ -0,0 +1,13 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+&i2c0 {
+ /* Add a test I2C define */
+ basic_i2c_device: basic_i2c_device@ec {
+ compatible = "basic-i2c-device";
+ status = "okay";
+ reg = <0xec>;
+ };
+};
diff --git a/zephyr/test/drivers/i2c_controller/include/basic_i2c_device_emul.h b/zephyr/test/drivers/i2c_controller/include/basic_i2c_device_emul.h
new file mode 100644
index 0000000000..8d54e9a335
--- /dev/null
+++ b/zephyr/test/drivers/i2c_controller/include/basic_i2c_device_emul.h
@@ -0,0 +1,24 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdint.h>
+
+#include "emul/emul_common_i2c.h"
+
+/**
+ * @brief Emulator state struct
+ *
+ */
+struct basic_i2c_device_data {
+ struct i2c_common_emul_data common;
+ uint8_t regs[256];
+};
+
+/**
+ * @brief Resets the internal register store to default
+ *
+ * @param emul Pointer to the emulator object
+ */
+void basic_i2c_device_reset(const struct emul *emul);
diff --git a/zephyr/test/drivers/i2c_controller/src/basic_i2c_device_emul.c b/zephyr/test/drivers/i2c_controller/src/basic_i2c_device_emul.c
new file mode 100644
index 0000000000..b05fef6836
--- /dev/null
+++ b/zephyr/test/drivers/i2c_controller/src/basic_i2c_device_emul.c
@@ -0,0 +1,89 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/device.h>
+
+#include "basic_i2c_device_emul.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_stub_device.h"
+
+#define DT_DRV_COMPAT basic_i2c_device
+
+void basic_i2c_device_reset(const struct emul *emul)
+{
+ struct basic_i2c_device_data *data =
+ (struct basic_i2c_device_data *)emul->data;
+
+ memset(data->regs, 0, sizeof(data->regs));
+}
+
+static int basic_i2c_device_write(const struct emul *emul, int reg, uint8_t val,
+ int bytes, void *unused_data)
+{
+ struct basic_i2c_device_data *data =
+ (struct basic_i2c_device_data *)emul->data;
+
+ uint8_t *regs = data->regs;
+ int pos = reg + bytes - 1;
+
+ if (!IN_RANGE(pos, 0, sizeof(data->regs) - 1)) {
+ return -1;
+ }
+ regs[pos] = val;
+
+ return 0;
+}
+
+static int basic_i2c_device_read(const struct emul *emul, int reg, uint8_t *val,
+ int bytes, void *unused_data)
+{
+ struct basic_i2c_device_data *data =
+ (struct basic_i2c_device_data *)emul->data;
+
+ uint8_t *regs = data->regs;
+ int pos = reg + bytes;
+
+ if (!IN_RANGE(pos, 0, sizeof(data->regs) - 1)) {
+ return -1;
+ }
+ *val = regs[pos];
+
+ return 0;
+}
+
+static int basic_i2c_device_init(const struct emul *emul,
+ const struct device *parent)
+{
+ struct basic_i2c_device_data *data =
+ (struct basic_i2c_device_data *)emul->data;
+ struct i2c_common_emul_data *common_data = &data->common;
+
+ i2c_common_emul_init(common_data);
+ i2c_common_emul_set_read_func(common_data, basic_i2c_device_read, NULL);
+ i2c_common_emul_set_write_func(common_data, basic_i2c_device_write,
+ NULL);
+
+ basic_i2c_device_reset(emul);
+
+ return 0;
+}
+
+#define INIT_BASIC_I2C_DEVICE_EMUL(n) \
+ static struct i2c_common_emul_cfg common_cfg_##n; \
+ static struct basic_i2c_device_data basic_i2c_device_data_##n; \
+ static struct i2c_common_emul_cfg common_cfg_##n = { \
+ .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \
+ .data = &basic_i2c_device_data_##n.common, \
+ .addr = DT_INST_REG_ADDR(n) \
+ }; \
+ static struct basic_i2c_device_data basic_i2c_device_data_##n = { \
+ .common = { .cfg = &common_cfg_##n } \
+ }; \
+ EMUL_DT_INST_DEFINE(n, basic_i2c_device_init, \
+ &basic_i2c_device_data_##n, &common_cfg_##n, \
+ &i2c_common_emul_api)
+
+DT_INST_FOREACH_STATUS_OKAY(INIT_BASIC_I2C_DEVICE_EMUL);
+
+DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE);
diff --git a/zephyr/test/drivers/i2c_controller/src/i2c_controller.c b/zephyr/test/drivers/i2c_controller/src/i2c_controller.c
new file mode 100644
index 0000000000..cb48a84d38
--- /dev/null
+++ b/zephyr/test/drivers/i2c_controller/src/i2c_controller.c
@@ -0,0 +1,114 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/device.h>
+#include <zephyr/fff.h>
+#include <zephyr/sys/byteorder.h>
+#include <zephyr/ztest.h>
+
+#include "basic_i2c_device_emul.h"
+#include "i2c.h"
+#include "test/drivers/test_state.h"
+
+struct i2c_controller_fixture {
+ int port;
+ int addr;
+ const struct emul *emul;
+ struct basic_i2c_device_data *emul_data;
+};
+
+ZTEST_F(i2c_controller, write_read32_le)
+{
+ uint32_t expected = 0xAABBCCDD;
+ uint32_t actual;
+
+ zassert_ok(i2c_write32(fixture->port, fixture->addr, 0, expected));
+
+ /* Get the first four bytes of the register space as a uint32_t */
+ actual = *((uint32_t *)&fixture->emul_data->regs[0]);
+
+ zassert_equal(expected, actual, "got %08x, expected %08x", actual,
+ expected);
+
+ /* Now read back through I2C API */
+ zassert_ok(i2c_read32(fixture->port, fixture->addr, 0, &actual));
+
+ zassert_equal(expected, actual, "got %08x, expected %08x", actual,
+ expected);
+}
+
+ZTEST_F(i2c_controller, write_read32_be)
+{
+ uint32_t expected = 0xAABBCCDD;
+ uint32_t actual;
+
+ zassert_ok(i2c_write32(fixture->port,
+ fixture->addr | I2C_FLAG_BIG_ENDIAN, 0,
+ expected));
+
+ /* Get the first four bytes of the register space as a uint32_t */
+ actual = __bswap_32(*((uint32_t *)&fixture->emul_data->regs[0]));
+
+ zassert_equal(expected, actual, "got %08x, expected %08x", actual,
+ expected);
+
+ /* Now read back through I2C API */
+ zassert_ok(i2c_read32(fixture->port,
+ fixture->addr | I2C_FLAG_BIG_ENDIAN, 0, &actual));
+
+ zassert_equal(expected, actual, "got %08x, expected %08x", actual,
+ expected);
+}
+
+ZTEST_F(i2c_controller, read32_fail)
+{
+ int ret;
+ uint32_t data;
+
+ /* Fail by reading from wrong address */
+ ret = i2c_read32(fixture->port, fixture->addr + 1, 0, &data);
+
+ zassert_equal(EC_ERROR_INVAL, ret, "Got %d", ret);
+}
+
+ZTEST_F(i2c_controller, write32_fail)
+{
+ int ret;
+
+ /* Fail by writing to wrong address */
+ ret = i2c_write32(fixture->port, fixture->addr + 1, 0, 0x00000000);
+
+ zassert_equal(EC_ERROR_INVAL, ret, "Got %d", ret);
+}
+
+static void *setup(void)
+{
+ static struct i2c_controller_fixture fixture;
+ const struct emul *emul = EMUL_DT_GET(DT_NODELABEL(basic_i2c_device));
+ struct basic_i2c_device_data *emul_data =
+ (struct basic_i2c_device_data *)emul->data;
+
+ fixture.port = I2C_PORT_BY_DEV(DT_NODELABEL(basic_i2c_device));
+ fixture.addr = emul_data->common.cfg->addr;
+ fixture.emul = emul;
+ fixture.emul_data = emul_data;
+
+ return &fixture;
+}
+
+static void reset(void *data)
+{
+ struct i2c_controller_fixture *f =
+ (struct i2c_controller_fixture *)data;
+
+ basic_i2c_device_reset(f->emul);
+
+ i2c_common_emul_set_read_fail_reg(&f->emul_data->common,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_write_fail_reg(&f->emul_data->common,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_SUITE(i2c_controller, drivers_predicate_post_main, setup, reset, reset,
+ NULL);
diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml
index 329eb445dd..352025f89b 100644
--- a/zephyr/test/drivers/testcase.yaml
+++ b/zephyr/test/drivers/testcase.yaml
@@ -47,6 +47,10 @@ tests:
extra_configs:
- CONFIG_LINK_TEST_SUITE_ISL923X=y
- CONFIG_POWER_SEQUENCE_MOCK=y
+ drivers.i2c_controller:
+ extra_args: DTC_OVERLAY_FILE="./boards/native_posix.overlay;i2c_controller/i2c.dts"
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_I2C_CONTROLLER=y
drivers.keyboard_scan:
extra_configs:
- CONFIG_LINK_TEST_SUITE_KEYBOARD_SCAN=y