mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Daniel Golle <daniel@makrotopia.org>
To: "Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Daniel Golle" <daniel@makrotopia.org>,
	"Uwe Kleine-König" <u.kleine-koenig@baylibre.com>,
	"Oleh Kuzhylnyi" <kuzhylol@gmail.com>,
	linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v4 3/5] Input: hynitron-cst816x: release gesture keys
Date: Mon, 5 Oct 2026 22:11:45 +0100	[thread overview]
Message-ID: <5312d67200e3251b2be08aef0a726d50d94fadde.1791233147.git.daniel@makrotopia.org> (raw)
In-Reply-To: <cover.1791233147.git.daniel@makrotopia.org>

The gesture key is reported with the value of the touch flag, so it
stays pressed once the controller stops reporting the gesture code
while the finger is still down. Report the press on its own and
release the keys the input core still holds down on the first report
that carries no gesture code. Report a key only for the gesture codes
the binding names: the controller also sends codes such as single
click, and the index fallback aliased those onto the long-press
keycode. Keycodes above KEY_MAX are rejected, as that release looks
the key state up in the input core's key bitmap.

Fixes: c87a819bec86 ("Input: add driver for Hynitron CST816x series")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v4:
- map only the documented gesture codes to keys, as single click
  aliased onto the long-press keycode (Oleh Kuzhylnyi)
- read each keycode once in the release loop, so the key it tests is
  the key it releases (Sashiko AI review)
v2:
- reject keycodes above KEY_MAX and publish keycodemax only once the
  whole array validates (Sashiko AI review)

 drivers/input/touchscreen/hynitron-cst816x.c | 87 +++++++++++++-------
 1 file changed, 55 insertions(+), 32 deletions(-)

