2020-04-26 16:12:58

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 00/10] input: elants: Support Asus TF300T touchscreen

This series cleans up the driver a bit and implements changes needed to
support EKTF3624-based touchscreen used in Asus TF300T and similar
Tegra3-based tablets.

---
v2: extended with Dmitry's patches (replaced v1 patches 3 and 4)
v3: rebased for v5.7-rc1
v4: rebased onto v5.7-rc2+ (current Linus' master)
update "remove unused axes" and "refactor
elants_i2c_execute_command()" patches after review
add David's patch converting DT binding to YAML
---

David Heidelberg (1):
dt-bindings: input: touchscreen: elants_i2c: convert to YAML

Dmitry Osipenko (3):
input: elants: support 0x66 reply opcode for reporting touches
dt-bindings: input: elants-i2c: Document common touchscreen properties
dt-bindings: input: elants-i2c: Document eKTF3624

Michał Mirosław (6):
input: elants: document some registers and values
input: elants: support old touch report format
input: elants: remove unused axes
input: elants: override touchscreen info with DT properties
input: elants: refactor elants_i2c_execute_command()
input: elants: read touchscreen size for EKTF3624

.../devicetree/bindings/input/elants_i2c.txt | 34 --
.../input/touchscreen/elan,elants_i2c.yaml | 69 ++++
drivers/input/touchscreen/elants_i2c.c | 380 +++++++++++-------
3 files changed, 314 insertions(+), 169 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/input/elants_i2c.txt
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml

--
2.20.1


2020-04-26 16:13:16

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 10/10] dt-bindings: input: touchscreen: elants_i2c: convert to YAML

From: David Heidelberg <[email protected]>

Convert elants_i2c.txt DT binding to YAML and put into correct directory.

