linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] Face lift for st1232 touchscreen driver
@ 2019-10-22 19:56 Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 1/8] Input: st1232 - simplify parsing of read buffer Dmitry Torokhov
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Henrik Rydberg, Kuninori Morimoto, Matthias Fend,
	linux-input, linux-kernel

This series cleans up the driver and switches it over to the slotted
multi-touch protocol (MT-B) that should reduce the traffic between kernel
and userspace.

Note that I do not have hardware, so I would appreciate if you could try
running it and tell me if it is broken or not.

Thanks!


Dmitry Torokhov (8):
  Input: st1232 - simplify parsing of read buffer
  Input: st1232 - do not unconditionally configure as wakeup source
  Input: st1232 - rely on I2C core to configure wakeup interrupt
  Input: st1232 - do not reset the chip too early
  Input: st1232 - do not allocate fingers data separately
  Input: st1232 - do not set parent device explicitly
  Input: st1232 - note that the receive buffer is DMA-safe
  Input: st1232 - switch to using MT-B protocol

 drivers/input/touchscreen/st1232.c | 184 ++++++++++++++---------------
 1 file changed, 89 insertions(+), 95 deletions(-)

-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] Input: st1232 - simplify parsing of read buffer
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 2/8] Input: st1232 - do not unconditionally configure as wakeup source Dmitry Torokhov
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

Avoid complex 2-variable loop when parsing touchscreen data to make the
code clearer.

Acked-by: Martin Kepplinger <martink@posteo.de>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 50 +++++++++++++++---------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index 1139714e72e2..47033ef3749a 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -57,38 +57,38 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts)
 {
 	struct st1232_ts_finger *finger = ts->finger;
 	struct i2c_client *client = ts->client;
-	struct i2c_msg msg[2];
-	int error;
-	int i, y;
 	u8 start_reg = ts->chip_info->start_reg;
-	u8 *buf = ts->read_buf;
-
-	/* read touchscreen data */
-	msg[0].addr = client->addr;
-	msg[0].flags = 0;
-	msg[0].len = 1;
-	msg[0].buf = &start_reg;
-
-	msg[1].addr = ts->client->addr;
-	msg[1].flags = I2C_M_RD;
-	msg[1].len = ts->read_buf_len;
-	msg[1].buf = buf;
+	struct i2c_msg msg[] = {
+		{
+			.addr	= client->addr,
+			.len	= sizeof(start_reg),
+			.buf	= &start_reg,
+		},
+		{
+			.addr	= client->addr,
+			.flags	= I2C_M_RD,
+			.len	= ts->read_buf_len,
+			.buf	= ts->read_buf,
+		}
+	};
+	int ret;
+	int i;
+	u8 *buf;
 
-	error = i2c_transfer(client->adapter, msg, 2);
-	if (error < 0)
-		return error;
+	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+	if (ret != ARRAY_SIZE(msg))
+		return ret < 0 ? ret : -EIO;
 
-	for (i = 0, y = 0; i < ts->chip_info->max_fingers; i++, y += 3) {
-		finger[i].is_valid = buf[i + y] >> 7;
+	for (i = 0; i < ts->chip_info->max_fingers; i++) {
+		buf = &ts->read_buf[i * 4];
+		finger[i].is_valid = buf[0] >> 7;
 		if (finger[i].is_valid) {
-			finger[i].x = ((buf[i + y] & 0x0070) << 4) |
-					buf[i + y + 1];
-			finger[i].y = ((buf[i + y] & 0x0007) << 8) |
-					buf[i + y + 2];
+			finger[i].x = ((buf[0] & 0x70) << 4) | buf[1];
+			finger[i].y = ((buf[0] & 0x07) << 8) | buf[2];
 
 			/* st1232 includes a z-axis / touch strength */
 			if (ts->chip_info->have_z)
-				finger[i].t = buf[i + 6];
+				finger[i].t = ts->read_buf[i + 6];
 		}
 	}
 
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] Input: st1232 - do not unconditionally configure as wakeup source
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 1/8] Input: st1232 - simplify parsing of read buffer Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 3/8] Input: st1232 - rely on I2C core to configure wakeup interrupt Dmitry Torokhov
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

