summaryrefslogtreecommitdiff
path: root/zephyr/test/drivers
diff options
context:
space:
mode:
authorAl Semjonovs <asemjonovs@google.com>2022-01-25 13:47:23 -0700
committerCommit Bot <commit-bot@chromium.org>2022-01-28 22:14:11 +0000
commit4a6ee66519fd49ce405614de30655ff637b4788b (patch)
treee5cb5278c261d7b52ac04ac3ef2866d674aaad63 /zephyr/test/drivers
parent60cdf31ebd01e26ec0d602902b0653f051607442 (diff)
downloadchrome-ec-4a6ee66519fd49ce405614de30655ff637b4788b.tar.gz
zephyr: drivers: Improve code coverage of gpio.c
Add test cases to improve code coverage of gpio.c Created new GPIO_TEST enum to avoid affecting other test cases. BRANCH=none BUG=b:216483477 TEST=zmake -D configure --coverage --test zephyr/test/drivers/ Signed-off-by: Al Semjonovs <asemjonovs@google.com> Change-Id: I2ead3610e3ed64b04702488707aa96988f38f378 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3417013 Reviewed-by: Yuval Peress <peress@google.com>
Diffstat (limited to 'zephyr/test/drivers')
-rw-r--r--zephyr/test/drivers/include/stubs.h2
-rw-r--r--zephyr/test/drivers/overlay.dts11
-rw-r--r--zephyr/test/drivers/src/gpio.c339
-rw-r--r--zephyr/test/drivers/src/stubs.c9
4 files changed, 360 insertions, 1 deletions
diff --git a/zephyr/test/drivers/include/stubs.h b/zephyr/test/drivers/include/stubs.h
index 2ea3ec6288..2e03142d72 100644
--- a/zephyr/test/drivers/include/stubs.h
+++ b/zephyr/test/drivers/include/stubs.h
@@ -26,4 +26,6 @@ DECLARE_FAKE_VOID_FUNC(system_hibernate, uint32_t, uint32_t);
void sys_arch_reboot(int type);
+/* Declare GPIO_TEST interrupt handler */
+void gpio_test_interrupt(enum gpio_signal signal);
#endif /* __TEST_DRIVERS_STUBS_H */
diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts
index fe8e604754..2cd815da00 100644
--- a/zephyr/test/drivers/overlay.dts
+++ b/zephyr/test/drivers/overlay.dts
@@ -132,6 +132,10 @@
gpios = <&gpio0 26 (GPIO_INPUT | GPIO_PULL_DOWN)>;
enum-name = "GPIO_SWITCHCAP_PG";
};
+ gpio_test: test {
+ gpios = <&gpio0 27 (GPIO_INPUT | GPIO_OUTPUT)>;
+ enum-name = "GPIO_TEST";
+ };
};
gpio-interrupts {
@@ -167,6 +171,11 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "ln9310_interrupt";
};
+ int_gpio_test: test {
+ irq-gpio = <&gpio_test>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "gpio_test_interrupt";
+ };
};
named-i2c-ports {
@@ -653,7 +662,7 @@
};
&gpio0 {
- ngpios = <27>;
+ ngpios = <28>;
};
&i2c0 {
diff --git a/zephyr/test/drivers/src/gpio.c b/zephyr/test/drivers/src/gpio.c
new file mode 100644
index 0000000000..158c2e9321
--- /dev/null
+++ b/zephyr/test/drivers/src/gpio.c
@@ -0,0 +1,339 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @file
+ * @brief Unit Tests for GPIO.
+ */
+
+#include <device.h>
+
+#include <drivers/gpio/gpio_emul.h>
+#include <logging/log.h>
+#include <zephyr.h>
+#include <ztest.h>
+
+#include "common.h"
+#include "ec_tasks.h"
+#include "gpio.h"
+#include "gpio/gpio.h"
+#include "stubs.h"
+#include "util.h"
+#include "test_state.h"
+
+/**
+ * @brief TestPurpose: Verify Zephyr to EC GPIO bitmask conversion.
+ *
+ * @details
+ * Validate Zephyr to EC GPIO bitmask conversion.
+ *
+ * Expected Results
+ * - GPIO bitmask conversions are successful
+ */
+ZTEST(gpio, test_convert_from_zephyr_flags)
+{
+ int retval;
+ struct {
+ int zephyr_bmask;
+ gpio_flags_t expected_ec_bmask;
+ } validate[] = {
+ { GPIO_DISCONNECTED, GPIO_FLAG_NONE },
+ { GPIO_OUTPUT_INIT_LOW, GPIO_LOW },
+ { GPIO_OUTPUT_INIT_HIGH, GPIO_HIGH },
+ { GPIO_VOLTAGE_1P8, GPIO_SEL_1P8V },
+ { GPIO_INT_ENABLE, GPIO_FLAG_NONE },
+ { GPIO_INT_ENABLE | GPIO_INT_EDGE, GPIO_FLAG_NONE },
+ { GPIO_INT_ENABLE | GPIO_INT_EDGE | GPIO_INT_HIGH_1,
+ GPIO_INT_F_RISING },
+ { GPIO_INT_ENABLE | GPIO_INT_EDGE | GPIO_INT_LOW_0,
+ GPIO_INT_F_FALLING },
+ { GPIO_INT_ENABLE | GPIO_INT_HIGH_1, GPIO_INT_F_HIGH },
+ { GPIO_INT_ENABLE | GPIO_INT_LOW_0, GPIO_INT_F_LOW },
+ { GPIO_OUTPUT_INIT_LOGICAL, 0 },
+ { GPIO_OPEN_DRAIN | GPIO_PULL_UP,
+ GPIO_OPEN_DRAIN | GPIO_PULL_UP },
+ };
+ int num_tests = ARRAY_SIZE(validate);
+
+ for (int i = 0; i < num_tests; i++) {
+ retval = convert_from_zephyr_flags(validate[i].zephyr_bmask);
+ zassert_equal(validate[i].expected_ec_bmask, retval,
+ "[%d] Expected 0x%08X, returned 0x%08X.", i,
+ validate[i].expected_ec_bmask, retval);
+ }
+}
+
+/**
+ * @brief TestPurpose: Verify EC to Zephyr GPIO bitmask conversion.
+ *
+ * @details
+ * Validate EC to Zephyr GPIO bitmask conversion.
+ *
+ * Expected Results
+ * - GPIO bitmask conversions are successful
+ */
+ZTEST(gpio, test_convert_to_zephyr_flags)
+{
+ gpio_flags_t retval;
+
+ struct {
+ gpio_flags_t ec_bmask;
+ int expected_zephyr_bmask;
+ } validate[] = {
+ { GPIO_FLAG_NONE, GPIO_DISCONNECTED },
+ { GPIO_LOW, GPIO_OUTPUT_INIT_LOW },
+ { GPIO_HIGH, GPIO_OUTPUT_INIT_HIGH },
+ { GPIO_INT_F_RISING,
+ GPIO_INT_ENABLE | GPIO_INT_EDGE | GPIO_INT_HIGH_1 },
+ { GPIO_INT_F_FALLING,
+ GPIO_INT_ENABLE | GPIO_INT_EDGE | GPIO_INT_LOW_0 },
+ { GPIO_INT_F_LOW, GPIO_INT_ENABLE | GPIO_INT_LOW_0 },
+ { GPIO_INT_F_HIGH, GPIO_INT_ENABLE | GPIO_INT_HIGH_1 },
+ { GPIO_SEL_1P8V, GPIO_VOLTAGE_1P8 },
+ { GPIO_LOCKED, 0 },
+ };
+ int num_tests = ARRAY_SIZE(validate);
+
+ for (int i = 0; i < num_tests; i++) {
+ retval = convert_to_zephyr_flags(validate[i].ec_bmask);
+ zassert_equal(validate[i].expected_zephyr_bmask, retval,
+ "[%d] Expected 0x%08X, returned 0x%08X.", i,
+ validate[i].expected_zephyr_bmask, retval);
+ }
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO signal_is_gpio.
+ *
+ * @details
+ * Validate signal_is_gpio
+ *
+ * Expected Results
+ * - Success
+ */
+ZTEST(gpio, test_signal_is_gpio)
+{
+ zassert_true(signal_is_gpio(GPIO_TEST), "Expected true");
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO set/get level.
+ *
+ * @details
+ * Validate set/get level
+ *
+ * Expected Results
+ * - Success
+ */
+ZTEST(gpio, test_gpio_get_set_level)
+{
+ enum gpio_signal signal = GPIO_TEST;
+ int level;
+
+ /* Test invalid signal */
+ gpio_set_level(GPIO_COUNT, 0);
+ zassert_equal(0, gpio_get_level(GPIO_COUNT), "Expected level==0");
+
+ /* Test valid signal */
+ gpio_set_level(signal, 0);
+ zassert_equal(0, gpio_get_level(signal), "Expected level==0");
+
+ gpio_set_level(signal, 1);
+ zassert_equal(1, gpio_get_level(signal), "Expected level==1");
+
+ level = gpio_get_ternary(signal);
+ zassert_equal(2, level, "Expected level==2, returned=%d", level);
+
+ gpio_set_level_verbose(CC_CHIPSET, signal, 0);
+ zassert_equal(0, gpio_get_level(signal), "Expected level==0");
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO get name.
+ *
+ * @details
+ * Validate gpio_get_name
+ *
+ * Expected Results
+ * - Success
+ */
+ZTEST(gpio, test_gpio_get_name)
+{
+ enum gpio_signal signal = GPIO_TEST;
+ const char *signal_name;
+
+ /* Test invalid signal */
+ signal_name = gpio_get_name(GPIO_COUNT);
+ zassert_mem_equal("UNIMPLEMENTED", signal_name, strlen(signal_name),
+ "gpio_get_name returned a valid signal \'%s\'",
+ signal_name);
+
+ /* Test valid signal */
+ signal_name = gpio_get_name(signal);
+ zassert_mem_equal("test", signal_name, strlen(signal_name),
+ "gpio_get_name returned signal \'%s\'", signal_name);
+}
+
+/**
+ * @brief Helper function to get GPIO flags
+ *
+ * @param signal
+ * @return gpio_flags_t
+ */
+gpio_flags_t gpio_helper_get_flags(enum gpio_signal signal)
+{
+ const struct gpio_dt_spec *spec;
+ gpio_flags_t flags;
+
+ spec = gpio_get_dt_spec(signal);
+ gpio_emul_flags_get(spec->port, spec->pin, &flags);
+
+ return flags;
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO get default flags.
+ *
+ * @details
+ * Validate gpio_get_default_flags
+ *
+ * Expected Results
+ * - Success
+ */
+ZTEST(gpio, test_gpio_get_default_flags)
+{
+ enum gpio_signal signal = GPIO_TEST;
+ gpio_flags_t flags;
+ gpio_flags_t flags_at_start[GPIO_COUNT];
+ int def_flags;
+
+ /* Snapshot of GPIO flags before testing */
+ for (int i = 0; i < GPIO_COUNT; i++)
+ flags_at_start[i] = gpio_helper_get_flags(i);
+
+ /* Test invalid signal */
+ def_flags = gpio_get_default_flags(GPIO_COUNT);
+ zassert_equal(0, def_flags, "Expected 0x0, returned 0x%08X", def_flags);
+ gpio_set_flags(GPIO_COUNT, GPIO_INPUT);
+
+ /* Verify flags didn't change */
+ for (int i = 0; i < GPIO_COUNT; i++) {
+ flags = gpio_helper_get_flags(i);
+ zassert_equal(flags_at_start[i], flags,
+ "%s[%d] flags_at_start=0x%x, flags=0x%x",
+ gpio_get_name(i), i, flags_at_start[i], flags);
+ }
+
+ /* Test valid signal */
+ def_flags = gpio_get_default_flags(signal);
+ zassert_equal(GPIO_INPUT | GPIO_OUTPUT, def_flags,
+ "Expected 0x%08x, returned 0x%08X",
+ GPIO_INPUT | GPIO_OUTPUT, def_flags);
+
+ gpio_set_flags(signal, GPIO_INPUT);
+ flags = gpio_helper_get_flags(signal);
+ zassert_equal(flags, GPIO_INPUT, "Flags set 0x%x", flags);
+
+ gpio_set_flags(signal, GPIO_OUTPUT);
+ flags = gpio_helper_get_flags(signal);
+ zassert_equal(flags, GPIO_OUTPUT, "Flags set 0x%x", flags);
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO reset.
+ *
+ * @details
+ * Validate gpio_reset
+ *
+ * Expected Results
+ * - Success
+ */
+ZTEST(gpio, test_gpio_reset)
+{
+ enum gpio_signal signal = GPIO_TEST;
+ gpio_flags_t flags;
+ gpio_flags_t flags_at_start[GPIO_COUNT];
+
+ /* Snapshot of GPIO flags before testing */
+ for (int i = 0; i < GPIO_COUNT; i++)
+ flags_at_start[i] = gpio_helper_get_flags(i);
+
+ /* Test reset on invalid signal */
+ gpio_reset(GPIO_COUNT);
+
+ /* Verify flags didn't change */
+ for (int i = 0; i < GPIO_COUNT; i++) {
+ flags = gpio_helper_get_flags(i);
+ zassert_equal(flags_at_start[i], flags,
+ "%s[%d] flags_at_start=0x%x, flags=0x%x",
+ gpio_get_name(i), i, flags_at_start[i], flags);
+ }
+
+ /* Test reset on valid signal */
+ gpio_set_flags(signal, GPIO_OUTPUT);
+ flags = gpio_helper_get_flags(signal);
+ zassert_equal(flags, GPIO_OUTPUT, "Flags set 0x%x", flags);
+
+ gpio_reset(signal);
+
+ flags = gpio_helper_get_flags(signal);
+ zassert_equal(flags, gpio_get_default_flags(signal), "Flags set 0x%x",
+ flags);
+}
+
+/**
+ * @brief TestPurpose: Verify GPIO enable/disable interrupt.
+ *
+ * @details
+ * Validate gpio_enable_interrupt
+ *
+ * Expected Results
+ * - Success
+ */
+extern bool gpio_test_interrupt_triggered;
+ZTEST(gpio, test_gpio_enable_interrupt)
+{
+ enum gpio_signal signal = GPIO_TEST;
+
+ gpio_test_interrupt_triggered = false;
+
+ /* Test invalid signal */
+ zassert_not_equal(EC_SUCCESS, gpio_disable_interrupt(GPIO_COUNT), NULL);
+ zassert_not_equal(EC_SUCCESS, gpio_enable_interrupt(GPIO_COUNT), NULL);
+ zassert_false(gpio_test_interrupt_triggered, NULL);
+
+ /* Test valid signal */
+ zassert_ok(gpio_disable_interrupt(signal), NULL);
+ gpio_set_level(signal, 0);
+ zassert_false(gpio_test_interrupt_triggered, NULL);
+ gpio_set_level(signal, 1);
+ zassert_false(gpio_test_interrupt_triggered, NULL);
+
+ zassert_ok(gpio_enable_interrupt(signal), NULL);
+ gpio_set_level(signal, 0);
+ zassert_true(gpio_test_interrupt_triggered, NULL);
+ gpio_test_interrupt_triggered = false;
+ gpio_set_level(signal, 1);
+ zassert_true(gpio_test_interrupt_triggered, NULL);
+}
+
+/**
+ * @brief GPIO test setup handler.
+ */
+static void gpio_before(void *state)
+{
+ ARG_UNUSED(state);
+ /** TODO: Reset all signals here. Currently other tests fail when reset
+ * for(int i = 0; i < GPIO_COUNT; i++) {
+ * gpio_reset(i);
+ * }
+ */
+ gpio_reset(GPIO_TEST);
+}
+
+/**
+ * @brief Test Suite: Verifies GPIO functionality.
+ */
+ZTEST_SUITE(gpio, drivers_predicate_post_main, NULL, gpio_before, NULL, NULL);
diff --git a/zephyr/test/drivers/src/stubs.c b/zephyr/test/drivers/src/stubs.c
index 2921f0ef97..85d7e99d13 100644
--- a/zephyr/test/drivers/src/stubs.c
+++ b/zephyr/test/drivers/src/stubs.c
@@ -401,3 +401,12 @@ void sys_arch_reboot(int type)
{
ARG_UNUSED(type);
}
+
+/* GPIO TEST interrupt handler */
+bool gpio_test_interrupt_triggered;
+void gpio_test_interrupt(enum gpio_signal signal)
+{
+ ARG_UNUSED(signal);
+ printk("%s called\n", __func__);
+ gpio_test_interrupt_triggered = true;
+}