Signed-off-by: David Heidelberg <[email protected]>
Signed-off-by: Michał Mirosław <[email protected]>
---
.../devicetree/bindings/input/elants_i2c.txt | 38 ----------
.../input/touchscreen/elan,elants_i2c.yaml | 69 +++++++++++++++++++
2 files changed, 69 insertions(+), 38 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/elants_i2c.txt b/Documentation/devicetree/bindings/input/elants_i2c.txt
deleted file mode 100644
index 1bc60303f0ea..000000000000
--- a/Documentation/devicetree/bindings/input/elants_i2c.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-Elantech I2C Touchscreen
-
-Required properties:
-- compatible: must be "elan,ekth3500" or "elan,ektf3624".
-- reg: I2C address of the chip.
-- interrupts: interrupt to which the chip is connected (see interrupt
- binding[0]).
-
-Optional properties:
-- wakeup-source: touchscreen can be used as a wakeup source.
-- pinctrl-names: should be "default" (see pinctrl binding [1]).
-- pinctrl-0: a phandle pointing to the pin settings for the device (see
- pinctrl binding [1]).
-- reset-gpios: reset gpio the chip is connected to.
-- vcc33-supply: a phandle for the regulator supplying 3.3V power.
-- vccio-supply: a phandle for the regulator supplying IO power.
-- see [2] for additional properties
-
-For additional optional properties see: touchscreen.txt
-
-[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-[1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
-[2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
-
-Example:
- &i2c1 {
- /* ... */
-
- touchscreen@10 {
- compatible = "elan,ekth3500";
- reg = <0x10>;
- interrupt-parent = <&gpio4>;
- interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>;
- wakeup-source;
- };
-
- /* ... */
- };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml
new file mode 100644
index 000000000000..a792d6377b1d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/input/touchscreen/elan,elants_i2c.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Elantech I2C Touchscreen
+
+maintainers:
+ - David Heidelberg <[email protected]>
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+properties:
+ compatible:
+ enum:
+ - elan,ektf3624
+ - elan,ekth3500
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ wakeup-source:
+ type: boolean
+ description: touchscreen can be used as a wakeup source.
+
+ reset-gpios:
+ description: reset gpio the chip is connected to.
+
+ vcc33-supply:
+ description: a phandle for the regulator supplying 3.3V power.
+
+ vccio-supply:
+ description: a phandle for the regulator supplying IO power.
+
+ touchscreen-inverted-x: true
+ touchscreen-inverted-y: true
+ touchscreen-size-x: true
+ touchscreen-size-y: true
+ touchscreen-swapped-x-y: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@10 {
+ compatible = "elan,ekth3500";
+ reg = <0x10>;
+
+ interrupt-parent = <&gpio4>;
+ interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ };
+ };
--
2.20.1

2020-04-26 16:13:21

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 07/10] input: elants: support 0x66 reply opcode for reporting touches

From: Dmitry Osipenko <[email protected]>

eKTF3624 touchscreen firmware uses two variants of the reply opcodes for
reporting touch events: one is 0x63 (used by older firmware) and other is
0x66 (used by newer firmware). The 0x66 variant is equal to 0x63 of
eKTH3500, while 0x63 needs small adjustment of the touch pressure value.

Nexus 7 tablet device has eKTF3624 touchscreen and it uses 0x66 opcode for
reporting touch events, let's support it now. Other devices, eg. ASUS TF300T,
use 0x63.

Note: CMD_HEADER_REK is used for replying to calibration requests, it has
the same 0x66 opcode number which eKTF3624 uses for reporting touches.
The calibration replies are handled separately from the the rest of the
commands in the driver by entering into ELAN_WAIT_RECALIBRATION state
and thus this change shouldn't change the old behavior.

Signed-off-by: Dmitry Osipenko <[email protected]>
Tested-by: Michał Mirosław <[email protected]>
Signed-off-by: Michał Mirosław <[email protected]>
---
drivers/input/touchscreen/elants_i2c.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 34d5c1fb5bea..ece14cb39d63 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -60,6 +60,15 @@
#define QUEUE_HEADER_NORMAL 0X63
#define QUEUE_HEADER_WAIT 0x64

+/*
+ * Depending on firmware version, eKTF3624 touchscreens may utilize one of
+ * these opcodes for the touch events: 0x63 and 0x66. The 0x63 is used by
+ * older firmware version and differs from 0x66 such that touch pressure
+ * value needs to be adjusted. The 0x66 opcode of newer firmware is equal
+ * to 0x63 of eKTH3500.
+ */
+#define QUEUE_HEADER_NORMAL2 0x66
+
/* Command header definition */
#define CMD_HEADER_WRITE 0x54
#define CMD_HEADER_READ 0x53
@@ -1050,7 +1059,6 @@ static irqreturn_t elants_i2c_irq(int irq, void *_dev)
switch (ts->buf[FW_HDR_TYPE]) {
case CMD_HEADER_HELLO:
case CMD_HEADER_RESP:
- case CMD_HEADER_REK:
break;

case QUEUE_HEADER_WAIT:
@@ -1070,6 +1078,7 @@ static irqreturn_t elants_i2c_irq(int irq, void *_dev)
break;

case QUEUE_HEADER_NORMAL:
+ case QUEUE_HEADER_NORMAL2:
report_count = ts->buf[FW_HDR_COUNT];
if (report_count == 0 || report_count > 3) {
dev_err(&client->dev,
--
2.20.1

2020-04-26 16:13:26

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 06/10] input: elants: read touchscreen size for EKTF3624

EKTF3624 as present in Asus TF300T tablet has touchscreen size encoded
in different registers.

Signed-off-by: Michał Mirosław <[email protected]>
Reviewed-by: Dmitry Osipenko <[email protected]>
Tested-by: Dmitry Osipenko <[email protected]>
---
drivers/input/touchscreen/elants_i2c.c | 82 ++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 71ffbc565d8e..34d5c1fb5bea 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -34,7 +34,7 @@
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/acpi.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
@@ -42,6 +42,10 @@
/* Device, Driver information */
#define DEVICE_NAME "elants_i2c"

+/* Device IDs */
+#define EKTH3500 0
+#define EKTF3624 1
+
/* Convert from rows or columns into resolution */
#define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m))

@@ -164,6 +168,7 @@ struct elants_data {

bool wake_irq_enabled;
bool keep_power_in_suspend;
+ u8 chip_id;

/* Must be last to be used for DMA operations */
u8 buf[MAX_PACKET_SIZE] ____cacheline_aligned;
@@ -442,7 +447,58 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
return 0;
}

-static int elants_i2c_query_ts_info(struct elants_data *ts)
+static int elants_i2c_query_ts_info_ektf(struct elants_data *ts)
+{
+ struct i2c_client *client = ts->client;
+ int error;
+ u8 resp[4];
+ u16 phy_x, phy_y;
+ const u8 get_xres_cmd[] = {
+ CMD_HEADER_READ, E_INFO_X_RES, 0x00, 0x00
+ };
+ const u8 get_yres_cmd[] = {
+ CMD_HEADER_READ, E_INFO_Y_RES, 0x00, 0x00
+ };
+
+ /* Get X/Y size in mm */
+ error = elants_i2c_execute_command(client, get_xres_cmd,
+ sizeof(get_xres_cmd),
+ resp, sizeof(resp), 1,
+ "get X size");
+ if (error)
+ return error;
+
+ phy_x = resp[2] | ((resp[3] & 0xF0) << 4);
+
+ error = elants_i2c_execute_command(client, get_yres_cmd,
+ sizeof(get_yres_cmd),
+ resp, sizeof(resp), 1,
+ "get Y size");
+ if (error)
+ return error;
+
+ phy_y = resp[2] | ((resp[3] & 0xF0) << 4);
+
+ if (!phy_x || !phy_y) {
+ dev_warn(&client->dev,
+ "invalid size data: %d x %d mm\n",
+ phy_x, phy_y);
+ return 0;
+ }
+
+ dev_dbg(&client->dev, "phy_x=%d, phy_y=%d\n", phy_x, phy_y);
+
+ /* calculate resolution from size */
+ ts->x_max = 2240-1;
+ ts->x_res = DIV_ROUND_CLOSEST(ts->prop.max_x, phy_x);
+
+ ts->y_max = 1408-1;
+ ts->y_res = DIV_ROUND_CLOSEST(ts->prop.max_y, phy_y);
+
+ return 0;
+}
+
+static int elants_i2c_query_ts_info_ekth(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int error;
@@ -593,8 +649,20 @@ static int elants_i2c_initialize(struct elants_data *ts)
error = elants_i2c_query_fw_version(ts);
if (!error)
error = elants_i2c_query_test_version(ts);
- if (!error)
- error = elants_i2c_query_ts_info(ts);
+
+ switch (ts->chip_id) {
+ case EKTH3500:
+ if (!error)
+ error = elants_i2c_query_ts_info_ekth(ts);
+ break;
+ case EKTF3624:
+ if (!error)
+ error = elants_i2c_query_ts_info_ektf(ts);
+ break;
+ default:
+ unreachable();
+ break;
+ }

if (error)
ts->iap_mode = ELAN_IAP_RECOVERY;
@@ -1245,6 +1313,9 @@ static int elants_i2c_probe(struct i2c_client *client,
ts->client = client;
i2c_set_clientdata(client, ts);

+ if (client->dev.of_node)
+ ts->chip_id = (uintptr_t)of_device_get_match_data(&client->dev);
+
ts->vcc33 = devm_regulator_get(&client->dev, "vcc33");
if (IS_ERR(ts->vcc33)) {
error = PTR_ERR(ts->vcc33);
@@ -1471,7 +1542,8 @@ MODULE_DEVICE_TABLE(acpi, elants_acpi_id);

#ifdef CONFIG_OF
static const struct of_device_id elants_of_match[] = {
- { .compatible = "elan,ekth3500" },
+ { .compatible = "elan,ekth3500", .data = (void *)EKTH3500 },
+ { .compatible = "elan,ektf3624", .data = (void *)EKTF3624 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, elants_of_match);
--
2.20.1

2020-04-26 16:13:30

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 05/10] input: elants: refactor elants_i2c_execute_command()

Apply some DRY-ing to elants_i2c_execute_command() callers. This pulls
polling and error printk()s into a single function.

Signed-off-by: Michał Mirosław <[email protected]>
---
v4: return 0 on success; use %pe for error code
---
drivers/input/touchscreen/elants_i2c.c | 189 +++++++++++++------------
1 file changed, 96 insertions(+), 93 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index c08a7971cd32..71ffbc565d8e 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -205,7 +205,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)

static int elants_i2c_execute_command(struct i2c_client *client,
const u8 *cmd, size_t cmd_size,
- u8 *resp, size_t resp_size)
+ u8 *resp, size_t resp_size,
+ int retries, const char *cmd_name)
{
struct i2c_msg msgs[2];
int ret;
@@ -225,30 +226,55 @@ static int elants_i2c_execute_command(struct i2c_client *client,
break;

default:
- dev_err(&client->dev, "%s: invalid command %*ph\n",
- __func__, (int)cmd_size, cmd);
+ dev_err(&client->dev, "(%s): invalid command: %*ph\n",
+ cmd_name, (int)cmd_size, cmd);
return -EINVAL;
}

- msgs[0].addr = client->addr;
- msgs[0].flags = client->flags & I2C_M_TEN;
- msgs[0].len = cmd_size;
- msgs[0].buf = (u8 *)cmd;
+ for (;;) {
+ msgs[0].addr = client->addr;
+ msgs[0].flags = client->flags & I2C_M_TEN;
+ msgs[0].len = cmd_size;
+ msgs[0].buf = (u8 *)cmd;

- msgs[1].addr = client->addr;
- msgs[1].flags = client->flags & I2C_M_TEN;
- msgs[1].flags |= I2C_M_RD;
- msgs[1].len = resp_size;
- msgs[1].buf = resp;
+ msgs[1].addr = client->addr;
+ msgs[1].flags = client->flags & I2C_M_TEN;
+ msgs[1].flags |= I2C_M_RD;
+ msgs[1].len = resp_size;
+ msgs[1].buf = resp;

- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret < 0)
- return ret;
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0) {
+ if (--retries > 0) {
+ dev_dbg(&client->dev,
+ "(%s) I2C transfer failed: %pe (retrying)\n",
+ cmd_name, ERR_PTR(ret));
+ continue;
+ }

- if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
- return -EIO;
+ dev_err(&client->dev,
+ "(%s) I2C transfer failed: %pe\n",
+ cmd_name, ERR_PTR(ret));
+ return ret;
+ }

- return 0;
+ if (ret != ARRAY_SIZE(msgs) ||
+ resp[FW_HDR_TYPE] != expected_response) {
+ if (--retries > 0) {
+ dev_dbg(&client->dev,
+ "(%s) unexpected response: %*ph (retrying)\n",
+ cmd_name, ret, resp);
+ continue;
+ }
+
+ dev_err(&client->dev,
+ "(%s) unexpected response: %*ph\n",
+ cmd_name, ret, resp);
+ return -EIO;
+ }
+
+ return 0;
+ }
}

static int elants_i2c_calibrate(struct elants_data *ts)
@@ -321,27 +347,21 @@ static u16 elants_i2c_parse_version(u8 *buf)
static int elants_i2c_query_hw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
+ int err;

- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
- error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- ts->hw_version = elants_i2c_parse_version(resp);
- if (ts->hw_version != 0xffff)
- return 0;
- }
+ while (retry_cnt--) {
+ err = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+ resp, sizeof(resp), 1,
+ "read fw id");
+ if (err < 0)
+ return err;

- dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
- }
-
- if (error) {
- dev_err(&client->dev,
- "Failed to read fw id: %d\n", error);
- return error;
+ ts->hw_version = elants_i2c_parse_version(resp);
+ if (ts->hw_version != 0xffff)
+ return 0;
}

dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
@@ -352,26 +372,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts)
static int elants_i2c_query_fw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
+ int err;

- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
- error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- ts->fw_version = elants_i2c_parse_version(resp);
- if (ts->fw_version != 0x0000 &&
- ts->fw_version != 0xffff)
- return 0;
- }
+ while (retry_cnt--) {
+ err = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+ resp, sizeof(resp), 1,
+ "read fw version");
+ if (err < 0)
+ return err;

- dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ ts->fw_version = elants_i2c_parse_version(resp);
+ if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
+ return 0;
+
+ dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
+ (int)sizeof(resp), resp);
}

- dev_err(&client->dev,
- "Failed to read fw version or fw version is invalid\n");
+ dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);

return -EINVAL;
}
@@ -379,25 +400,20 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
static int elants_i2c_query_test_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int error;
u16 version;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];

- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
- error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- version = elants_i2c_parse_version(resp);
- ts->test_version = version >> 8;
- ts->solution_version = version & 0xff;
+ error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+ resp, sizeof(resp), MAX_RETRIES,
+ "read test version");
+ if (!error) {
+ version = elants_i2c_parse_version(resp);
+ ts->test_version = version >> 8;
+ ts->solution_version = version & 0xff;

- return 0;
- }
-
- dev_dbg(&client->dev,
- "read test version error rc=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ return 0;
}

dev_err(&client->dev, "Failed to read test version\n");
@@ -414,13 +430,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
int error;

error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev,
- "read BC version error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ resp, sizeof(resp), 1,
+ "read BC version");
+ if (error)
return error;
- }

