1 /*
2  * Copyright (c) 2022 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/sys/util.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio/gpio_emul.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12 #include <zephyr/input/input.h>
13 
14 static const struct device *const test_gpio_keys_dev = DEVICE_DT_GET(DT_NODELABEL(buttons));
15 #define BUTTON_0_IDX DT_NODE_CHILD_IDX(DT_NODELABEL(voldown_button))
16 
17 struct gpio_keys_pin_config {
18 	/** GPIO specification from devicetree */
19 	struct gpio_dt_spec spec;
20 	/** Zephyr code from devicetree */
21 	uint32_t zephyr_code;
22 };
23 struct gpio_keys_config {
24 	/** Debounce interval in milliseconds from devicetree */
25 	uint32_t debounce_interval_ms;
26 	const int num_keys;
27 	const struct gpio_keys_pin_config *pin_cfg;
28 };
29 
30 /**
31  * @brief Test Suite: Verifies gpio_keys_config functionality.
32  */
33 ZTEST_SUITE(gpio_keys, NULL, NULL, NULL, NULL, NULL);
34 
35 static int event_count;
36 static uint16_t last_code;
37 static bool last_val;
test_gpio_keys_cb_handler(struct input_event * evt)38 static void test_gpio_keys_cb_handler(struct input_event *evt)
39 {
40 	TC_PRINT("GPIO_KEY %s pressed, zephyr_code=%u, value=%d\n",
41 		 evt->dev->name, evt->code, evt->value);
42 	event_count++;
43 	last_code = evt->code;
44 	last_val = evt->value;
45 }
46 INPUT_CALLBACK_DEFINE(test_gpio_keys_dev, test_gpio_keys_cb_handler);
47 
48 /**
49  * @brief TestPurpose: Verify gpio_keys_config pressed raw.
50  *
51  */
ZTEST(gpio_keys,test_gpio_keys_pressed)52 ZTEST(gpio_keys, test_gpio_keys_pressed)
53 {
54 	const struct gpio_keys_config *config = test_gpio_keys_dev->config;
55 	const struct gpio_keys_pin_config *pin_cfg = &config->pin_cfg[BUTTON_0_IDX];
56 	const struct gpio_dt_spec *spec = &pin_cfg->spec;
57 
58 	last_code = 0;
59 	last_val = false;
60 
61 	zassert_ok(gpio_emul_input_set(spec->port, spec->pin, 0));
62 
63 	/* Check interrupt doesn't prematurely fires */
64 	k_sleep(K_MSEC(config->debounce_interval_ms / 2));
65 	zassert_equal(event_count, 0);
66 
67 	/* Check interrupt fires after debounce interval */
68 	k_sleep(K_MSEC(config->debounce_interval_ms));
69 	zassert_equal(event_count, 1);
70 	zassert_equal(last_code, pin_cfg->zephyr_code);
71 	zassert_equal(last_val, true);
72 
73 	zassert_ok(gpio_emul_input_set(spec->port, spec->pin, 1));
74 
75 	/* Check interrupt doesn't prematurely fires */
76 	k_sleep(K_MSEC(config->debounce_interval_ms / 2));
77 	zassert_equal(event_count, 1);
78 
79 	/* Check interrupt fires after debounce interval */
80 	k_sleep(K_MSEC(config->debounce_interval_ms));
81 	zassert_equal(event_count, 2);
82 	zassert_equal(last_code, pin_cfg->zephyr_code);
83 	zassert_equal(last_val, false);
84 }
85