Commit eeb6bf7d authored by Juliane Schulze's avatar Juliane Schulze Committed by Fabio Baltieri
Browse files

input: make short-inputs optional



By making short inputs optional, the user can bypass short-events all
together if necessary (e.g. custom button-press listener).

Signed-off-by: default avatarJuliane Schulze <juliane.schulze@deveritec.com>
parent c3a54ae1
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -8,7 +8,9 @@ description: |
  corresponding to short and long press.

  Can be optionally be associated to a specific device to listen for events
  only from that device. Example configuration:
  only from that device.

  Example configuration:

  #include <zephyr/dt-bindings/input/input-event-codes.h>

@@ -23,12 +25,14 @@ description: |

  Example output:

  # short press
  input event: dev=buttons          SYN type= 1 code= 11 value=1 # INPUT_KEY_0 press
  # release before one second
  input event: dev=buttons          SYN type= 1 code= 11 value=0 # INPUT_KEY_0 release
  input event: dev=longpress        SYN type= 1 code= 30 value=1 # INPUT_KEY_A press
  input event: dev=longpress        SYN type= 1 code= 30 value=0 # INPUT_KEY_A release

  # long press
  input event: dev=buttons          SYN type= 1 code= 11 value=1 # INPUT_KEY_0 press
  # hold for more than one second
  input event: dev=longpress        SYN type= 1 code= 45 value=1 # INPUT_KEY_X press
@@ -52,9 +56,8 @@ properties:

  short-codes:
    type: array
    required: true
    description: |
      Array of key codes to be generated for short press (INPUT_KEY_* or
      Optional array of key codes to be generated for short press (INPUT_KEY_* or
      INPUT_BTN_*).

  long-codes:
+8 −3
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static void longpress_cb(const struct device *dev, struct input_event *evt)
		k_work_cancel_delayable(&entry->work);
		if (entry->long_fired) {
			input_report_key(dev, cfg->long_codes[i], 0, true, K_FOREVER);
		} else {
		} else if (cfg->short_codes != NULL) {
			input_report_key(dev, cfg->short_codes[i], 1, true, K_FOREVER);
			input_report_key(dev, cfg->short_codes[i], 0, true, K_FOREVER);
		}
@@ -109,8 +109,9 @@ static int longpress_init(const struct device *dev)
}

#define INPUT_LONGPRESS_DEFINE(inst)                                                               \
	BUILD_ASSERT(DT_INST_PROP_LEN(inst, input_codes) ==                                        \
		     DT_INST_PROP_LEN(inst, short_codes));                                         \
	BUILD_ASSERT((DT_INST_PROP_LEN(inst, input_codes) ==                                       \
		      DT_INST_PROP_LEN_OR(inst, short_codes, 0)) ||                                \
		     !DT_INST_NODE_HAS_PROP(inst, short_codes));                                   \
	BUILD_ASSERT(DT_INST_PROP_LEN(inst, input_codes) ==                                        \
		     DT_INST_PROP_LEN(inst, long_codes));                                          \
	static void longpress_cb_##inst(struct input_event *evt)                                   \
@@ -120,12 +121,16 @@ static int longpress_init(const struct device *dev)
	INPUT_CALLBACK_DEFINE(DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, input)),                 \
			      longpress_cb_##inst);                                                \
	static const uint16_t longpress_input_codes_##inst[] = DT_INST_PROP(inst, input_codes);    \
	IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, short_codes), (                                     \
	static const uint16_t longpress_short_codes_##inst[] = DT_INST_PROP(inst, short_codes);    \
	));                                                                                        \
	static const uint16_t longpress_long_codes_##inst[] = DT_INST_PROP(inst, long_codes);      \
	static const struct longpress_config longpress_config_##inst = {                           \
		.input_dev = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, input)),                  \
		.input_codes = longpress_input_codes_##inst,                                       \
		IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, short_codes), (                             \
		.short_codes = longpress_short_codes_##inst,                                       \
		))                                                                                 \
		.long_codes = longpress_long_codes_##inst,                                         \
		.num_codes = DT_INST_PROP_LEN(inst, input_codes),                                  \
		.long_delays_ms = DT_INST_PROP(inst, long_delay_ms),                               \
+8 −0
Original line number Diff line number Diff line
@@ -19,4 +19,12 @@
		long-codes = <INPUT_KEY_X>, <INPUT_KEY_Y>;
		long-delay-ms = <100>;
        };

	longpress_no_short: longpress-no-short {
		input = <&fake_input_device>;
		compatible = "zephyr,input-longpress";
		input-codes = <INPUT_KEY_0>, <INPUT_KEY_1>;
		long-codes = <INPUT_KEY_X>, <INPUT_KEY_Y>;
		long-delay-ms = <100>;
	};
};
+34 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ static const struct device *const fake_dev = DEVICE_DT_GET(
		DT_NODELABEL(fake_input_device));