version = elants_i2c_parse_version(resp);
ts->bc_version = version >> 8;
@@ -452,12 +465,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
error = elants_i2c_execute_command(client,
get_resolution_cmd,
sizeof(get_resolution_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get resolution command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get resolution");
+ if (error)
return error;
- }

rows = resp[2] + resp[6] + resp[10];
cols = resp[3] + resp[7] + resp[11];
@@ -465,36 +476,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
/* Process mm_to_pixel information */
error = elants_i2c_execute_command(client,
get_osr_cmd, sizeof(get_osr_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get osr command failed: %d\n",
- error);
+ resp, sizeof(resp), 1, "get osr");
+ if (error)
return error;
- }

osr = resp[3];

error = elants_i2c_execute_command(client,
get_physical_scan_cmd,
sizeof(get_physical_scan_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get physical scan command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get physical scan");
+ if (error)
return error;
- }

phy_x = get_unaligned_be16(&resp[2]);

error = elants_i2c_execute_command(client,
get_physical_drive_cmd,
sizeof(get_physical_drive_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get physical drive command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get physical drive");
+ if (error)
return error;
- }

phy_y = get_unaligned_be16(&resp[2]);

@@ -649,11 +653,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,

/* Compare TS Remark ID and FW Remark ID */
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
+ resp, sizeof(resp),
+ 1, "read Remark ID");
+ if (error < 0)
return error;
- }

ts_remark_id = get_unaligned_be16(&resp[3]);

--
2.20.1

2020-04-26 16:13:44

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 09/10] dt-bindings: input: elants-i2c: Document eKTF3624

From: Dmitry Osipenko <[email protected]>

The eKTF3624 hardware is similar to eKTH3500.

Signed-off-by: Dmitry Osipenko <[email protected]>
Reviewed-by: Michał Mirosław <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Michał Mirosław <[email protected]>
---
Documentation/devicetree/bindings/input/elants_i2c.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/elants_i2c.txt b/Documentation/devicetree/bindings/input/elants_i2c.txt
index 45fab32bbc19..1bc60303f0ea 100644
--- a/Documentation/devicetree/bindings/input/elants_i2c.txt
+++ b/Documentation/devicetree/bindings/input/elants_i2c.txt
@@ -1,7 +1,7 @@
Elantech I2C Touchscreen

Required properties:
-- compatible: must be "elan,ekth3500".
+- compatible: must be "elan,ekth3500" or "elan,ektf3624".
- reg: I2C address of the chip.
- interrupts: interrupt to which the chip is connected (see interrupt
binding[0]).
--
2.20.1

2020-04-26 16:13:49

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 08/10] dt-bindings: input: elants-i2c: Document common touchscreen properties

From: Dmitry Osipenko <[email protected]>

Document support of the common touchscreen properties.

Signed-off-by: Dmitry Osipenko <[email protected]>
Reviewed-by: Michał Mirosław <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Michał Mirosław <[email protected]>
---
Documentation/devicetree/bindings/input/elants_i2c.txt | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/elants_i2c.txt b/Documentation/devicetree/bindings/input/elants_i2c.txt
index 5edac8be0802..45fab32bbc19 100644
--- a/Documentation/devicetree/bindings/input/elants_i2c.txt
+++ b/Documentation/devicetree/bindings/input/elants_i2c.txt
@@ -14,9 +14,13 @@ Optional properties:
- reset-gpios: reset gpio the chip is connected to.
- vcc33-supply: a phandle for the regulator supplying 3.3V power.
- vccio-supply: a phandle for the regulator supplying IO power.
+- see [2] for additional properties
+
+For additional optional properties see: touchscreen.txt

[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
[1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+[2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt

Example:
&i2c1 {
--
2.20.1

2020-04-26 16:13:55

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 03/10] input: elants: remove unused axes

Driver only ever reports MT events and input_mt_init_slots() sets up
emulated axes already. Clear the capabilities not generated directly
and move MT axes setup, so they are visible by input_mt_init_slots().

Signed-off-by: Michał Mirosław <[email protected]>
Reviewed-by: Dmitry Osipenko <[email protected]>
Tested-by: Dmitry Osipenko <[email protected]>
---
v4: reword commitmsg; reorder axis setup
---
drivers/input/touchscreen/elants_i2c.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index ddebd3741145..58aa9b7dbcbf 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -1312,25 +1312,7 @@ static int elants_i2c_probe(struct i2c_client *client,
ts->input->name = "Elan Touchscreen";
ts->input->id.bustype = BUS_I2C;

- __set_bit(BTN_TOUCH, ts->input->keybit);
- __set_bit(EV_ABS, ts->input->evbit);
- __set_bit(EV_KEY, ts->input->evbit);
-
- /* Single touch input params setup */
- input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0);
- input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0);
- input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0);
- input_abs_set_res(ts->input, ABS_X, ts->x_res);
- input_abs_set_res(ts->input, ABS_Y, ts->y_res);
-
/* Multitouch input params setup */
- error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
- INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
- if (error) {
- dev_err(&client->dev,
- "failed to initialize MT slots: %d\n", error);
- return error;
- }

input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0);
input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
@@ -1340,6 +1322,14 @@ static int elants_i2c_probe(struct i2c_client *client,
input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);