diff --git a/drivers/input/touchscreen/hynitron-cst816x.c b/drivers/input/touchscreen/hynitron-cst816x.c
index 865c5a767ba01..2d8f0b78a3a8a 100644
--- a/drivers/input/touchscreen/hynitron-cst816x.c
+++ b/drivers/input/touchscreen/hynitron-cst816x.c
@@ -39,28 +39,40 @@ static int cst816x_parse_keycodes(struct device *dev, struct cst816x_priv *priv)
 {
 	int count;
 	int error;
+	int i;
 
-	if (device_property_present(dev, "linux,keycodes")) {
-		count = device_property_count_u32(dev, "linux,keycodes");
-		if (count < 0) {
-			error = count;
-			dev_err(dev, "failed to count keys: %d\n", error);
-			return error;
-		} else if (count > ARRAY_SIZE(priv->keycode)) {
-			dev_err(dev, "too many keys defined: %d\n", count);
-			return -EINVAL;
-		}
-		priv->keycodemax = count;
-
-		error = device_property_read_u32_array(dev, "linux,keycodes",
-						       priv->keycode,
-						       priv->keycodemax);
-		if (error) {
-			dev_err(dev, "failed to read keycodes: %d\n", error);
-			return error;
-		}
+	if (!device_property_present(dev, "linux,keycodes"))
+		return 0;
+
+	count = device_property_count_u32(dev, "linux,keycodes");
+	if (count < 0) {
+		error = count;
+		dev_err(dev, "failed to count keys: %d\n", error);
+		return error;
+	}
+
+	if (count > ARRAY_SIZE(priv->keycode)) {
+		dev_err(dev, "too many keys defined: %d\n", count);
+		return -EINVAL;
+	}
+
+	error = device_property_read_u32_array(dev, "linux,keycodes",
+					       priv->keycode, count);
+	if (error) {
+		dev_err(dev, "failed to read keycodes: %d\n", error);
+		return error;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (priv->keycode[i] <= KEY_MAX)
+			continue;
+
+		dev_err(dev, "keycode %u out of range\n", priv->keycode[i]);
+		return -EINVAL;
 	}
 
+	priv->keycodemax = count;
+
 	return 0;
 }
 
@@ -94,24 +106,19 @@ static int cst816x_i2c_read_register(struct cst816x_priv *priv, u8 reg,
 	return 0;
 }
 
-static u8 cst816x_gest_idx(u8 gest)
+static unsigned int cst816x_gest_keycode(struct cst816x_priv *priv, u8 gest)
 {
-	u8 index;
-
 	switch (gest) {
 	case 0x01: /* Slide up gesture */
 	case 0x02: /* Slide down gesture */
 	case 0x03: /* Slide left gesture */
 	case 0x04: /* Slide right gesture */
-		index = gest;
-		break;
+		return priv->keycode[gest - 1];
 	case 0x0c: /* Long press gesture */
+		return priv->keycode[CST816X_NUM_KEYS - 1];
 	default:
-		index = CST816X_NUM_KEYS;
-		break;
+		return KEY_RESERVED;
 	}
-
-	return index - 1;
 }
 
 static bool cst816x_process_touch(struct cst816x_priv *priv,
@@ -168,10 +175,25 @@ static void cst816x_reset(struct cst816x_priv *priv)
 	msleep(100);
 }
 
+static void cst816x_release_keys(struct cst816x_priv *priv)
+{
+	unsigned int key;
+	unsigned int i;
+
+	for (i = 0; i < priv->keycodemax; i++) {
+		key = priv->keycode[i];
+		if (!test_bit(key, priv->input->key))
+			continue;
+
+		input_report_key(priv->input, key, 0);
+	}
+}
+
 static irqreturn_t cst816x_irq_cb(int irq, void *cookie)
 {
 	struct cst816x_priv *priv = cookie;
 	struct cst816x_touch tch;
+	unsigned int key;
 
 	if (!cst816x_process_touch(priv, &tch))
 		return IRQ_HANDLED;
@@ -179,10 +201,11 @@ static irqreturn_t cst816x_irq_cb(int irq, void *cookie)
 	touchscreen_report_pos(priv->input, &priv->prop,
 			       tch.abs_x, tch.abs_y, false);
 
-	if (tch.gest)
-		input_report_key(priv->input,
-				 priv->keycode[cst816x_gest_idx(tch.gest)],
-				 tch.active);
+	key = cst816x_gest_keycode(priv, tch.gest);
+	if (key != KEY_RESERVED)
+		input_report_key(priv->input, key, 1);
+	else
+		cst816x_release_keys(priv);
 
 	input_report_key(priv->input, BTN_TOUCH, tch.active);
 
-- 
2.56.0

  parent reply	other threads:[~2026-10-05 21:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-05 21:10 [PATCH v4 0/5] Input: hynitron-cst816x: axes and " Daniel Golle
2026-10-05 21:11 ` [PATCH v4 1/5] dt-bindings: input: touchscreen: hynitron,cst816x: axes and panel Daniel Golle
2026-10-06  2:51   ` Rob Herring
2026-10-05 21:11 ` [PATCH v4 2/5] Input: hynitron-cst816x: respect touchscreen DT properties Daniel Golle
2026-10-05 21:11 ` Daniel Golle [this message]
2026-10-12 18:57   ` [PATCH v4 3/5] Input: hynitron-cst816x: release gesture keys Oleh Kuzhylnyi
2026-10-05 21:12 ` [PATCH v4 4/5] Input: hynitron-cst816x: time out gesture key release Daniel Golle
2026-10-12 18:58   ` Oleh Kuzhylnyi
2026-10-05 21:12 ` [PATCH v4 5/5] Input: hynitron-cst816x: set INPUT_PROP_DIRECT Daniel Golle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5312d67200e3251b2be08aef0a726d50d94fadde.1791233147.git.daniel@makrotopia.org \
    --to=daniel@makrotopia.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=krzk+dt@kernel.org \
    --cc=kuzhylol@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=u.kleine-koenig@baylibre.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®