diff mbox

[2/3] input: handle case whether first repeated key triggers repeat

Message ID e00a5bd5e87f011c92f7af5aac7e1654bf455cfb.1511523174.git.sean@mess.org (mailing list archive)
State New, archived
Headers show

Commit Message

Sean Young Nov. 24, 2017, 11:44 a.m. UTC
In the CEC protocol, as soon as the first repeated key is received,
the autorepeat should start. We introduce a special value 3 for this
situation.

Signed-off-by: Sean Young <sean@mess.org>
---
 Documentation/input/input.rst |  4 +++-
 drivers/input/input.c         | 17 +++++++++++++++--
 2 files changed, 18 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/Documentation/input/input.rst b/Documentation/input/input.rst
index 47f86a4bf16c..31cea9026193 100644
--- a/Documentation/input/input.rst
+++ b/Documentation/input/input.rst
@@ -276,6 +276,8 @@  list is in include/uapi/linux/input-event-codes.h.
 
 ``value`` is the value the event carries. Either a relative change for
 EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
-release, 1 for keypress and 2 for autorepeat.
+release, 1 for keypress and 2 for autorepeat, and 3 for autorepeat where
+the repeats should start immediately, rather than waiting REP_DELAY
+milliseconds.
 
 See :ref:`input-event-codes` for more information about various even codes.
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ecc41d65b82a..84182d7e5a6b 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -72,6 +72,16 @@  static int input_defuzz_abs_event(int value, int old_val, int fuzz)
 	return value;
 }
 
+static void input_start_autorepeat_now(struct input_dev *dev, int code)
+{
+	if (dev->rep[REP_PERIOD] && dev->timer.data &&
+	    !timer_pending(&dev->timer)) {
+		dev->repeat_key = code;
+		mod_timer(&dev->timer,
+			  jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD]));
+	}
+}
+
 static void input_start_autorepeat(struct input_dev *dev, int code)
 {
 	if (dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && dev->timer.data) {
@@ -155,7 +165,10 @@  static void input_pass_values(struct input_dev *dev,
 	if (test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit)) {
 		for (v = vals; v != vals + count; v++) {
 			if (v->type == EV_KEY && v->value != 2) {
-				if (v->value)
+				if (v->value == 3)
+					input_start_autorepeat_now(dev,
+								   v->code);
+				else if (v->value)
 					input_start_autorepeat(dev, v->code);
 				else
 					input_stop_autorepeat(dev);
@@ -285,7 +298,7 @@  static int input_get_disposition(struct input_dev *dev,
 		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
 
 			/* auto-repeat bypasses state updates */
-			if (value == 2) {
+			if (value == 2 || value == 3) {
 				disposition = INPUT_PASS_TO_HANDLERS;
 				break;
 			}