Do not unconditionally configure the touchscreen as wakeup source but
rather rely on I2C core to do that when requested (either via
"wakeup-source" device property, or when creating a client with
I2C_CLIENT_WAKE flag).

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index 47033ef3749a..f1b97075aa9b 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -266,7 +266,6 @@ static int st1232_ts_probe(struct i2c_client *client,
 	}
 
 	i2c_set_clientdata(client, ts);
-	device_init_wakeup(&client->dev, 1);
 
 	return 0;
 }
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] Input: st1232 - rely on I2C core to configure wakeup interrupt
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 1/8] Input: st1232 - simplify parsing of read buffer Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 2/8] Input: st1232 - do not unconditionally configure as wakeup source Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 4/8] Input: st1232 - do not reset the chip too early Dmitry Torokhov
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

When I2C client is created with I2C_CLIENT_WAKE flag (which happens
either because we have "wakeup-source" device property or the flag
was passed in when creating an I2C client manually), I2C core will
take care of configuring interrupt as wakeup source on suspend.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index f1b97075aa9b..bb116f41f1c0 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -284,12 +284,10 @@ static int __maybe_unused st1232_ts_suspend(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct st1232_ts_data *ts = i2c_get_clientdata(client);
 
-	if (device_may_wakeup(&client->dev)) {
-		enable_irq_wake(client->irq);
-	} else {
-		disable_irq(client->irq);
+	disable_irq(client->irq);
+
+	if (!device_may_wakeup(&client->dev))
 		st1232_ts_power(ts, false);
-	}
 
 	return 0;
 }
@@ -299,12 +297,10 @@ static int __maybe_unused st1232_ts_resume(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct st1232_ts_data *ts = i2c_get_clientdata(client);
 
-	if (device_may_wakeup(&client->dev)) {
-		disable_irq_wake(client->irq);
-	} else {
+	if (!device_may_wakeup(&client->dev))
 		st1232_ts_power(ts, true);
-		enable_irq(client->irq);
-	}
+
+	enable_irq(client->irq);
 
 	return 0;
 }
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] Input: st1232 - do not reset the chip too early
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (2 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 3/8] Input: st1232 - rely on I2C core to configure wakeup interrupt Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 5/8] Input: st1232 - do not allocate fingers data separately Dmitry Torokhov
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

We should not be putting the chip into reset while interrupts are enabled
and ISR may be running. Fix this by installing a custom devm action and
powering off the device/resetting GPIO line from there. This ensures proper
ordering.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index bb116f41f1c0..bfea02202ded 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -149,6 +149,11 @@ static void st1232_ts_power(struct st1232_ts_data *ts, bool poweron)
 		gpiod_set_value_cansleep(ts->reset_gpio, !poweron);
 }
 