+ error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+ if (error) {
+ dev_err(&client->dev,
+ "failed to initialize MT slots: %d\n", error);
+ return error;
+ }
+
error = input_register_device(ts->input);
if (error) {
dev_err(&client->dev,
--
2.20.1

2020-04-26 16:14:04

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 04/10] input: elants: override touchscreen info with DT properties

Allow overriding of information from hardware and support additional
common DT properties like axis inversion. This is required for eg.
Nexus 7 and TF300T where the programmed values in firmware differ
from reality.

Signed-off-by: Dmitry Osipenko <[email protected]>
[moved "prop" before DMA buffer]
Signed-off-by: Michał Mirosław <[email protected]>
---
drivers/input/touchscreen/elants_i2c.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 58aa9b7dbcbf..c08a7971cd32 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
@@ -150,6 +151,7 @@ struct elants_data {
unsigned int y_res;
unsigned int x_max;
unsigned int y_max;
+ struct touchscreen_properties prop;

enum elants_state state;
enum elants_iap_mode iap_mode;
@@ -894,8 +896,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf,

input_mt_slot(input, i);
input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
- input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
+ touchscreen_report_pos(input, &ts->prop, x, y, true);
input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w);

@@ -1322,6 +1323,8 @@ static int elants_i2c_probe(struct i2c_client *client,
input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);

+ touchscreen_parse_properties(ts->input, true, &ts->prop);
+
error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
if (error) {
--
2.20.1

2020-04-26 16:14:25

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 02/10] input: elants: support old touch report format

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

Signed-off-by: Michał Mirosław <[email protected]>
Reviewed-by: Dmitry Osipenko <[email protected]>
Tested-by: Dmitry Osipenko <[email protected]>
---
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 b528bd687cca..ddebd3741145 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -67,6 +67,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
@@ -853,7 +854,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;
@@ -865,7 +867,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);

for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
if (finger_state & 1) {
@@ -875,8 +878,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);
@@ -909,7 +920,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);

@@ -923,7 +935,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)
@@ -981,7 +993,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:
@@ -994,17 +1007,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

2020-04-26 16:16:57

by Michał Mirosław

[permalink] [raw]
Subject: [PATCH v4 01/10] input: elants: document some registers and values

Add information found in downstream kernels, to make the code less
magic.

Signed-off-by: Michał Mirosław <[email protected]>
Reviewed-by: Dmitry Osipenko <[email protected]>
Tested-by: Dmitry Osipenko <[email protected]>
---
drivers/input/touchscreen/elants_i2c.c | 29 +++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 14c577c16b16..b528bd687cca 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -79,7 +79,11 @@

#define HEADER_REPORT_10_FINGER 0x62

-/* Header (4 bytes) plus 3 fill 10-finger packets */
+/* Power state */
+#define PWR_STATE_DEEP_SLEEP 0
+#define PWR_STATE_NORMAL 1
+
+/* Header (4 bytes) plus 3 full 10-finger packets */
#define MAX_PACKET_SIZE 169

#define BOOT_TIME_DELAY_MS 50
@@ -89,10 +93,21 @@
#define E_ELAN_INFO_BC_VER 0x10
#define E_ELAN_INFO_TEST_VER 0xE0
#define E_ELAN_INFO_FW_ID 0xF0
+#define E_POWER_MODE 0x40
+#define E_POWER_STATE 0x50
+#define E_INFO_X_RES 0x60
+#define E_INFO_Y_RES 0x63
#define E_INFO_OSR 0xD6
#define E_INFO_PHY_SCAN 0xD7
#define E_INFO_PHY_DRIVER 0xD8

+/* FW write command, 0x54 0x?? 0x0, 0x01 */
+#define E_POWER_MODE_BATTERY 0x40
+#define E_POWER_MODE_AC 0x41
+#define E_POWER_MODE_USB 0x42
+#define E_POWER_STATE_SLEEP 0x50
+#define E_POWER_STATE_RESUME 0x58
+
#define MAX_RETRIES 3
#define MAX_FW_UPDATE_RETRIES 30

@@ -237,8 +252,8 @@ static int elants_i2c_calibrate(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int ret, error;
- static const u8 w_flashkey[] = { 0x54, 0xC0, 0xE1, 0x5A };
- static const u8 rek[] = { 0x54, 0x29, 0x00, 0x01 };
+ static const u8 w_flashkey[] = { CMD_HEADER_WRITE, 0xC0, 0xE1, 0x5A };
+ static const u8 rek[] = { CMD_HEADER_WRITE, 0x29, 0x00, 0x01 };
static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 };

disable_irq(client->irq);
@@ -1357,7 +1372,9 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct elants_data *ts = i2c_get_clientdata(client);
- const u8 set_sleep_cmd[] = { 0x54, 0x50, 0x00, 0x01 };
+ const u8 set_sleep_cmd[] = {
+ CMD_HEADER_WRITE, E_POWER_STATE_SLEEP, 0x00, 0x01
+ };
int retry_cnt;
int error;

@@ -1394,7 +1411,9 @@ static int __maybe_unused elants_i2c_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct elants_data *ts = i2c_get_clientdata(client);
- const u8 set_active_cmd[] = { 0x54, 0x58, 0x00, 0x01 };
+ const u8 set_active_cmd[] = {
+ CMD_HEADER_WRITE, E_POWER_STATE_RESUME, 0x00, 0x01
+ };
int retry_cnt;
int error;

--
2.20.1

2020-04-26 16:26:04

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v4 05/10] input: elants: refactor elants_i2c_execute_command()

26.04.2020 19:11, Michał Mirosław пишет:
> Apply some DRY-ing to elants_i2c_execute_command() callers. This pulls
> polling and error printk()s into a single function.
>
> Signed-off-by: Michał Mirosław <[email protected]>
> ---
> v4: return 0 on success; use %pe for error code
> ---
> drivers/input/touchscreen/elants_i2c.c | 189 +++++++++++++------------
> 1 file changed, 96 insertions(+), 93 deletions(-)

This patch doesn't apply to the recent linux-next, it needs to be rebased.

2020-04-26 16:39:56

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v4 03/10] input: elants: remove unused axes

