linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
To: David Heidelberg <david@ixit.cz>,
	Dmitry Osipenko <digetx@gmail.com>,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Henrik Rydberg <rydberg@bitmath.org>,
	James Chen <james.chen@emc.com.tw>,
	Johnny Chuang <johnny.chuang@emc.com.tw>,
	Rob Herring <robh+dt@kernel.org>,
	Scott Liu <scott.liu@emc.com.tw>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v5 02/10] input: elants: support old touch report format
Date: Sun, 26 Apr 2020 19:47:49 +0200	[thread overview]
Message-ID: <0c2d8ebf44062bf84bc6e65a0445948fb6d1da63.1587923061.git.mirq-linux@rere.qmqm.pl> (raw)
In-Reply-To: <cover.1587923061.git.mirq-linux@rere.qmqm.pl>

Support ELAN touchpad sensor with older firmware as found on eg. Asus
Transformer Pads.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/input/touchscreen/elants_i2c.c | 36 ++++++++++++++++++--------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index d2175fb6209a..6c2b336d92bf 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -68,6 +68,7 @@
 #define CMD_HEADER_REK		0x66
 
 /* FW position data */
+#define PACKET_SIZE_OLD		40
 #define PACKET_SIZE		55
 #define MAX_CONTACT_NUM		10
 #define FW_POS_HEADER		0
@@ -855,7 +856,8 @@ static int elants_i2c_fw_update(struct elants_data *ts)
  * Event reporting.
  */
 
-static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
+static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf,
+				size_t report_len)
 {
 	struct input_dev *input = ts->input;
 	unsigned int n_fingers;
@@ -868,7 +870,8 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 			buf[FW_POS_STATE];
 
 	dev_dbg(&ts->client->dev,
-		"n_fingers: %u, state: %04x\n",  n_fingers, finger_state);
+		"n_fingers: %u, state: %04x, report_len: %zu\n",
+		n_fingers, finger_state, report_len);
 
 	/* Note: all fingers have the same tool type */
 	tool_type = buf[FW_POS_TOOL_TYPE] & BIT(0) ?
@@ -882,8 +885,16 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 			pos = &buf[FW_POS_XY + i * 3];
 			x = (((u16)pos[0] & 0xf0) << 4) | pos[1];
 			y = (((u16)pos[0] & 0x0f) << 8) | pos[2];
-			p = buf[FW_POS_PRESSURE + i];
-			w = buf[FW_POS_WIDTH + i];
+			if (report_len == PACKET_SIZE_OLD) {
+				w = buf[FW_POS_WIDTH + i / 2];
+				w >>= 4 * (~i & 1);	// little-endian-nibbles
+				w |= w << 4;
+				w |= !w;
+				p = w;
+			} else {
+				p = buf[FW_POS_PRESSURE + i];
+				w = buf[FW_POS_WIDTH + i];
+			}
 
 			dev_dbg(&ts->client->dev, "i=%d x=%d y=%d p=%d w=%d\n",
 				i, x, y, p, w);
@@ -916,7 +927,8 @@ static u8 elants_i2c_calculate_checksum(u8 *buf)
 	return checksum;
 }
 
-static void elants_i2c_event(struct elants_data *ts, u8 *buf)
+static void elants_i2c_event(struct elants_data *ts, u8 *buf,
+			     size_t report_len)
 {
 	u8 checksum = elants_i2c_calculate_checksum(buf);
 
@@ -930,7 +942,7 @@ static void elants_i2c_event(struct elants_data *ts, u8 *buf)
 			 "%s: unknown packet type: %02x\n",
 			 __func__, buf[FW_POS_HEADER]);
 	else
-		elants_i2c_mt_event(ts, buf);
+		elants_i2c_mt_event(ts, buf, report_len);
 }
 
 static irqreturn_t elants_i2c_irq(int irq, void *_dev)
@@ -988,7 +1000,8 @@ static irqreturn_t elants_i2c_irq(int irq, void *_dev)
 			break;
 
 		case QUEUE_HEADER_SINGLE:
-			elants_i2c_event(ts, &ts->buf[HEADER_SIZE]);
+			elants_i2c_event(ts, &ts->buf[HEADER_SIZE],
+					 ts->buf[FW_HDR_LENGTH]);
 			break;
 
 		case QUEUE_HEADER_NORMAL:
@@ -1001,17 +1014,18 @@ static irqreturn_t elants_i2c_irq(int irq, void *_dev)
 			}
 
 			report_len = ts->buf[FW_HDR_LENGTH] / report_count;
-			if (report_len != PACKET_SIZE) {
+			if (report_len != PACKET_SIZE &&
+			    report_len != PACKET_SIZE_OLD) {
 				dev_err(&client->dev,
-					"mismatching report length: %*ph\n",
+					"unsupported report length: %*ph\n",
 					HEADER_SIZE, ts->buf);
 				break;
 			}
 
 			for (i = 0; i < report_count; i++) {
 				u8 *buf = ts->buf + HEADER_SIZE +
-							i * PACKET_SIZE;
-				elants_i2c_event(ts, buf);
+					  i * report_len;
+				elants_i2c_event(ts, buf, report_len);
 			}
 			break;
 
-- 
2.20.1


  reply	other threads:[~2020-04-26 17:48 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-26 17:47 [PATCH v5 00/10] input: elants: Support Asus TF300T touchscreen Michał Mirosław
2020-04-26 17:47 ` Michał Mirosław [this message]
2020-04-26 17:47 ` [PATCH v5 01/10] input: elants: document some registers and values Michał Mirosław
2020-05-18  4:07   ` Dmitry Torokhov
2020-05-18  9:18     ` Dmitry Osipenko
2020-04-26 17:47 ` [PATCH v5 03/10] input: elants: remove unused axes Michał Mirosław
2020-04-26 18:34   ` Dmitry Osipenko
2020-05-18  3:39   ` Dmitry Torokhov
2020-04-26 17:47 ` [PATCH v5 04/10] input: elants: override touchscreen info with DT properties Michał Mirosław
2020-05-18  4:02   ` Dmitry Torokhov
2020-04-26 17:47 ` [PATCH v5 05/10] input: elants: refactor elants_i2c_execute_command() Michał Mirosław
2020-05-14 19:43   ` Dmitry Osipenko
2020-05-18  4:03   ` Dmitry Torokhov
2020-04-26 17:47 ` [PATCH v5 06/10] input: elants: read touchscreen size for EKTF3624 Michał Mirosław
2020-04-26 17:47 ` [PATCH v5 07/10] input: elants: support 0x66 reply opcode for reporting touches Michał Mirosław
2020-05-18  4:05   ` Dmitry Torokhov
2020-05-18  9:10     ` Dmitry Osipenko
2020-04-26 17:47 ` [PATCH v5 08/10] dt-bindings: input: elants-i2c: Document common touchscreen properties Michał Mirosław
2020-04-26 17:47 ` [PATCH v5 09/10] dt-bindings: input: elants-i2c: Document eKTF3624 Michał Mirosław
2020-04-26 17:47 ` [PATCH v5 10/10] dt-bindings: input: touchscreen: elants_i2c: convert to YAML Michał Mirosław
2020-05-14 19:45 ` [PATCH v5 00/10] input: elants: Support Asus TF300T touchscreen Dmitry Osipenko

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=0c2d8ebf44062bf84bc6e65a0445948fb6d1da63.1587923061.git.mirq-linux@rere.qmqm.pl \
    --to=mirq-linux@rere.qmqm.pl \
    --cc=david@ixit.cz \
    --cc=digetx@gmail.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=james.chen@emc.com.tw \
    --cc=johnny.chuang@emc.com.tw \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=rydberg@bitmath.org \
    --cc=scott.liu@emc.com.tw \
    /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;
as well as URLs for NNTP newsgroup(s).