+static void st1232_ts_power_off(void *data)
+{
+	st1232_ts_power(data, false);
+}
+
 static const struct st_chip_info st1232_chip_info = {
 	.have_z		= true,
 	.max_x		= 0x31f, /* 800 - 1 */
@@ -229,6 +234,13 @@ static int st1232_ts_probe(struct i2c_client *client,
 
 	st1232_ts_power(ts, true);
 
+	error = devm_add_action_or_reset(&client->dev, st1232_ts_power_off, ts);
+	if (error) {
+		dev_err(&client->dev,
+			"Failed to install power off action: %d\n", error);
+		return error;
+	}
+
 	input_dev->name = "st1232-touchscreen";
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->dev.parent = &client->dev;
@@ -270,15 +282,6 @@ static int st1232_ts_probe(struct i2c_client *client,
 	return 0;
 }
 
-static int st1232_ts_remove(struct i2c_client *client)
-{
-	struct st1232_ts_data *ts = i2c_get_clientdata(client);
-
-	st1232_ts_power(ts, false);
-
-	return 0;
-}
-
 static int __maybe_unused st1232_ts_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -324,7 +327,6 @@ MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
 
 static struct i2c_driver st1232_ts_driver = {
 	.probe		= st1232_ts_probe,
-	.remove		= st1232_ts_remove,
 	.id_table	= st1232_ts_id,
 	.driver = {
 		.name	= ST1232_TS_NAME,
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] Input: st1232 - do not allocate fingers data separately
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (3 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 4/8] Input: st1232 - do not reset the chip too early Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 6/8] Input: st1232 - do not set parent device explicitly Dmitry Torokhov
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

The finger structure size is quite small and allocating it together with
the main driver structure will not increase likelihood of allocation
failing, but reduces number of objects needing to be tracked by the
allocator and devm.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index bfea02202ded..dfc0c6cb0213 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -50,12 +50,12 @@ struct st1232_ts_data {
 	const struct st_chip_info *chip_info;
 	int read_buf_len;
 	u8 *read_buf;
-	struct st1232_ts_finger *finger;
+	struct st1232_ts_finger fingers[];
 };
 
 static int st1232_ts_read_data(struct st1232_ts_data *ts)
 {
-	struct st1232_ts_finger *finger = ts->finger;
+	struct st1232_ts_finger *finger = ts->fingers;
 	struct i2c_client *client = ts->client;
 	u8 start_reg = ts->chip_info->start_reg;
 	struct i2c_msg msg[] = {
@@ -98,7 +98,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts)
 static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
 {
 	struct st1232_ts_data *ts = dev_id;
-	struct st1232_ts_finger *finger = ts->finger;
+	struct st1232_ts_finger *finger = ts->fingers;
 	struct input_dev *input_dev = ts->input_dev;
 	int count = 0;
 	int i, ret;
@@ -177,7 +177,6 @@ static int st1232_ts_probe(struct i2c_client *client,
 {
 	const struct st_chip_info *match;
 	struct st1232_ts_data *ts;
-	struct st1232_ts_finger *finger;
 	struct input_dev *input_dev;
 	int error;
 
@@ -199,16 +198,13 @@ static int st1232_ts_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
+	ts = devm_kzalloc(&client->dev,
+			  struct_size(ts, fingers, match->max_fingers),
+			  GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
 
 	ts->chip_info = match;
-	ts->finger = devm_kcalloc(&client->dev,
-				  ts->chip_info->max_fingers, sizeof(*finger),
-				  GFP_KERNEL);
-	if (!ts->finger)
-		return -ENOMEM;
 
 	/* allocate a buffer according to the number of registers to read */
 	ts->read_buf_len = ts->chip_info->max_fingers * 4;
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] Input: st1232 - do not set parent device explicitly
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (4 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 5/8] Input: st1232 - do not allocate fingers data separately Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 7/8] Input: st1232 - note that the receive buffer is DMA-safe Dmitry Torokhov
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

devm_input_allocate_device() already sets parent device for us.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index dfc0c6cb0213..0aee330731c9 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -239,7 +239,6 @@ static int st1232_ts_probe(struct i2c_client *client,
 
 	input_dev->name = "st1232-touchscreen";
 	input_dev->id.bustype = BUS_I2C;
-	input_dev->dev.parent = &client->dev;
 
 	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
 	__set_bit(EV_SYN, input_dev->evbit);
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] Input: st1232 - note that the receive buffer is DMA-safe
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (5 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 6/8] Input: st1232 - do not set parent device explicitly Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-22 19:56 ` [PATCH 8/8] Input: st1232 - switch to using MT-B protocol Dmitry Torokhov
  2019-10-28  7:28 ` AW: [PATCH 0/8] Face lift for st1232 touchscreen driver Matthias Fend
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Kuninori Morimoto, Matthias Fend, linux-input,
	linux-kernel

The receiving buffer is allocated separately from the main driver
data structure, and is naturally DMA-safe, so mark it as such when
building I2C transfer message.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

 drivers/input/touchscreen/st1232.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index 0aee330731c9..a4a3b82ee69d 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -66,7 +66,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts)
 		},
 		{
 			.addr	= client->addr,
-			.flags	= I2C_M_RD,
+			.flags	= I2C_M_RD | I2C_M_DMA_SAFE,
 			.len	= ts->read_buf_len,
 			.buf	= ts->read_buf,
 		}
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] Input: st1232 - switch to using MT-B protocol
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (6 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 7/8] Input: st1232 - note that the receive buffer is DMA-safe Dmitry Torokhov
@ 2019-10-22 19:56 ` Dmitry Torokhov
  2019-10-28  7:28 ` AW: [PATCH 0/8] Face lift for st1232 touchscreen driver Matthias Fend
  8 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-22 19:56 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Dixit Parmar, Henrik Rydberg, Kuninori Morimoto, Matthias Fend,
	linux-input, linux-kernel

Switch the driver to the slotted variant of multitouch protocol (MT-B)
with in-kernel tracking of the contacts.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

---

 drivers/input/touchscreen/st1232.c | 110 +++++++++++++++--------------
 1 file changed, 56 insertions(+), 54 deletions(-)

diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index a4a3b82ee69d..63b29c7279e2 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -14,23 +14,19 @@
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm_qos.h>
 #include <linux/slab.h>
 #include <linux/types.h>
-#include <linux/input/touchscreen.h>
 
 #define ST1232_TS_NAME	"st1232-ts"
 #define ST1633_TS_NAME	"st1633-ts"
 
-struct st1232_ts_finger {
-	u16 x;
-	u16 y;
-	u8 t;
-	bool is_valid;
-};
+#define ST_TS_MAX_FINGERS	10
 
 struct st_chip_info {
 	bool	have_z;
@@ -50,12 +46,10 @@ struct st1232_ts_data {
 	const struct st_chip_info *chip_info;
 	int read_buf_len;
 	u8 *read_buf;
-	struct st1232_ts_finger fingers[];
 };
 
 static int st1232_ts_read_data(struct st1232_ts_data *ts)
 {
-	struct st1232_ts_finger *finger = ts->fingers;
 	struct i2c_client *client = ts->client;
 	u8 start_reg = ts->chip_info->start_reg;
 	struct i2c_msg msg[] = {
@@ -72,59 +66,69 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts)
 		}
 	};
 	int ret;
-	int i;
-	u8 *buf;
 
 	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
 	if (ret != ARRAY_SIZE(msg))
 		return ret < 0 ? ret : -EIO;
 
+	return 0;
+}
+
+static int st1232_ts_parse_and_report(struct st1232_ts_data *ts)
+{
+	struct input_dev *input = ts->input_dev;
+	struct input_mt_pos pos[ST_TS_MAX_FINGERS];
+	u8 z[ST_TS_MAX_FINGERS];
+	int slots[ST_TS_MAX_FINGERS];
+	int n_contacts = 0;
+	int i;
+
 	for (i = 0; i < ts->chip_info->max_fingers; i++) {
-		buf = &ts->read_buf[i * 4];
-		finger[i].is_valid = buf[0] >> 7;
-		if (finger[i].is_valid) {
-			finger[i].x = ((buf[0] & 0x70) << 4) | buf[1];
-			finger[i].y = ((buf[0] & 0x07) << 8) | buf[2];
+		u8 *buf = &ts->read_buf[i * 4];
+
+		if (buf[0] & BIT(7)) {
+			unsigned int x = ((buf[0] & 0x70) << 4) | buf[1];
+			unsigned int y = ((buf[0] & 0x07) << 8) | buf[2];
+
+			touchscreen_set_mt_pos(&pos[n_contacts],
+					       &ts->prop, x, y);
 
 			/* st1232 includes a z-axis / touch strength */
 			if (ts->chip_info->have_z)
-				finger[i].t = ts->read_buf[i + 6];
+				z[n_contacts] = ts->read_buf[i + 6];
+
+			n_contacts++;
 		}
 	}
 
-	return 0;
+	input_mt_assign_slots(input, slots, pos, n_contacts, 0);
+	for (i = 0; i < n_contacts; i++) {
+		input_mt_slot(input, slots[i]);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+		input_report_abs(input, ABS_MT_POSITION_X, pos[i].x);
+		input_report_abs(input, ABS_MT_POSITION_Y, pos[i].y);
+		if (ts->chip_info->have_z)
+			input_report_abs(input, ABS_MT_TOUCH_MAJOR, z[i]);
+	}
+
+	input_mt_sync_frame(input);
+	input_sync(input);
+
+	return n_contacts;
 }
 
 static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
 {
 	struct st1232_ts_data *ts = dev_id;
-	struct st1232_ts_finger *finger = ts->fingers;
-	struct input_dev *input_dev = ts->input_dev;
-	int count = 0;
-	int i, ret;
-
-	ret = st1232_ts_read_data(ts);
-	if (ret < 0)
-		goto end;
-
-	/* multi touch protocol */
-	for (i = 0; i < ts->chip_info->max_fingers; i++) {
-		if (!finger[i].is_valid)
-			continue;
+	int count;
+	int error;
 
-		if (ts->chip_info->have_z)
-			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
-					 finger[i].t);
+	error = st1232_ts_read_data(ts);
+	if (error)
+		goto out;
 
-		touchscreen_report_pos(input_dev, &ts->prop,
-					finger[i].x, finger[i].y, true);
-		input_mt_sync(input_dev);
-		count++;
-	}
-
-	/* SYN_MT_REPORT only if no contact */
+	count = st1232_ts_parse_and_report(ts);
 	if (!count) {
-		input_mt_sync(input_dev);
 		if (ts->low_latency_req.dev) {
 			dev_pm_qos_remove_request(&ts->low_latency_req);
 			ts->low_latency_req.dev = NULL;
@@ -136,10 +140,7 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
 						DEV_PM_QOS_RESUME_LATENCY, 100);
 	}
 
-	/* SYN_REPORT */
-	input_sync(input_dev);
-
-end:
+out:
 	return IRQ_HANDLED;
 }
 
@@ -198,9 +199,7 @@ static int st1232_ts_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	ts = devm_kzalloc(&client->dev,
-			  struct_size(ts, fingers, match->max_fingers),
-			  GFP_KERNEL);
+	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
 
@@ -240,11 +239,6 @@ static int st1232_ts_probe(struct i2c_client *client,
 	input_dev->name = "st1232-touchscreen";
 	input_dev->id.bustype = BUS_I2C;
 
-	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
-	__set_bit(EV_SYN, input_dev->evbit);
-	__set_bit(EV_KEY, input_dev->evbit);
-	__set_bit(EV_ABS, input_dev->evbit);
-
 	if (ts->chip_info->have_z)
 		input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
 				     ts->chip_info->max_area, 0, 0);
@@ -256,6 +250,14 @@ static int st1232_ts_probe(struct i2c_client *client,
 
 	touchscreen_parse_properties(input_dev, true, &ts->prop);
 
+	error = input_mt_init_slots(input_dev, ts->chip_info->max_fingers,
+				    INPUT_MT_DIRECT | INPUT_MT_TRACK |
+					INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(&client->dev, "failed to initialize MT slots\n");
+		return error;
+	}
+
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, st1232_ts_irq_handler,
 					  IRQF_ONESHOT,
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* AW: [PATCH 0/8] Face lift for st1232 touchscreen driver
  2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
                   ` (7 preceding siblings ...)
  2019-10-22 19:56 ` [PATCH 8/8] Input: st1232 - switch to using MT-B protocol Dmitry Torokhov
@ 2019-10-28  7:28 ` Matthias Fend
  2019-10-29  4:09   ` Dmitry Torokhov
  8 siblings, 1 reply; 11+ messages in thread
From: Matthias Fend @ 2019-10-28  7:28 UTC (permalink / raw)
  To: Dmitry Torokhov, Martin Kepplinger
  Cc: Dixit Parmar, Henrik Rydberg, Kuninori Morimoto, linux-input,
	linux-kernel

Hi Dmitry,

> -----Ursprüngliche Nachricht-----
> Von: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Gesendet: Dienstag, 22. Oktober 2019 21:56
> An: Martin Kepplinger <martink@posteo.de>
> Cc: Dixit Parmar <dixitparmar19@gmail.com>; Henrik Rydberg
> <rydberg@bitmath.org>; Kuninori Morimoto
> <kuninori.morimoto.gx@renesas.com>; Matthias Fend
> <Matthias.Fend@wolfvision.net>; linux-input@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Betreff: [PATCH 0/8] Face lift for st1232 touchscreen driver
> 
> This series cleans up the driver and switches it over to the slotted
> multi-touch protocol (MT-B) that should reduce the traffic between kernel
> and userspace.
> 
> Note that I do not have hardware, so I would appreciate if you could try
> running it and tell me if it is broken or not.

Looks good. I tested the series from your st1232 branch [1] and could not see any regressions.
Note that I my 'real' application only supports ONE finger. So, the other fingers are just tested with debug output.

Thanks,
 ~Matthias

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

> 
> Thanks!
> 
> 
> Dmitry Torokhov (8):
>   Input: st1232 - simplify parsing of read buffer
>   Input: st1232 - do not unconditionally configure as wakeup source
>   Input: st1232 - rely on I2C core to configure wakeup interrupt
>   Input: st1232 - do not reset the chip too early
>   Input: st1232 - do not allocate fingers data separately
>   Input: st1232 - do not set parent device explicitly
>   Input: st1232 - note that the receive buffer is DMA-safe
>   Input: st1232 - switch to using MT-B protocol
> 
>  drivers/input/touchscreen/st1232.c | 184 ++++++++++++++---------------
>  1 file changed, 89 insertions(+), 95 deletions(-)
> 
> --
> 2.23.0.866.gb869b98d4c-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/8] Face lift for st1232 touchscreen driver
  2019-10-28  7:28 ` AW: [PATCH 0/8] Face lift for st1232 touchscreen driver Matthias Fend
@ 2019-10-29  4:09   ` Dmitry Torokhov
  0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2019-10-29  4:09 UTC (permalink / raw)
  To: Matthias Fend
  Cc: Martin Kepplinger, Dixit Parmar, Henrik Rydberg,
	Kuninori Morimoto, linux-input, linux-kernel

On Mon, Oct 28, 2019 at 07:28:51AM +0000, Matthias Fend wrote:
> Hi Dmitry,
> 
> > -----Ursprüngliche Nachricht-----
> > Von: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > Gesendet: Dienstag, 22. Oktober 2019 21:56
> > An: Martin Kepplinger <martink@posteo.de>
> > Cc: Dixit Parmar <dixitparmar19@gmail.com>; Henrik Rydberg
> > <rydberg@bitmath.org>; Kuninori Morimoto
> > <kuninori.morimoto.gx@renesas.com>; Matthias Fend
> > <Matthias.Fend@wolfvision.net>; linux-input@vger.kernel.org; linux-
> > kernel@vger.kernel.org
> > Betreff: [PATCH 0/8] Face lift for st1232 touchscreen driver
> > 
> > This series cleans up the driver and switches it over to the slotted
> > multi-touch protocol (MT-B) that should reduce the traffic between kernel
> > and userspace.
> > 
> > Note that I do not have hardware, so I would appreciate if you could try
> > running it and tell me if it is broken or not.
> 
> Looks good. I tested the series from your st1232 branch [1] and could not see any regressions.
> Note that I my 'real' application only supports ONE finger. So, the other fingers are just tested with debug output.

Thank you for testing. I committed the patches.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-10-29  4:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-22 19:56 [PATCH 0/8] Face lift for st1232 touchscreen driver Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 1/8] Input: st1232 - simplify parsing of read buffer Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 2/8] Input: st1232 - do not unconditionally configure as wakeup source Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 3/8] Input: st1232 - rely on I2C core to configure wakeup interrupt Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 4/8] Input: st1232 - do not reset the chip too early Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 5/8] Input: st1232 - do not allocate fingers data separately Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 6/8] Input: st1232 - do not set parent device explicitly Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 7/8] Input: st1232 - note that the receive buffer is DMA-safe Dmitry Torokhov
2019-10-22 19:56 ` [PATCH 8/8] Input: st1232 - switch to using MT-B protocol Dmitry Torokhov
2019-10-28  7:28 ` AW: [PATCH 0/8] Face lift for st1232 touchscreen driver Matthias Fend
2019-10-29  4:09   ` Dmitry Torokhov

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).