26.04.2020 19:11, Michał Mirosław пишет:
> Driver only ever reports MT events and input_mt_init_slots() sets up
> emulated axes already. Clear the capabilities not generated directly
> and move MT axes setup, so they are visible by input_mt_init_slots().
>
> Signed-off-by: Michał Mirosław <[email protected]>
> Reviewed-by: Dmitry Osipenko <[email protected]>
> Tested-by: Dmitry Osipenko <[email protected]>
> ---
> v4: reword commitmsg; reorder axis setup
> ---

Legacy pointer emulation doesn't work using v4. I think it will be
better to drop this patch for now and add this hunk to the patch #4:

--- >8 ---
diff --git a/drivers/input/touchscreen/elants_i2c.c
b/drivers/input/touchscreen/elants_i2c.c
index 060c60c04f25..3644b5b48081 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -1414,6 +1414,8 @@ static int elants_i2c_probe(struct i2c_client *client,
input_abs_set_res(ts->input, ABS_X, ts->x_res);
input_abs_set_res(ts->input, ABS_Y, ts->y_res);

+ touchscreen_parse_properties(ts->input, false, &ts->prop);
+
/* Multitouch input params setup */
error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
--- >8 ---

This hunk makes the DT properties to be applied for the legacy pointer,
fixing the cursor position on Nexus 7 device using Ubuntu 12.04. The MT
still works fine using Ubuntu 20.04.

Maybe input_mt_init_slots() could be changed to set up all the
properties that are needed for the legacy pointer, but I'm not 100% sure
because not very familiar with that code. Perhaps Dmitry Torokhov could
clarify?

2020-04-26 17:34:42

by Michał Mirosław

[permalink] [raw]
Subject: Re: [PATCH v4 03/10] input: elants: remove unused axes

On Sun, Apr 26, 2020 at 07:35:47PM +0300, Dmitry Osipenko wrote:
> 26.04.2020 19:11, Michał Mirosław пишет:
> > Driver only ever reports MT events and input_mt_init_slots() sets up
> > emulated axes already. Clear the capabilities not generated directly
> > and move MT axes setup, so they are visible by input_mt_init_slots().
> >
> > Signed-off-by: Michał Mirosław <[email protected]>
> > Reviewed-by: Dmitry Osipenko <[email protected]>
> > Tested-by: Dmitry Osipenko <[email protected]>
> > ---
> > v4: reword commitmsg; reorder axis setup
> > ---
>
> Legacy pointer emulation doesn't work using v4. I think it will be
> better to drop this patch for now and add this hunk to the patch #4:

Have you tried it together with the next patch? It adds
touchscreen_parse_properties() to initialize axes also from DT, and
should be equivalent to the hunk you proposed.

[...]
> Maybe input_mt_init_slots() could be changed to set up all the
> properties that are needed for the legacy pointer, but I'm not 100% sure
> because not very familiar with that code. Perhaps Dmitry Torokhov could
> clarify?

The code of input_mt_init_slots() looks like it does initialize the
properties needed. What does evtest return with and without the patches?

Best Regards
Michał Mirosław

2020-04-26 17:42:57

by Michał Mirosław

[permalink] [raw]
Subject: Re: [PATCH v4 05/10] input: elants: refactor elants_i2c_execute_command()

On Sun, Apr 26, 2020 at 07:24:14PM +0300, Dmitry Osipenko wrote:
> 26.04.2020 19:11, Michał Mirosław пишет:
> > Apply some DRY-ing to elants_i2c_execute_command() callers. This pulls
> > polling and error printk()s into a single function.
> >
> > Signed-off-by: Michał Mirosław <[email protected]>
> > ---
> > v4: return 0 on success; use %pe for error code
> > ---
> > drivers/input/touchscreen/elants_i2c.c | 189 +++++++++++++------------
> > 1 file changed, 96 insertions(+), 93 deletions(-)
>
> This patch doesn't apply to the recent linux-next, it needs to be rebased.

I'm rebasing against for-linus brach at [1]. Will send v5 shortly.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git

2020-04-26 17:47:05

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v4 03/10] input: elants: remove unused axes

26.04.2020 20:29, Michał Mirosław пишет:
> On Sun, Apr 26, 2020 at 07:35:47PM +0300, Dmitry Osipenko wrote:
>> 26.04.2020 19:11, Michał Mirosław пишет:
>>> Driver only ever reports MT events and input_mt_init_slots() sets up
>>> emulated axes already. Clear the capabilities not generated directly
>>> and move MT axes setup, so they are visible by input_mt_init_slots().
>>>
>>> Signed-off-by: Michał Mirosław <[email protected]>
>>> Reviewed-by: Dmitry Osipenko <[email protected]>
>>> Tested-by: Dmitry Osipenko <[email protected]>
>>> ---
>>> v4: reword commitmsg; reorder axis setup
>>> ---
>>
>> Legacy pointer emulation doesn't work using v4. I think it will be
>> better to drop this patch for now and add this hunk to the patch #4:
>
> Have you tried it together with the next patch? It adds
> touchscreen_parse_properties() to initialize axes also from DT, and
> should be equivalent to the hunk you proposed.

Yes, the touchscreen_parse_properties() takes bool multitouch for the
argument, and thus, it needs to be applied to both MT/non-MT cases.

https://elixir.bootlin.com/linux/v5.7-rc2/source/drivers/input/touchscreen/of_touchscreen.c#L64

> [...]
>> Maybe input_mt_init_slots() could be changed to set up all the
>> properties that are needed for the legacy pointer, but I'm not 100% sure
>> because not very familiar with that code. Perhaps Dmitry Torokhov could
>> clarify?
>
> The code of input_mt_init_slots() looks like it does initialize the
> properties needed. What does evtest return with and without the patches?