static const struct device *const longpress_dev = DEVICE_DT_GET(
		DT_NODELABEL(longpress));
static const struct device *const longpress_no_short_dev = DEVICE_DT_GET(
		DT_NODELABEL(longpress_no_short));

DEVICE_DT_DEFINE(DT_INST(0, vnd_input_device), NULL, NULL, NULL, NULL,
		 PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
@@ -30,6 +32,18 @@ static void test_cb(struct input_event *evt)
}
INPUT_CALLBACK_DEFINE(longpress_dev, test_cb);

static int event_count_no_short;
static struct input_event last_events_no_short[2];
static void test_cb_no_short(struct input_event *evt)
{
	TC_PRINT("%s: %d %x %d\n", __func__, event_count_no_short, evt->code, evt->value);

	event_count_no_short++;
	memcpy(&last_events_no_short[1], &last_events_no_short[0], sizeof(struct input_event));
	memcpy(&last_events_no_short[0], evt, sizeof(struct input_event));
}
INPUT_CALLBACK_DEFINE(longpress_no_short_dev, test_cb_no_short);

ZTEST(longpress, test_longpress_test)
{
	zassert_equal(event_count, 0);
@@ -38,9 +52,11 @@ ZTEST(longpress, test_longpress_test)
	input_report_key(fake_dev, INPUT_KEY_3, 1, true, K_FOREVER);
	input_report_key(fake_dev, INPUT_KEY_3, 0, true, K_FOREVER);
	zassert_equal(event_count, 0);
	zassert_equal(event_count_no_short, 0);
	input_report_abs(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
	input_report_abs(fake_dev, INPUT_KEY_0, 0, true, K_FOREVER);
	zassert_equal(event_count, 0);
	zassert_equal(event_count_no_short, 0);

	/* short press */
	input_report_key(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
@@ -53,6 +69,7 @@ ZTEST(longpress, test_longpress_test)
	zassert_equal(last_events[0].type, INPUT_EV_KEY);
	zassert_equal(last_events[0].code, INPUT_KEY_A);
	zassert_equal(last_events[0].value, 0);
	zassert_equal(event_count_no_short, 0);

	/* short press - other key */
	input_report_key(fake_dev, INPUT_KEY_1, 1, true, K_FOREVER);
@@ -65,6 +82,7 @@ ZTEST(longpress, test_longpress_test)
	zassert_equal(last_events[0].type, INPUT_EV_KEY);
	zassert_equal(last_events[0].code, INPUT_KEY_B);
	zassert_equal(last_events[0].value, 0);
	zassert_equal(event_count_no_short, 0);

	/* long press */
	input_report_key(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
@@ -78,6 +96,14 @@ ZTEST(longpress, test_longpress_test)
	zassert_equal(last_events[0].code, INPUT_KEY_X);
	zassert_equal(last_events[0].value, 0);

	zassert_equal(event_count_no_short, 2);
	zassert_equal(last_events_no_short[1].type, INPUT_EV_KEY);
	zassert_equal(last_events_no_short[1].code, INPUT_KEY_X);
	zassert_equal(last_events_no_short[1].value, 1);
	zassert_equal(last_events_no_short[0].type, INPUT_EV_KEY);
	zassert_equal(last_events_no_short[0].code, INPUT_KEY_X);
	zassert_equal(last_events_no_short[0].value, 0);

	/* long press - other key */
	input_report_key(fake_dev, INPUT_KEY_1, 1, true, K_FOREVER);
	k_sleep(K_MSEC(150));
@@ -89,6 +115,14 @@ ZTEST(longpress, test_longpress_test)
	zassert_equal(last_events[0].type, INPUT_EV_KEY);
	zassert_equal(last_events[0].code, INPUT_KEY_Y);
	zassert_equal(last_events[0].value, 0);

	zassert_equal(event_count_no_short, 4);
	zassert_equal(last_events_no_short[1].type, INPUT_EV_KEY);
	zassert_equal(last_events_no_short[1].code, INPUT_KEY_Y);
	zassert_equal(last_events_no_short[1].value, 1);
	zassert_equal(last_events_no_short[0].type, INPUT_EV_KEY);
	zassert_equal(last_events_no_short[0].code, INPUT_KEY_Y);
	zassert_equal(last_events_no_short[0].value, 0);
}

ZTEST_SUITE(longpress, NULL, NULL, NULL, NULL, NULL);