summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Bettis <jbettis@google.com>2022-08-16 11:13:21 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-08-17 22:35:12 +0000
commit96af58d5d8e438628342bca6458d8cd2987df7b6 (patch)
treed13fb3d854f33baf1d0c6e8e8c9e8e17926b6f24
parentb37f579fdaa277bc0b89fd255fa2a7535f06e24d (diff)
downloadchrome-ec-96af58d5d8e438628342bca6458d8cd2987df7b6.tar.gz
zephyr: Added test for steelix board specific coderelease-R106-15054.B-main
Add a dts file for native_posix tests that want to use npcx gpios and interrupts. There is more work to be done to make it full featured. Specifically the npcx pinctrl driver really needs an emulator. Add test for the board specific code in steelix. This is mostly a sample on how to do this, more than being that useful of a test on it's own. BRANCH=None BUG=b:242032118 TEST=./twister --coverage -T zephyr/test/kingler Signed-off-by: Jeremy Bettis <jbettis@google.com> Change-Id: I9436a447e7cd4f3baa743c77d4b2d89bafeb0c9c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3833914 Tested-by: Jeremy Bettis <jbettis@chromium.org> Commit-Queue: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Yuval Peress <peress@google.com> Reviewed-by: Simon Glass <sjg@chromium.org> Auto-Submit: Jeremy Bettis <jbettis@chromium.org> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r--zephyr/dts/npcx_emul.dts266
-rw-r--r--zephyr/test/kingler/CMakeLists.txt16
-rw-r--r--zephyr/test/kingler/Kconfig15
-rw-r--r--zephyr/test/kingler/README.md3
-rw-r--r--zephyr/test/kingler/common.dts153
-rw-r--r--zephyr/test/kingler/prj.conf31
-rw-r--r--zephyr/test/kingler/src/clamshell.c89
-rw-r--r--zephyr/test/kingler/src/fakes.c22
-rw-r--r--zephyr/test/kingler/src/tablet.c91
-rw-r--r--zephyr/test/kingler/testcase.yaml15
10 files changed, 701 insertions, 0 deletions
diff --git a/zephyr/dts/npcx_emul.dts b/zephyr/dts/npcx_emul.dts
new file mode 100644
index 0000000000..a0357d7a88
--- /dev/null
+++ b/zephyr/dts/npcx_emul.dts
@@ -0,0 +1,266 @@
+/* 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.
+ */
+
+/* Contains emulators for devices normally found on NPCX chips.
+ * To use, include this file, then the board's gpio definitions.
+ */
+
+#include <dt-bindings/gpio_defines.h>
+
+/ {
+ gpio1: gpio@101 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x101 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio3: gpio@301 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x301 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio4: gpio@400 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x400 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio5: gpio@500 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x500 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio6: gpio@600 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x600 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio7: gpio@700 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x700 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio8: gpio@801 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x801 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpio9: gpio@900 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0x900 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpioa: gpio@a00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xa00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpiob: gpio@b00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xb00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpioc: gpio@c00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xc00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpiod: gpio@d00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xd00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpioe: gpio@e00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xe00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ gpiof: gpio@f00 {
+ status = "okay";
+ compatible = "zephyr,gpio-emul";
+ reg = <0xf00 0x4>;
+ rising-edge;
+ falling-edge;
+ high-level;
+ low-level;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+
+ i2c_ctrl0: i2c@40009000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40009000 0x1000>;
+ };
+ i2c_ctrl1: i2c@4000b000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4000b000 0x1000>;
+ };
+
+ i2c_ctrl2: i2c@400c0000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x400c0000 0x1000>;
+ };
+
+ i2c_ctrl3: i2c@400c2000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x400c2000 0x1000>;
+ };
+
+ i2c_ctrl4: i2c@40008000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40008000 0x1000>;
+ };
+
+ i2c_ctrl5: i2c@40017000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40017000 0x1000>;
+ };
+
+ i2c_ctrl6: i2c@40018000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40018000 0x1000>;
+ };
+
+ i2c_ctrl7: i2c@40019000 {
+ status = "okay";
+ compatible = "zephyr,i2c-emul-controller";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40019000 0x1000>;
+ };
+ scfg: scfg@400c3000 {
+ compatible = "nuvoton,npcx-scfg";
+ /* First reg region is System Configuration Device */
+ /* Second reg region is System Glue Device */
+ reg = <0x400c3000 0x70
+ 0x400a5000 0x2000>;
+ reg-names = "scfg", "glue";
+ #alt-cells = <3>;
+ #lvol-cells = <2>;
+ };
+};
+
+&gpio0 {
+ ngpios = <8>;
+};
diff --git a/zephyr/test/kingler/CMakeLists.txt b/zephyr/test/kingler/CMakeLists.txt
new file mode 100644
index 0000000000..eaaf04fe4d
--- /dev/null
+++ b/zephyr/test/kingler/CMakeLists.txt
@@ -0,0 +1,16 @@
+# 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.
+
+cmake_minimum_required(VERSION 3.13.1)
+find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}")
+project(kingler)
+
+target_sources(app PRIVATE ${PLATFORM_EC}/zephyr/projects/corsola/src/kingler/board_steelix.c)
+
+target_sources(app PRIVATE src/fakes.c)
+
+target_sources_ifdef(CONFIG_TEST_FORM_FACTOR_CONVERTIBLE
+ app PRIVATE src/tablet.c)
+target_sources_ifdef(CONFIG_TEST_FORM_FACTOR_CLAMSHELL
+ app PRIVATE src/clamshell.c)
diff --git a/zephyr/test/kingler/Kconfig b/zephyr/test/kingler/Kconfig
new file mode 100644
index 0000000000..d284e646a2
--- /dev/null
+++ b/zephyr/test/kingler/Kconfig
@@ -0,0 +1,15 @@
+# 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.
+
+config TEST_FORM_FACTOR_CLAMSHELL
+ bool "Run the tests intended for clamshells"
+ help
+ Include clamshell tests into the binary.
+
+config TEST_FORM_FACTOR_CONVERTIBLE
+ bool "Run the tests intended for convertibles"
+ help
+ Include convertible tests into the binary.
+
+source "Kconfig.zephyr"
diff --git a/zephyr/test/kingler/README.md b/zephyr/test/kingler/README.md
new file mode 100644
index 0000000000..bac3afced2
--- /dev/null
+++ b/zephyr/test/kingler/README.md
@@ -0,0 +1,3 @@
+Tests for board specific code under `zephyr/projects/corsola/src/kingler`.
+
+Run with ./twister -T zephyr/test/kingler
diff --git a/zephyr/test/kingler/common.dts b/zephyr/test/kingler/common.dts
new file mode 100644
index 0000000000..173e6aef5e
--- /dev/null
+++ b/zephyr/test/kingler/common.dts
@@ -0,0 +1,153 @@
+/* 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 <board-overlays/native_posix.dts>
+#include <npcx_emul.dts>
+
+/ {
+ /* These are temporary just to get the test to build.
+ * Should be replaced with the correct accel drivers,
+ * but we're not testing that code right now anyway.
+ */
+ motionsense-sensor-data {
+ bmi160_data: bmi160-drv-data {
+ compatible = "cros-ec,drvdata-bmi160";
+ status = "okay";
+ };
+ };
+ motionsense-sensor {
+ base_accel: ms-bmi160-accel {
+ compatible = "cros-ec,bmi160-accel";
+ status = "okay";
+
+ active-mask = "SENSOR_ACTIVE_S0_S3_S5";
+ location = "MOTIONSENSE_LOC_BASE";
+ drv-data = <&bmi160_data>;
+ default-range = <4>;
+ i2c-spi-addr-flags = "BMI160_ADDR0_FLAGS";
+ };
+ lid_accel: ms-bmi160-accel2 {
+ compatible = "cros-ec,bmi160-accel";
+ status = "okay";
+
+ active-mask = "SENSOR_ACTIVE_S0_S3_S5";
+ location = "MOTIONSENSE_LOC_BASE";
+ drv-data = <&bmi160_data>;
+ default-range = <4>;
+ i2c-spi-addr-flags = "BMI160_ADDR0_FLAGS";
+ };
+ };
+ motionsense-sensor-info {
+ compatible = "cros-ec,motionsense-sensor-info";
+
+ /*
+ * list of GPIO interrupts that have to
+ * be enabled at initial stage
+ */
+ sensor-irqs = <&int_base_imu>;
+ /* list of sensors in force mode */
+ accel-force-mode-sensors = <&lid_accel>;
+ };
+ named-i2c-ports {
+ compatible = "named-i2c-ports";
+ i2c_sensor: sensor {
+ i2c-port = <&i2c0_0>;
+ enum-names = "I2C_PORT_SENSOR";
+ };
+ };
+ /* TODO(jbettis): Move the i2c ports and pinctrls to npcx_emul.dts,
+ * and add all of them instead of just these.
+ */
+ soc-if {
+ i2c0_0: io_i2c_ctrl0_port0 {
+ compatible = "nuvoton,npcx-i2c-port";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port = <0x00>;
+ controller = <&i2c_ctrl0>;
+ status = "disabled";
+ };
+ i2c3_0: io_i2c_ctrl3_port0 {
+ compatible = "nuvoton,npcx-i2c-port";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port = <0x30>;
+ controller = <&i2c_ctrl3>;
+ status = "disabled";
+ };
+ };
+ pinctrl: pinctrl {
+ compatible = "nuvoton,npcx-pinctrl";
+ status = "okay";
+ /* I2C peripheral interfaces */
+ /omit-if-no-ref/ i2c0_0_sda_scl_gpb4_b5: periph-i2c0-0 {
+ pinmux = <&alt2_i2c0_0_sl>;
+ periph-pupd = <0x00 0>;
+ };
+ /omit-if-no-ref/ i2c3_0_sda_scl_gpd0_d1: periph-i2c3-0 {
+ pinmux = <&alt2_i2c3_0_sl>;
+ periph-pupd = <0x00 6>;
+ };
+ };
+ npcx-alts-map {
+ compatible = "nuvoton,npcx-pinctrl-conf";
+ /* SCFG DEVALT 2 */
+ alt2_i2c0_0_sl: alt20 {
+ alts = <&scfg 0x02 0x0 0>;
+ };
+ alt2_i2c3_0_sl: alt26 {
+ alts = <&scfg 0x02 0x6 0>;
+ };
+ };
+};
+
+&i2c0_0 {
+ label = "I2C_SENSOR";
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST>;
+ pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>;
+ pinctrl-names = "default";
+};
+
+&i2c_ctrl0 {
+ status = "okay";
+};
+
+&i2c_ctrl2 {
+ status = "okay";
+};
+
+i2c_pwr_cbi: &i2c3_0 {
+ label = "I2C_PWR_CBI";
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST>;
+ pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>;
+ pinctrl-names = "default";
+
+ charger: isl923x@9 {
+ compatible = "intersil,isl923x";
+ status = "okay";
+ reg = <0x9>;
+ };
+};
+
+&i2c_ctrl3 {
+ status = "okay";
+};
+
+&i2c_ctrl5 {
+ status = "okay";
+};
+
+&i2c_ctrl3 {
+ cbi_eeprom: eeprom@50 {
+ compatible = "atmel,at24";
+ reg = <0x50>;
+ size = <2048>;
+ pagesize = <16>;
+ address-width = <8>;
+ timeout = <5>;
+ };
+};
diff --git a/zephyr/test/kingler/prj.conf b/zephyr/test/kingler/prj.conf
new file mode 100644
index 0000000000..e9f5c8b89f
--- /dev/null
+++ b/zephyr/test/kingler/prj.conf
@@ -0,0 +1,31 @@
+# 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.
+
+CONFIG_ZTEST=y
+CONFIG_ZTEST_ASSERT_VERBOSE=1
+CONFIG_ZTEST_NEW_API=y
+CONFIG_ASSERT=y
+CONFIG_EMUL=y
+CONFIG_PLATFORM_EC_HOOKS=y
+
+CONFIG_CROS_EC=y
+CONFIG_PLATFORM_EC=y
+CONFIG_SHIMMED_TASKS=y
+
+CONFIG_PLATFORM_EC_MOTIONSENSE=y
+CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y
+CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y
+CONFIG_PLATFORM_EC_TABLET_MODE=y
+CONFIG_PLATFORM_EC_LID_ANGLE=y
+
+CONFIG_I2C=y
+CONFIG_I2C_NPCX=n
+
+CONFIG_PLATFORM_EC_CBI_EEPROM=y
+CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=y
+CONFIG_EEPROM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_SIMULATOR=n
+CONFIG_EMUL_EEPROM_AT2X=y
+CONFIG_EEPROM_SHELL=n
diff --git a/zephyr/test/kingler/src/clamshell.c b/zephyr/test/kingler/src/clamshell.c
new file mode 100644
index 0000000000..faa340add0
--- /dev/null
+++ b/zephyr/test/kingler/src/clamshell.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/kernel.h"
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/ztest.h>
+
+#include "cros_board_info.h"
+#include "cros_cbi.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "tablet_mode.h"
+
+static void *clamshell_setup(void)
+{
+ uint32_t val;
+ const struct device *wp_gpio =
+ DEVICE_DT_GET(DT_GPIO_CTLR(DT_ALIAS(gpio_wp), gpios));
+ const gpio_port_pins_t wp_pin = DT_GPIO_PIN(DT_ALIAS(gpio_wp), gpios);
+
+ /* Make sure that write protect is disabled */
+ zassert_ok(gpio_emul_input_set(wp_gpio, wp_pin, 1), NULL);
+ /* Set CBI form factor to CONVERTIBLE. */
+ zassert_ok(cbi_set_fw_config(CLAMSHELL << 13), NULL);
+ /* Run init hooks to initialize cbi. */
+ hook_notify(HOOK_INIT);
+
+ /* Check if CBI write worked. */
+ zassert_ok(cros_cbi_get_fw_config(FORM_FACTOR, &val), NULL);
+ zassert_equal(CLAMSHELL, val, "val=%d", val);
+
+ return NULL;
+}
+
+ZTEST_SUITE(steelix_clamshell, NULL, clamshell_setup, NULL, NULL, NULL);
+
+ZTEST(steelix_clamshell, test_gmr_tablet_switch_disabled)
+{
+ const struct device *tablet_mode_gpio = DEVICE_DT_GET(
+ DT_GPIO_CTLR(DT_NODELABEL(gpio_tablet_mode_l), gpios));
+ const gpio_port_pins_t tablet_mode_pin =
+ DT_GPIO_PIN(DT_NODELABEL(gpio_tablet_mode_l), gpios);
+
+ /* Verify gmr_tablet_switch is disabled, by checking the side effects
+ * of calling tablet_set_mode, and setting gpio_tablet_mode_l.
+ */
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 0),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(1, TABLET_TRIGGER_LID);
+ zassert_equal(0, tablet_get_mode(), NULL);
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 1),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
+ zassert_equal(0, tablet_get_mode(), NULL);
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 0),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(1, TABLET_TRIGGER_LID);
+ zassert_equal(0, tablet_get_mode(), NULL);
+}
+
+static int interrupt_count;
+
+void bmi3xx_interrupt(enum gpio_signal signal)
+{
+ interrupt_count++;
+}
+
+ZTEST(steelix_clamshell, test_base_imu_irq_disabled)
+{
+ const struct device *base_imu_gpio = DEVICE_DT_GET(
+ DT_GPIO_CTLR(DT_NODELABEL(base_imu_int_l), gpios));
+ const gpio_port_pins_t base_imu_pin =
+ DT_GPIO_PIN(DT_NODELABEL(base_imu_int_l), gpios);
+
+ /* Verify base_imu_irq is disabled. */
+ interrupt_count = 0;
+ zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 1), NULL);
+ k_sleep(K_MSEC(100));
+ zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 0), NULL);
+ k_sleep(K_MSEC(100));
+
+ zassert_equal(interrupt_count, 0, "interrupt_count=%d",
+ interrupt_count);
+}
diff --git a/zephyr/test/kingler/src/fakes.c b/zephyr/test/kingler/src/fakes.c
new file mode 100644
index 0000000000..5de43475ae
--- /dev/null
+++ b/zephyr/test/kingler/src/fakes.c
@@ -0,0 +1,22 @@
+/* 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/fff.h>
+#include "gpio_signal.h"
+
+DEFINE_FFF_GLOBALS;
+FAKE_VOID_FUNC(power_button_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(button_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(lid_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(chipset_reset_request_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(power_signal_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(chipset_watchdog_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(extpower_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(usb_a0_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(switch_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(tcpc_alert_event, enum gpio_signal);
+FAKE_VOID_FUNC(ppc_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(bc12_interrupt, enum gpio_signal);
+FAKE_VOID_FUNC(x_ec_interrupt, enum gpio_signal);
diff --git a/zephyr/test/kingler/src/tablet.c b/zephyr/test/kingler/src/tablet.c
new file mode 100644
index 0000000000..694cea3577
--- /dev/null
+++ b/zephyr/test/kingler/src/tablet.c
@@ -0,0 +1,91 @@
+/* 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/kernel.h"
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/ztest.h>
+
+#include "cros_board_info.h"
+#include "cros_cbi.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "tablet_mode.h"
+
+static void *tablet_setup(void)
+{
+ uint32_t val;
+ const struct device *wp_gpio =
+ DEVICE_DT_GET(DT_GPIO_CTLR(DT_ALIAS(gpio_wp), gpios));
+ const gpio_port_pins_t wp_pin = DT_GPIO_PIN(DT_ALIAS(gpio_wp), gpios);
+
+ /* Make sure that write protect is disabled */
+ zassert_ok(gpio_emul_input_set(wp_gpio, wp_pin, 1), NULL);
+ /* Set CBI form factor to CONVERTIBLE. */
+ zassert_ok(cbi_set_fw_config(CONVERTIBLE << 13), NULL);
+ /* Run init hooks to initialize cbi. */
+ hook_notify(HOOK_INIT);
+
+ /* Check if CBI write worked. */
+ zassert_ok(cros_cbi_get_fw_config(FORM_FACTOR, &val), NULL);
+ zassert_equal(CONVERTIBLE, val, "val=%d", val);
+
+ return NULL;
+}
+
+ZTEST_SUITE(steelix_tablet, NULL, tablet_setup, NULL, NULL, NULL);
+
+ZTEST(steelix_tablet, test_gmr_tablet_switch_enabled)
+{
+ const struct device *tablet_mode_gpio = DEVICE_DT_GET(
+ DT_GPIO_CTLR(DT_NODELABEL(gpio_tablet_mode_l), gpios));
+ const gpio_port_pins_t tablet_mode_pin =
+ DT_GPIO_PIN(DT_NODELABEL(gpio_tablet_mode_l), gpios);
+
+ /* Verify gmr_tablet_switch is enabled, by checking the side effects
+ * of calling tablet_set_mode, and setting gpio_tablet_mode_l.
+ */
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 0),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(1, TABLET_TRIGGER_LID);
+ zassert_equal(1, tablet_get_mode(), NULL);
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 1),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
+ zassert_equal(0, tablet_get_mode(), NULL);
+ zassert_ok(gpio_emul_input_set(tablet_mode_gpio, tablet_mode_pin, 0),
+ NULL);
+ k_sleep(K_MSEC(100));
+ tablet_set_mode(1, TABLET_TRIGGER_LID);
+ zassert_equal(1, tablet_get_mode(), NULL);
+}
+
+static int interrupt_count;
+
+void bmi3xx_interrupt(enum gpio_signal signal)
+{
+ interrupt_count++;
+}
+
+ZTEST(steelix_tablet, test_base_imu_irq_enabled)
+{
+ const struct device *base_imu_gpio = DEVICE_DT_GET(
+ DT_GPIO_CTLR(DT_NODELABEL(base_imu_int_l), gpios));
+ const gpio_port_pins_t base_imu_pin =
+ DT_GPIO_PIN(DT_NODELABEL(base_imu_int_l), gpios);
+
+ /* Verify base_imu_irq is enabled. Interrupt is configured
+ * GPIO_INT_EDGE_FALLING, so set high, then set low.
+ */
+ interrupt_count = 0;
+ zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 1), NULL);
+ k_sleep(K_MSEC(100));
+ zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 0), NULL);
+ k_sleep(K_MSEC(100));
+
+ zassert_equal(interrupt_count, 1, "interrupt_count=%d",
+ interrupt_count);
+}
diff --git a/zephyr/test/kingler/testcase.yaml b/zephyr/test/kingler/testcase.yaml
new file mode 100644
index 0000000000..e49c89ee47
--- /dev/null
+++ b/zephyr/test/kingler/testcase.yaml
@@ -0,0 +1,15 @@
+# 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.
+
+common:
+ platform_allow: native_posix
+tests:
+ kingler.steelix:
+ extra_args: DTC_OVERLAY_FILE="./common.dts;../projects/corsola/interrupts_kingler.dts;../projects/corsola/cbi_steelix.dts;../projects/corsola/gpio_steelix.dts"
+ extra_configs:
+ - CONFIG_TEST_FORM_FACTOR_CONVERTIBLE=y
+ kingler.rusty:
+ extra_args: DTC_OVERLAY_FILE="./common.dts;../projects/corsola/interrupts_kingler.dts;../projects/corsola/cbi_steelix.dts;../projects/corsola/gpio_steelix.dts"
+ extra_configs:
+ - CONFIG_TEST_FORM_FACTOR_CLAMSHELL=y