==== vanilla v4 (doesn't work) ====

Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "Elan Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 47 (ABS_MT_SLOT)
Value 0
Min 0
Max 9
Event code 48 (ABS_MT_TOUCH_MAJOR)
Value 0
Min 0
Max 255
Resolution 1
Event code 53 (ABS_MT_POSITION_X)
Value 0
Min 0
Max 1279
Event code 54 (ABS_MT_POSITION_Y)
Value 0
Min 0
Max 2111
Event code 55 (ABS_MT_TOOL_TYPE)
Value 0
Min 0
Max 2
Event code 57 (ABS_MT_TRACKING_ID)
Value 0
Min 0
Max 65535
Event code 58 (ABS_MT_PRESSURE)
Value 0
Min 0
Max 255

Event: time 1587922487.077439, type 3 (EV_ABS), code 57
(ABS_MT_TRACKING_ID), value 64
Event: time 1587922487.077439, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 855
Event: time 1587922487.077439, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 893
Event: time 1587922487.077439, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 47
Event: time 1587922487.077439, type 1 (EV_KEY), code 330 (BTN_TOUCH),
value 1
Event: time 1587922487.077439, -------------- SYN_REPORT ------------
Event: time 1587922487.089144, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 899
Event: time 1587922487.089144, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 124
Event: time 1587922487.089144, type 3 (EV_ABS), code 48
(ABS_MT_TOUCH_MAJOR), value 11
Event: time 1587922487.089144, -------------- SYN_REPORT ------------
Event: time 1587922487.100292, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 854
Event: time 1587922487.100292, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 911
Event: time 1587922487.100292, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 166
Event: time 1587922487.100292, -------------- SYN_REPORT ------------
Event: time 1587922487.109238, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 851
Event: time 1587922487.109238, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 922
Event: time 1587922487.109238, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 180
Event: time 1587922487.109238, -------------- SYN_REPORT ------------
Event: time 1587922487.117997, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 847
Event: time 1587922487.117997, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 936
Event: time 1587922487.117997, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 187
Event: time 1587922487.117997, -------------- SYN_REPORT ------------
Event: time 1587922487.126925, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 841
Event: time 1587922487.126925, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 947
Event: time 1587922487.126925, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 199
Event: time 1587922487.126925, -------------- SYN_REPORT ------------
Event: time 1587922487.139066, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 836
Event: time 1587922487.139066, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 958
Event: time 1587922487.139066, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 204
Event: time 1587922487.139066, -------------- SYN_REPORT ------------
Event: time 1587922487.150355, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 829
Event: time 1587922487.150355, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 969
Event: time 1587922487.150355, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 207
Event: time 1587922487.150355, -------------- SYN_REPORT ------------
Event: time 1587922487.172261, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 826
Event: time 1587922487.172261, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 977
Event: time 1587922487.172261, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 183
Event: time 1587922487.172261, -------------- SYN_REPORT ------------
Event: time 1587922487.205326, type 3 (EV_ABS), code 57
(ABS_MT_TRACKING_ID), value -1
Event: time 1587922487.205326, type 1 (EV_KEY), code 330 (BTN_TOUCH),
value 0
Event: time 1587922487.205326, -------------- SYN_REPORT ------------


==== v4 with reverted patch #3 + my hunk applied (works) ====

Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "Elan Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 0
Min 0
Max 1279
Event code 1 (ABS_Y)
Value 0
Min 0
Max 2111
Event code 24 (ABS_PRESSURE)
Value 0
Min 0
Max 255
Event code 47 (ABS_MT_SLOT)
Value 0
Min 0
Max 9
Event code 48 (ABS_MT_TOUCH_MAJOR)
Value 0
Min 0
Max 255
Resolution 1
Event code 53 (ABS_MT_POSITION_X)
Value 0
Min 0
Max 1279
Event code 54 (ABS_MT_POSITION_Y)
Value 0
Min 0
Max 2111
Event code 55 (ABS_MT_TOOL_TYPE)
Value 0
Min 0
Max 2
Event code 57 (ABS_MT_TRACKING_ID)
Value 0
Min 0
Max 65535
Event code 58 (ABS_MT_PRESSURE)
Value 0
Min 0
Max 255
Testing ... (interrupt to exit)
Event: time 1587922846.335151, type 3 (EV_ABS), code 57
(ABS_MT_TRACKING_ID), value 0
Event: time 1587922846.335151, type 3 (EV_ABS), code 53
(ABS_MT_POSITION_X), value 565
Event: time 1587922846.335151, type 3 (EV_ABS), code 54
(ABS_MT_POSITION_Y), value 423
Event: time 1587922846.335151, type 3 (EV_ABS), code 58
(ABS_MT_PRESSURE), value 39
Event: time 1587922846.335151, type 3 (EV_ABS), code 48
(ABS_MT_TOUCH_MAJOR), value 10
Event: time 1587922846.335151, type 1 (EV_KEY), code 330 (BTN_TOUCH),
value 1
Event: time 1587922846.335151, type 3 (EV_ABS), code 0 (ABS_X), value 565
Event: time 1587922846.335151, type 3 (EV_ABS), code 1 (ABS_Y), value 423
Event: time 1587922846.335151, type 3 (EV_ABS), code 24 (ABS_PRESSURE),
value 39
Event: time 1587922846.335151, -------------- SYN_REPORT ------------
Event: time 1587922846.464426, type 3 (EV_ABS), code 57
(ABS_MT_TRACKING_ID), value -1
Event: time 1587922846.464426, type 1 (EV_KEY), code 330 (BTN_TOUCH),
value 0
Event: time 1587922846.464426, type 3 (EV_ABS), code 24 (ABS_PRESSURE),
value 0
Event: time 1587922846.464426, -------------- SYN_REPORT ------------

2020-04-26 17:59:56

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v4 03/10] input: elants: remove unused axes

