1 /*
2  * Copyright 2023 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/gpio/gpio_emul.h>
9 #include <zephyr/input/input.h>
10 #include <zephyr/input/input_kbd_matrix.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/ztest.h>
13 
14 #define INTERRUPT_NODE DT_NODELABEL(kbd_matrix_interrupt)
15 #define POLL_NODE DT_NODELABEL(kbd_matrix_poll)
16 #define SCAN_NODE DT_NODELABEL(kbd_matrix_scan)
17 
18 static const struct device *dev_interrupt = DEVICE_DT_GET_OR_NULL(INTERRUPT_NODE);
19 static const struct device *dev_poll = DEVICE_DT_GET_OR_NULL(POLL_NODE);
20 static const struct device *dev_scan = DEVICE_DT_GET_OR_NULL(SCAN_NODE);
21 
22 #define INTERRUPT_R0_PIN DT_GPIO_PIN_BY_IDX(INTERRUPT_NODE, row_gpios, 0)
23 #define INTERRUPT_R1_PIN DT_GPIO_PIN_BY_IDX(INTERRUPT_NODE, row_gpios, 1)
24 #define INTERRUPT_C0_PIN DT_GPIO_PIN_BY_IDX(INTERRUPT_NODE, col_gpios, 0)
25 #define INTERRUPT_C1_PIN DT_GPIO_PIN_BY_IDX(INTERRUPT_NODE, col_gpios, 1)
26 
27 #define POLL_R0_PIN DT_GPIO_PIN_BY_IDX(POLL_NODE, row_gpios, 0)
28 #define POLL_R1_PIN DT_GPIO_PIN_BY_IDX(POLL_NODE, row_gpios, 1)
29 #define POLL_C0_PIN DT_GPIO_PIN_BY_IDX(POLL_NODE, col_gpios, 0)
30 #define POLL_C1_PIN DT_GPIO_PIN_BY_IDX(POLL_NODE, col_gpios, 1)
31 
32 #define SCAN_R0_PIN DT_GPIO_PIN_BY_IDX(SCAN_NODE, row_gpios, 0)
33 #define SCAN_R1_PIN DT_GPIO_PIN_BY_IDX(SCAN_NODE, row_gpios, 1)
34 #define SCAN_C0_PIN DT_GPIO_PIN_BY_IDX(SCAN_NODE, col_gpios, 0)
35 #define SCAN_C1_PIN DT_GPIO_PIN_BY_IDX(SCAN_NODE, col_gpios, 1)
36 
37 static const struct device *dev_gpio = DEVICE_DT_GET(DT_NODELABEL(gpio0));
38 
39 enum {
40 	KBD_DEV_INTERRUPT,
41 	KBD_DEV_POLL,
42 	KBD_DEV_SCAN,
43 };
44 
45 #define KBD_DEV_COUNT (KBD_DEV_SCAN + 1)
46 
47 #define COL_COUNT 2
48 
49 BUILD_ASSERT(DT_PROP_LEN(INTERRUPT_NODE, col_gpios) == COL_COUNT);
50 BUILD_ASSERT(DT_PROP_LEN(POLL_NODE, col_gpios) == COL_COUNT);
51 BUILD_ASSERT(DT_PROP_LEN(SCAN_NODE, col_gpios) == COL_COUNT);
52 
53 static uint8_t test_rows[KBD_DEV_COUNT][COL_COUNT];
54 static int scan_set_count[KBD_DEV_COUNT];
55 
gpio_kbd_scan_set_row(const struct device * dev,uint8_t row)56 static void gpio_kbd_scan_set_row(const struct device *dev, uint8_t row)
57 {
58 	if (dev == dev_interrupt) {
59 		gpio_emul_input_set(dev_gpio, INTERRUPT_R0_PIN, !(row & BIT(0)));
60 		gpio_emul_input_set(dev_gpio, INTERRUPT_R1_PIN, !(row & BIT(1)));
61 		return;
62 	} else if (dev == dev_poll) {
63 		gpio_emul_input_set(dev_gpio, POLL_R0_PIN, !(row & BIT(0)));
64 		gpio_emul_input_set(dev_gpio, POLL_R1_PIN, !(row & BIT(1)));
65 		return;
66 	} else if (dev == dev_scan) {
67 		gpio_emul_input_set(dev_gpio, SCAN_R0_PIN, !(row & BIT(0)));
68 		gpio_emul_input_set(dev_gpio, SCAN_R1_PIN, !(row & BIT(1)));
69 		return;
70 	}
71 
72 	TC_PRINT("unknown device: %s\n", dev->name);
73 }
74 
input_kbd_matrix_drive_column_hook(const struct device * dev,int col)75 void input_kbd_matrix_drive_column_hook(const struct device *dev, int col)
76 {
77 	gpio_flags_t flags0, flags1;
78 
79 	if (col >= COL_COUNT) {
80 		TC_PRINT("invalid column: %d\n", col);
81 		return;
82 	}
83 
84 	if (dev == dev_interrupt) {
85 		scan_set_count[KBD_DEV_INTERRUPT]++;
86 		gpio_kbd_scan_set_row(dev, test_rows[KBD_DEV_INTERRUPT][col]);
87 
88 		/* Verify that columns are NOT driven. */
89 		gpio_emul_flags_get(dev_gpio, INTERRUPT_C0_PIN, &flags0);
90 		gpio_emul_flags_get(dev_gpio, INTERRUPT_C1_PIN, &flags1);
91 		switch (col) {
92 		case 0:
93 			zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_OUTPUT);
94 			zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_INPUT);
95 			break;
96 		case 1:
97 			zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_INPUT);
98 			zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_OUTPUT);
99 			break;
100 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE:
101 			zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_INPUT);
102 			zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_INPUT);
103 			break;
104 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL:
105 			zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_OUTPUT);
106 			zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_OUTPUT);
107 			break;
108 		}
109 
110 		return;
111 	} else if (dev == dev_poll) {
112 		scan_set_count[KBD_DEV_POLL]++;
113 		gpio_kbd_scan_set_row(dev, test_rows[KBD_DEV_POLL][col]);
114 
115 		/* Verify that columns are always driven */
116 		gpio_emul_flags_get(dev_gpio, POLL_C0_PIN, &flags0);
117 		gpio_emul_flags_get(dev_gpio, POLL_C1_PIN, &flags1);
118 		zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_OUTPUT);
119 		zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_OUTPUT);
120 
121 		switch (col) {
122 		case 0:
123 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C0_PIN), 0);
124 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C1_PIN), 1);
125 			break;
126 		case 1:
127 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C0_PIN), 1);
128 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C1_PIN), 0);
129 			break;
130 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE:
131 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C0_PIN), 1);
132 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C1_PIN), 1);
133 			break;
134 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL:
135 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C0_PIN), 0);
136 			zassert_equal(gpio_emul_output_get(dev_gpio, POLL_C1_PIN), 0);
137 			break;
138 		}
139 
140 		return;
141 	} else if (dev == dev_scan) {
142 		scan_set_count[KBD_DEV_SCAN]++;
143 		gpio_kbd_scan_set_row(dev, test_rows[KBD_DEV_SCAN][col]);
144 
145 		/* Verify that columns are always driven */
146 		gpio_emul_flags_get(dev_gpio, SCAN_C0_PIN, &flags0);
147 		gpio_emul_flags_get(dev_gpio, SCAN_C1_PIN, &flags1);
148 		zassert_equal(flags0 & GPIO_DIR_MASK, GPIO_OUTPUT);
149 		zassert_equal(flags1 & GPIO_DIR_MASK, GPIO_OUTPUT);
150 
151 		switch (col) {
152 		case 0:
153 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C0_PIN), 0);
154 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C1_PIN), 1);
155 			break;
156 		case 1:
157 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C0_PIN), 1);
158 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C1_PIN), 0);
159 			break;
160 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE:
161 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C0_PIN), 1);
162 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C1_PIN), 1);
163 			break;
164 		case INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL:
165 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C0_PIN), 0);
166 			zassert_equal(gpio_emul_output_get(dev_gpio, SCAN_C1_PIN), 0);
167 			break;
168 		}
169 
170 		return;
171 	}
172 
173 	TC_PRINT("unknown device: %s\n", dev->name);
174 }
175 
176 /* support stuff */
177 
178 static struct {
179 	int row;
180 	int col;
181 	int val;
182 	int event_count;
183 } test_event_data;
184 
185 static int last_checked_event_count;
186 
187 #define assert_no_new_events() \
188 	zassert_equal(last_checked_event_count, test_event_data.event_count);
189 
190 #define  assert_new_event(_row, _col, _val) { \
191 	last_checked_event_count++; \
192 	zassert_equal(last_checked_event_count, test_event_data.event_count); \
193 	zassert_equal(_row, test_event_data.row); \
194 	zassert_equal(_col, test_event_data.col); \
195 	zassert_equal(_val, test_event_data.val); \
196 }
197 
test_cb(struct input_event * evt,void * user_data)198 static void test_cb(struct input_event *evt, void *user_data)
199 {
200 	static int row, col, val;
201 
202 	switch (evt->code) {
203 	case INPUT_ABS_X:
204 		col = evt->value;
205 		break;
206 	case INPUT_ABS_Y:
207 		row = evt->value;
208 		break;
209 	case INPUT_BTN_TOUCH:
210 		val = evt->value;
211 		break;
212 	}
213 
214 	if (evt->sync) {
215 		test_event_data.row = row;
216 		test_event_data.col = col;
217 		test_event_data.val = val;
218 		test_event_data.event_count++;
219 		TC_PRINT("input event: count=%d row=%d col=%d val=%d\n",
220 			 test_event_data.event_count, row, col, val);
221 	}
222 }
223 INPUT_CALLBACK_DEFINE(NULL, test_cb, NULL);
224 
225 /* actual tests */
226 
ZTEST(gpio_kbd_scan,test_gpio_kbd_scan_interrupt)227 ZTEST(gpio_kbd_scan, test_gpio_kbd_scan_interrupt)
228 {
229 	const struct device *dev = dev_interrupt;
230 
231 	if (dev == NULL) {
232 		ztest_test_skip();
233 		return;
234 	}
235 
236 	const struct input_kbd_matrix_common_config *cfg = dev->config;
237 	uint8_t *rows = test_rows[KBD_DEV_INTERRUPT];
238 	int *set_count = &scan_set_count[KBD_DEV_INTERRUPT];
239 	int prev_count;
240 	gpio_flags_t flags;
241 
242 	k_sleep(K_SECONDS(1));
243 	assert_no_new_events();
244 	zassert_equal(*set_count, 1);
245 
246 	/* Verify that interrupts are enabled. */
247 	gpio_emul_flags_get(dev_gpio, INTERRUPT_R0_PIN, &flags);
248 	zassert_equal(flags & GPIO_INT_ENABLE, GPIO_INT_ENABLE);
249 	gpio_emul_flags_get(dev_gpio, INTERRUPT_R1_PIN, &flags);
250 	zassert_equal(flags & GPIO_INT_ENABLE, GPIO_INT_ENABLE);
251 
252 	rows[0] = BIT(0);
253 	gpio_kbd_scan_set_row(dev, 0x01);
254 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
255 	assert_new_event(0, 0, 1);
256 
257 	rows[1] = BIT(1);
258 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
259 	assert_new_event(1, 1, 1);
260 
261 	rows[0] = 0x00;
262 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
263 	assert_new_event(0, 0, 0);
264 
265 	rows[1] = 0x00;
266 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
267 	assert_new_event(1, 1, 0);
268 
269 	k_sleep(K_MSEC(cfg->poll_timeout_ms * 1.5));
270 
271 	/* Check that scanning is NOT running */
272 	prev_count = *set_count;
273 	k_sleep(K_MSEC(cfg->poll_timeout_ms * 10));
274 	assert_no_new_events();
275 	TC_PRINT("scan_set_count=%d, prev_count=%d\n", *set_count, prev_count);
276 	zassert_equal(*set_count, prev_count);
277 
278 	/* Verify that interrupts are still enabled. */
279 	gpio_emul_flags_get(dev_gpio, INTERRUPT_R0_PIN, &flags);
280 	zassert_equal(flags & GPIO_INT_ENABLE, GPIO_INT_ENABLE);
281 	gpio_emul_flags_get(dev_gpio, INTERRUPT_R1_PIN, &flags);
282 	zassert_equal(flags & GPIO_INT_ENABLE, GPIO_INT_ENABLE);
283 }
284 
ZTEST(gpio_kbd_scan,test_gpio_kbd_scan_poll)285 ZTEST(gpio_kbd_scan, test_gpio_kbd_scan_poll)
286 {
287 	const struct device *dev = dev_poll;
288 
289 	if (dev == NULL) {
290 		ztest_test_skip();
291 		return;
292 	}
293 
294 	const struct input_kbd_matrix_common_config *cfg = dev->config;
295 	uint8_t *rows = test_rows[KBD_DEV_POLL];
296 	int *set_count = &scan_set_count[KBD_DEV_POLL];
297 	int prev_count;
298 	gpio_flags_t flags;
299 
300 	k_sleep(K_SECONDS(1));
301 	assert_no_new_events();
302 	zassert_equal(*set_count, 0);
303 
304 	/* Verify that interrupts are NOT enabled. */
305 	gpio_emul_flags_get(dev_gpio, POLL_R0_PIN, &flags);
306 	zassert_equal(flags & GPIO_INT_MASK, 0);
307 	gpio_emul_flags_get(dev_gpio, POLL_R1_PIN, &flags);
308 	zassert_equal(flags & GPIO_INT_MASK, 0);
309 
310 	rows[0] = BIT(0);
311 	gpio_kbd_scan_set_row(dev, 0x01);
312 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
313 	assert_new_event(0, 0, 1);
314 
315 	rows[1] = BIT(1);
316 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
317 	assert_new_event(1, 1, 1);
318 
319 	rows[0] = 0x00;
320 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
321 	assert_new_event(0, 0, 0);
322 
323 	rows[1] = 0x00;
324 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
325 	assert_new_event(1, 1, 0);
326 
327 	k_sleep(K_MSEC(cfg->poll_timeout_ms * 1.5));
328 
329 	/* Check that scanning is NOT running */
330 	prev_count = *set_count;
331 	k_sleep(K_MSEC(cfg->poll_timeout_ms * 10));
332 	assert_no_new_events();
333 	TC_PRINT("scan_set_count=%d, prev_count=%d\n", *set_count, prev_count);
334 	zassert_equal(*set_count, prev_count);
335 
336 	/* Verify that interrupts are still NOT enabled. */
337 	gpio_emul_flags_get(dev_gpio, POLL_R0_PIN, &flags);
338 	zassert_equal(flags & GPIO_INT_MASK, 0);
339 	gpio_emul_flags_get(dev_gpio, POLL_R1_PIN, &flags);
340 	zassert_equal(flags & GPIO_INT_MASK, 0);
341 }
342 
ZTEST(gpio_kbd_scan,test_gpio_kbd_scan_scan)343 ZTEST(gpio_kbd_scan, test_gpio_kbd_scan_scan)
344 {
345 	const struct device *dev = dev_scan;
346 
347 	if (dev == NULL) {
348 		ztest_test_skip();
349 		return;
350 	}
351 
352 	const struct input_kbd_matrix_common_config *cfg = dev->config;
353 	uint8_t *rows = test_rows[KBD_DEV_SCAN];
354 	int *set_count = &scan_set_count[KBD_DEV_SCAN];
355 	int prev_count;
356 	int delta_count;
357 	gpio_flags_t flags;
358 
359 	/* check that scanning is already running */
360 	prev_count = *set_count;
361 	k_sleep(K_SECONDS(1));
362 	assert_no_new_events();
363 	delta_count = *set_count - prev_count;
364 	TC_PRINT("scan_set_count=%d, delta=%d\n", *set_count, delta_count);
365 	zassert_true(delta_count > 100);
366 
367 	/* Verify that interrupts are NOT enabled. */
368 	gpio_emul_flags_get(dev_gpio, SCAN_R0_PIN, &flags);
369 	zassert_equal(flags & GPIO_INT_MASK, 0);
370 	gpio_emul_flags_get(dev_gpio, SCAN_R1_PIN, &flags);
371 	zassert_equal(flags & GPIO_INT_MASK, 0);
372 
373 	rows[0] = BIT(0);
374 	gpio_kbd_scan_set_row(dev, 0x01);
375 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
376 	assert_new_event(0, 0, 1);
377 
378 	rows[1] = BIT(1);
379 	k_sleep(K_USEC(cfg->debounce_down_us * 1.5));
380 	assert_new_event(1, 1, 1);
381 
382 	rows[0] = 0x00;
383 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
384 	assert_new_event(0, 0, 0);
385 
386 	rows[1] = 0x00;
387 	k_sleep(K_USEC(cfg->debounce_up_us * 1.5));
388 	assert_new_event(1, 1, 0);
389 
390 	k_sleep(K_MSEC(cfg->poll_timeout_ms * 1.5));
391 
392 	/* Check that scanning is still running */
393 	prev_count = *set_count;
394 	k_sleep(K_SECONDS(1));
395 	assert_no_new_events();
396 	delta_count = *set_count - prev_count;
397 	TC_PRINT("scan_set_count=%d, delta=%d\n", *set_count, delta_count);
398 	zassert_true(delta_count > 100);
399 
400 	/* Verify that interrupts are still NOT enabled. */
401 	gpio_emul_flags_get(dev_gpio, SCAN_R0_PIN, &flags);
402 	zassert_equal(flags & GPIO_INT_MASK, 0);
403 	gpio_emul_flags_get(dev_gpio, SCAN_R1_PIN, &flags);
404 	zassert_equal(flags & GPIO_INT_MASK, 0);
405 }
406 
gpio_kbd_scan_before(void * data)407 static void gpio_kbd_scan_before(void *data)
408 {
409 	last_checked_event_count = 0;
410 	memset(&test_event_data, 0, sizeof(test_event_data));
411 	memset(&scan_set_count, 0, sizeof(scan_set_count));
412 }
413 
414 ZTEST_SUITE(gpio_kbd_scan, NULL, NULL, gpio_kbd_scan_before, NULL, NULL);
415