26.04.2020 20:45, Dmitry Osipenko пишет:
> 26.04.2020 20:29, Michał Mirosław пишет:
>> On Sun, Apr 26, 2020 at 07:35:47PM +0300, Dmitry Osipenko wrote:
>>> 26.04.2020 19:11, Michał Mirosław пишет:
>>>> Driver only ever reports MT events and input_mt_init_slots() sets up
>>>> emulated axes already. Clear the capabilities not generated directly
>>>> and move MT axes setup, so they are visible by input_mt_init_slots().
>>>>
>>>> Signed-off-by: Michał Mirosław <[email protected]>
>>>> Reviewed-by: Dmitry Osipenko <[email protected]>
>>>> Tested-by: Dmitry Osipenko <[email protected]>
>>>> ---
>>>> v4: reword commitmsg; reorder axis setup
>>>> ---
>>>
>>> Legacy pointer emulation doesn't work using v4. I think it will be
>>> better to drop this patch for now and add this hunk to the patch #4:
>>
>> Have you tried it together with the next patch? It adds
>> touchscreen_parse_properties() to initialize axes also from DT, and
>> should be equivalent to the hunk you proposed.
>
> Yes, the touchscreen_parse_properties() takes bool multitouch for the
> argument, and thus, it needs to be applied to both MT/non-MT cases.
>
> https://elixir.bootlin.com/linux/v5.7-rc2/source/drivers/input/touchscreen/of_touchscreen.c#L64
>
>> [...]
>>> Maybe input_mt_init_slots() could be changed to set up all the
>>> properties that are needed for the legacy pointer, but I'm not 100% sure
>>> because not very familiar with that code. Perhaps Dmitry Torokhov could
>>> clarify?
>>
>> The code of input_mt_init_slots() looks like it does initialize the
>> properties needed. What does evtest return with and without the patches?

Oh wait, seems I messed up something while was applying the patches.
I'll try the v5 now.

2020-04-26 18:18:57

by Michał Mirosław

[permalink] [raw]
Subject: Re: [PATCH v4 03/10] input: elants: remove unused axes

On Sun, Apr 26, 2020 at 08:45:14PM +0300, Dmitry Osipenko wrote:
> 26.04.2020 20:29, Michał Mirosław пишет:
> > On Sun, Apr 26, 2020 at 07:35:47PM +0300, Dmitry Osipenko wrote:
> >> 26.04.2020 19:11, Michał Mirosław пишет:
> >>> Driver only ever reports MT events and input_mt_init_slots() sets up
> >>> emulated axes already. Clear the capabilities not generated directly
> >>> and move MT axes setup, so they are visible by input_mt_init_slots().
> >>>
> >>> Signed-off-by: Michał Mirosław <[email protected]>
> >>> Reviewed-by: Dmitry Osipenko <[email protected]>
> >>> Tested-by: Dmitry Osipenko <[email protected]>
> >>> ---
> >>> v4: reword commitmsg; reorder axis setup
> >>> ---
> >>
> >> Legacy pointer emulation doesn't work using v4. I think it will be
> >> better to drop this patch for now and add this hunk to the patch #4:
> >
> > Have you tried it together with the next patch? It adds
> > touchscreen_parse_properties() to initialize axes also from DT, and
> > should be equivalent to the hunk you proposed.
>
> Yes, the touchscreen_parse_properties() takes bool multitouch for the
> argument, and thus, it needs to be applied to both MT/non-MT cases.
>
> https://elixir.bootlin.com/linux/v5.7-rc2/source/drivers/input/touchscreen/of_touchscreen.c#L64

input_mt_init_slots() should copy MT axes to non-MT if they are
described before the call.

With v5 applied, I can see in evtest MT and non-MT events.

Best Regards,
Michał Mirosław

2020-04-27 21:17:03

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v4 10/10] dt-bindings: input: touchscreen: elants_i2c: convert to YAML

On Sun, Apr 26, 2020 at 11:11 AM Michał Mirosław
<[email protected]> wrote:
>
> From: David Heidelberg <[email protected]>
>
> Convert elants_i2c.txt DT binding to YAML and put into correct directory.

Resend to the DT list or this won't be in my review queue. Looks okay
from a quick scan.

Rob

2020-04-28 14:13:04

by Michał Mirosław

[permalink] [raw]
Subject: Re: [PATCH v4 10/10] dt-bindings: input: touchscreen: elants_i2c: convert to YAML

On Mon, Apr 27, 2020 at 04:14:15PM -0500, Rob Herring wrote:
> On Sun, Apr 26, 2020 at 11:11 AM Micha? Miros?aw
> <[email protected]> wrote:
> >
> > From: David Heidelberg <[email protected]>
> >
> > Convert elants_i2c.txt DT binding to YAML and put into correct directory.
>
> Resend to the DT list or this won't be in my review queue. Looks okay
> from a quick scan.

Hi Rob,

This is the same patch that David already sent to the list about
a week ago [1]. Do you need it resent? (Whole patchset or just the patch?)

[1] https://lore.kernel.org/linux-devicetree/[email protected]/

Best Regards,
Micha? Miros?aw

2020-04-29 01:40:29

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v4 10/10] dt-bindings: input: touchscreen: elants_i2c: convert to YAML

28.04.2020 17:08, Michał Mirosław пишет:
> On Mon, Apr 27, 2020 at 04:14:15PM -0500, Rob Herring wrote:
>> On Sun, Apr 26, 2020 at 11:11 AM Michał Mirosław
>> <[email protected]> wrote:
>>>
>>> From: David Heidelberg <[email protected]>
>>>
>>> Convert elants_i2c.txt DT binding to YAML and put into correct directory.
>>
>> Resend to the DT list or this won't be in my review queue. Looks okay
>> from a quick scan.
>
> Hi Rob,
>
> This is the same patch that David already sent to the list about
> a week ago [1]. Do you need it resent? (Whole patchset or just the patch?)
>
> [1] https://lore.kernel.org/linux-devicetree/[email protected]/

The whole patchset should be better.