linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X
@ 2024-05-26 21:24 Oleh Kuzhylnyi
  2024-05-26 21:24 ` [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen Oleh Kuzhylnyi
  2024-05-27  6:09 ` [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Krzysztof Kozlowski
  0 siblings, 2 replies; 4+ messages in thread
From: Oleh Kuzhylnyi @ 2024-05-26 21:24 UTC (permalink / raw)
  To: linux-input
  Cc: dmitry.torokhov, robh, krzk+dt, conor+dt, kuzhylol, devicetree,
	linux-kernel, jeff, neil.armstrong, hdegoede, artur.serhiienko,
	igor.opaniuk

Add documentation for the Hynitron CST816X touchscreen bindings.

Signed-off-by: Oleh Kuzhylnyi <kuzhylol@gmail.com>
---

Changes in v3:
 - Rename filename to hynitron,cst816s.yaml
 - Update description with display details

 .../input/touchscreen/hynitron,cst816s.yaml   | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/hynitron,cst816s.yaml

diff --git a/Documentation/devicetree/bindings/input/touchscreen/hynitron,cst816s.yaml b/Documentation/devicetree/bindings/input/touchscreen/hynitron,cst816s.yaml
new file mode 100644
index 000000000000..ac9f1d8e8fc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/hynitron,cst816s.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/hynitron,cst816s.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hynitron CST816S Touchscreen controller
+
+description:
+  Hynitron CST816S Touchscreen controller for 1.28-inch 240x240 Resolution
+  Touch LCD Display Module
+
+maintainers:
+  - Oleh Kuzhylnyi <kuzhylol@gmail.com>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - hynitron,cst816s
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - reset-gpios
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      touchscreen@15 {
+        compatible = "hynitron,cst816s";
+        reg = <0x15>;
+        interrupt-parent = <&gpio0>;
+        interrupts = <4 IRQ_TYPE_EDGE_RISING>;
+        reset-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+      };
+    };
+
+...
-- 
2.34.1


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

* [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen
  2024-05-26 21:24 [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Oleh Kuzhylnyi
@ 2024-05-26 21:24 ` Oleh Kuzhylnyi
  2024-07-31 19:33   ` Dmitry Torokhov
  2024-05-27  6:09 ` [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Krzysztof Kozlowski
  1 sibling, 1 reply; 4+ messages in thread
From: Oleh Kuzhylnyi @ 2024-05-26 21:24 UTC (permalink / raw)
  To: linux-input
  Cc: dmitry.torokhov, robh, krzk+dt, conor+dt, kuzhylol, devicetree,
	linux-kernel, jeff, neil.armstrong, hdegoede, artur.serhiienko,
	igor.opaniuk

Introduce support for the Hynitron CST816X touchscreen controller
used for 240×240 1.28-inch Round LCD Display Module manufactured
by Waveshare Electronics. The driver is designed based on an Arduino
implementation marked as under MIT License. This driver is written
for a particular round display based on the CST816S controller, which
is not compatiable with existing driver for Hynitron controllers.

Signed-off-by: Oleh Kuzhylnyi <kuzhylol@gmail.com>
---

Changes in v3:
 - Drop timer and delayed work
 - Process touch in threaded IRQ context
 - Fix chip reset sequence
 - Move input_register() before devm_request_threaded_irq()
 - Re-arrange and document input reporting
 - Set u16 data type for event_code
 - Remove double tap event to prevent continuous double side sliding

 drivers/input/touchscreen/Kconfig            |  12 +
 drivers/input/touchscreen/Makefile           |   1 +
 drivers/input/touchscreen/hynitron-cst816x.c | 257 +++++++++++++++++++
 3 files changed, 270 insertions(+)
 create mode 100644 drivers/input/touchscreen/hynitron-cst816x.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c821fe3ee794..02f40d0fbac0 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -481,6 +481,18 @@ config TOUCHSCREEN_HYNITRON_CSTXXX
 	  To compile this driver as a module, choose M here: the
 	  module will be called hynitron-cstxxx.
 
+config TOUCHSCREEN_HYNITRON_CST816X
+	tristate "Hynitron CST816X touchscreen support"
+	depends on I2C
+	help
+	  Say Y here if you have a touchscreen using a Hynitron
+	  CST816X touchscreen controller.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hynitron-cst816x.
+
 config TOUCHSCREEN_ILI210X
 	tristate "Ilitek ILI210X based touchscreen"
 	depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index a81cb5aa21a5..a92a87417a97 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE)	+= goodix_berlin_core.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C)	+= goodix_berlin_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI)	+= goodix_berlin_spi.o
 obj-$(CONFIG_TOUCHSCREEN_HIDEEP)	+= hideep.o
+obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CST816X)	+= hynitron-cst816x.o
 obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX)	+= hynitron_cstxxx.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_ILITEK)	+= ilitek_ts_i2c.o
diff --git a/drivers/input/touchscreen/hynitron-cst816x.c b/drivers/input/touchscreen/hynitron-cst816x.c
new file mode 100644
index 000000000000..5bb85ec1d60e
--- /dev/null
+++ b/drivers/input/touchscreen/hynitron-cst816x.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for I2C connected Hynitron CST816X Touchscreen
+ *
+ * Copyright (C) 2024 Oleh Kuzhylnyi <kuzhylol@gmail.com>
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+enum cst816x_registers {
+	CST816X_FRAME = 0x01,
+	CST816X_MOTION = 0xEC,
+};
+
+enum cst816x_gestures {
+	CST816X_SWIPE_UP = 0x01,
+	CST816X_SWIPE_DOWN = 0x02,
+	CST816X_SWIPE_LEFT = 0x03,
+	CST816X_SWIPE_RIGHT = 0x04,
+	CST816X_SINGLE_TAP = 0x05,
+	CST816X_LONG_PRESS = 0x0C,
+};
+
+struct cst816x_touch_info {
+	u8 gesture;
+	u8 touch;
+	u8 abs_x;
+	u8 abs_y;
+} __packed;
+
+struct cst816x_priv {
+	struct device *dev;
+	struct i2c_client *client;
+	struct gpio_desc *reset;
+	struct input_dev *input;
+	struct cst816x_touch_info info;
+
+	u8 rxtx[8];
+};
+
+struct cst816x_event_mapping {
+	enum cst816x_gestures gesture;
+	u16 event_code;
+};
+
+static const struct cst816x_event_mapping cst816x_event_map[] = {
+	{CST816X_SWIPE_UP, BTN_FORWARD},
+	{CST816X_SWIPE_DOWN, BTN_BACK},
+	{CST816X_SWIPE_LEFT, BTN_LEFT},
+	{CST816X_SWIPE_RIGHT, BTN_RIGHT},
+	{CST816X_SINGLE_TAP, BTN_TOUCH},
+	{CST816X_LONG_PRESS, BTN_TOOL_TRIPLETAP}
+};
+
+static int cst816x_i2c_read_register(struct cst816x_priv *priv, u8 reg)
+{
+	struct i2c_client *client;
+	struct i2c_msg xfer[2];
+	int rc;
+
+	client = priv->client;
+
+	xfer[0].addr = client->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = sizeof(reg);
+	xfer[0].buf = &reg;
+
+	xfer[1].addr = client->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = sizeof(priv->rxtx);
+	xfer[1].buf = priv->rxtx;
+
+	rc = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
+	if (rc != ARRAY_SIZE(xfer)) {
+		if (rc >= 0)
+			rc = -EIO;
+	} else {
+		rc = 0;
+	}
+
+	if (rc < 0)
+		dev_err(&client->dev, "i2c rx err: %d\n", rc);
+
+	return rc;
+}
+
+static int cst816x_process_touch(struct cst816x_priv *priv)
+{
+	u8 *raw;
+	int rc;
+
+	rc = cst816x_i2c_read_register(priv, CST816X_FRAME);
+	if (!rc) {
+		raw = priv->rxtx;
+
+		priv->info.gesture = raw[0];
+		priv->info.touch = raw[1];
+		priv->info.abs_x = ((raw[2] & 0x0F) << 8) | raw[3];
+		priv->info.abs_y = ((raw[4] & 0x0F) << 8) | raw[5];
+
+		dev_dbg(priv->dev, "x: %d, y: %d, t: %d, g: 0x%x\n",
+			priv->info.abs_x, priv->info.abs_y, priv->info.touch,
+			priv->info.gesture);
+	}
+
+	return rc;
+}
+
+static int cst816x_register_input(struct cst816x_priv *priv)
+{
+	priv->input = devm_input_allocate_device(priv->dev);
+	if (!priv->input)
+		return -ENOMEM;
+
+	priv->input->name = "Hynitron CST816X Touchscreen";
+	priv->input->phys = "input/ts";
+	priv->input->id.bustype = BUS_I2C;
+	input_set_drvdata(priv->input, priv);
+
+	for (unsigned int i = 0; i < ARRAY_SIZE(cst816x_event_map); i++) {
+		input_set_capability(priv->input, EV_KEY,
+				     cst816x_event_map[i].event_code);
+	}
+
+	input_set_abs_params(priv->input, ABS_X, 0, 240, 0, 0);
+	input_set_abs_params(priv->input, ABS_Y, 0, 240, 0, 0);
+
+	return input_register_device(priv->input);
+}
+
+static void cst816x_reset(struct cst816x_priv *priv)
+{
+	gpiod_set_value_cansleep(priv->reset, 1);
+	msleep(50);
+	gpiod_set_value_cansleep(priv->reset, 0);
+	msleep(100);
+}
+
+static void report_gesture_event(const struct cst816x_priv *priv,
+				 enum cst816x_gestures gesture, bool touch)
+{
+	for (unsigned int i = 0; i < ARRAY_SIZE(cst816x_event_map); i++) {
+		if (cst816x_event_map[i].gesture == gesture) {
+			input_report_key(priv->input,
+					 cst816x_event_map[i].event_code,
+					 touch);
+			break;
+		}
+	}
+
+	if (!touch)
+		input_report_key(priv->input, BTN_TOUCH, 0);
+}
+
+/*
+ * Supports five gestures: TOUCH, LEFT, RIGHT, FORWARD, BACK, and LONG_PRESS.
+ * Reports surface interaction, sliding coordinates and finger detachment.
+ *
+ * 1. TOUCH Gesture Scenario:
+ *
+ * [x/y] [touch] [gesture] [Action] [Report ABS] [Report Key]
+ *  x y   true    0x00      Touch    ABS_X_Y      BTN_TOUCH
+ *  x y   true    0x00      Slide    ABS_X_Y
+ *  x y   false   0x05      Gesture               BTN_TOUCH
+ *
+ * 2. LEFT, RIGHT, FORWARD, BACK, and LONG_PRESS Gestures Scenario:
+ *
+ * [x/y] [touch] [gesture] [Action] [Report ABS] [Report Key]
+ *  x y   true    0x00      Touch    ABS_X_Y      BTN_TOUCH
+ *  x y   true    0x01      Gesture  ABS_X_Y      BTN_FORWARD
+ *  x y   true    0x01      Slide    ABS_X_Y
+ *  x y   false   0x01      Detach                BTN_FORWARD | BTN_TOUCH
+ */
+static irqreturn_t cst816x_irq_cb(int irq, void *cookie)
+{
+	struct cst816x_priv *priv = (struct cst816x_priv *)cookie;
+
+	if (!cst816x_process_touch(priv)) {
+		if (priv->info.touch) {
+			input_report_abs(priv->input, ABS_X, priv->info.abs_x);
+			input_report_abs(priv->input, ABS_Y, priv->info.abs_y);
+			input_report_key(priv->input, BTN_TOUCH, 1);
+		}
+
+		if (priv->info.gesture)
+			report_gesture_event(priv, priv->info.gesture,
+					     priv->info.touch);
+
+		input_sync(priv->input);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int cst816x_probe(struct i2c_client *client)
+{
+	struct cst816x_priv *priv;
+	struct device *dev = &client->dev;
+	int rc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->client = client;
+
+	priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->reset))
+		return dev_err_probe(dev, PTR_ERR(priv->reset),
+				     "reset gpio not found\n");
+
+	cst816x_reset(priv);
+
+	rc = cst816x_register_input(priv);
+	if (rc)
+		return dev_err_probe(dev, rc, "input register failed\n");
+
+	rc = devm_request_threaded_irq(dev, client->irq, NULL, cst816x_irq_cb,
+				       IRQF_ONESHOT, dev->driver->name, priv);
+	if (rc)
+		return dev_err_probe(dev, rc, "irq request failed\n");
+
+	return 0;
+}
+
+static const struct i2c_device_id cst816x_id[] = {
+	{ .name = "cst816s", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cst816x_id);
+
+static const struct of_device_id cst816x_of_match[] = {
+	{ .compatible = "hynitron,cst816s", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cst816x_of_match);
+
+static struct i2c_driver cst816x_driver = {
+	.driver = {
+		.name = "cst816x",
+		.of_match_table = cst816x_of_match,
+	},
+	.id_table = cst816x_id,
+	.probe = cst816x_probe,
+};
+
+module_i2c_driver(cst816x_driver);
+
+MODULE_AUTHOR("Oleh Kuzhylnyi <kuzhylol@gmail.com>");
+MODULE_DESCRIPTION("Hynitron CST816X Touchscreen Driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


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

* Re: [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X
  2024-05-26 21:24 [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Oleh Kuzhylnyi
  2024-05-26 21:24 ` [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen Oleh Kuzhylnyi
@ 2024-05-27  6:09 ` Krzysztof Kozlowski
  1 sibling, 0 replies; 4+ messages in thread
From: Krzysztof Kozlowski @ 2024-05-27  6:09 UTC (permalink / raw)
  To: Oleh Kuzhylnyi, linux-input
  Cc: dmitry.torokhov, robh, krzk+dt, conor+dt, devicetree,
	linux-kernel, jeff, neil.armstrong, hdegoede, artur.serhiienko,
	igor.opaniuk

On 26/05/2024 23:24, Oleh Kuzhylnyi wrote:
> Add documentation for the Hynitron CST816X touchscreen bindings.
> 
> Signed-off-by: Oleh Kuzhylnyi <kuzhylol@gmail.com>
> ---

This is a friendly reminder during the review process.

It looks like you received a tag and forgot to add it.

If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.

https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577

If a tag was not added on purpose, please state why and what changed.

Best regards,
Krzysztof


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

* Re: [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen
  2024-05-26 21:24 ` [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen Oleh Kuzhylnyi
@ 2024-07-31 19:33   ` Dmitry Torokhov
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Torokhov @ 2024-07-31 19:33 UTC (permalink / raw)
  To: Oleh Kuzhylnyi
  Cc: linux-input, robh, krzk+dt, conor+dt, devicetree, linux-kernel,
	jeff, neil.armstrong, hdegoede, artur.serhiienko, igor.opaniuk

Hi Oleh,

On Sun, May 26, 2024 at 11:24:42PM +0200, Oleh Kuzhylnyi wrote:
> Introduce support for the Hynitron CST816X touchscreen controller
> used for 240×240 1.28-inch Round LCD Display Module manufactured
> by Waveshare Electronics. The driver is designed based on an Arduino
> implementation marked as under MIT License. This driver is written
> for a particular round display based on the CST816S controller, which
> is not compatiable with existing driver for Hynitron controllers.
> 
> Signed-off-by: Oleh Kuzhylnyi <kuzhylol@gmail.com>
> ---
> 
> Changes in v3:
>  - Drop timer and delayed work
>  - Process touch in threaded IRQ context
>  - Fix chip reset sequence
>  - Move input_register() before devm_request_threaded_irq()
>  - Re-arrange and document input reporting
>  - Set u16 data type for event_code
>  - Remove double tap event to prevent continuous double side sliding
> 
>  drivers/input/touchscreen/Kconfig            |  12 +
>  drivers/input/touchscreen/Makefile           |   1 +
>  drivers/input/touchscreen/hynitron-cst816x.c | 257 +++++++++++++++++++
>  3 files changed, 270 insertions(+)
>  create mode 100644 drivers/input/touchscreen/hynitron-cst816x.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index c821fe3ee794..02f40d0fbac0 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -481,6 +481,18 @@ config TOUCHSCREEN_HYNITRON_CSTXXX
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called hynitron-cstxxx.
>  
> +config TOUCHSCREEN_HYNITRON_CST816X
> +	tristate "Hynitron CST816X touchscreen support"
> +	depends on I2C
> +	help
> +	  Say Y here if you have a touchscreen using a Hynitron
> +	  CST816X touchscreen controller.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called hynitron-cst816x.
> +
>  config TOUCHSCREEN_ILI210X
>  	tristate "Ilitek ILI210X based touchscreen"
>  	depends on I2C
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index a81cb5aa21a5..a92a87417a97 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE)	+= goodix_berlin_core.o
>  obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C)	+= goodix_berlin_i2c.o
>  obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI)	+= goodix_berlin_spi.o
>  obj-$(CONFIG_TOUCHSCREEN_HIDEEP)	+= hideep.o
> +obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CST816X)	+= hynitron-cst816x.o
>  obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX)	+= hynitron_cstxxx.o
>  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
>  obj-$(CONFIG_TOUCHSCREEN_ILITEK)	+= ilitek_ts_i2c.o
> diff --git a/drivers/input/touchscreen/hynitron-cst816x.c b/drivers/input/touchscreen/hynitron-cst816x.c
> new file mode 100644
> index 000000000000..5bb85ec1d60e
> --- /dev/null
> +++ b/drivers/input/touchscreen/hynitron-cst816x.c
> @@ -0,0 +1,257 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Driver for I2C connected Hynitron CST816X Touchscreen
> + *
> + * Copyright (C) 2024 Oleh Kuzhylnyi <kuzhylol@gmail.com>
> + */
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +
> +enum cst816x_registers {
> +	CST816X_FRAME = 0x01,
> +	CST816X_MOTION = 0xEC,
> +};
> +
> +enum cst816x_gestures {
> +	CST816X_SWIPE_UP = 0x01,
> +	CST816X_SWIPE_DOWN = 0x02,
> +	CST816X_SWIPE_LEFT = 0x03,
> +	CST816X_SWIPE_RIGHT = 0x04,
> +	CST816X_SINGLE_TAP = 0x05,
> +	CST816X_LONG_PRESS = 0x0C,
> +};
> +
> +struct cst816x_touch_info {
> +	u8 gesture;
> +	u8 touch;
> +	u8 abs_x;

Is this the right size? You are doing:

		priv->info.abs_x = ((raw[2] & 0x0F) << 8) | raw[3];


Which suggests it should be u16?


> +	u8 abs_y;
> +} __packed;

Why does this need to be __packed?

> +
> +struct cst816x_priv {
> +	struct device *dev;
> +	struct i2c_client *client;
> +	struct gpio_desc *reset;
> +	struct input_dev *input;
> +	struct cst816x_touch_info info;

Why do you need to have this here? It is tiny and does not need to be
kept around, just use on stack variable.

> +
> +	u8 rxtx[8];
> +};
> +
> +struct cst816x_event_mapping {
> +	enum cst816x_gestures gesture;
> +	u16 event_code;
> +};
> +
> +static const struct cst816x_event_mapping cst816x_event_map[] = {
> +	{CST816X_SWIPE_UP, BTN_FORWARD},
> +	{CST816X_SWIPE_DOWN, BTN_BACK},
> +	{CST816X_SWIPE_LEFT, BTN_LEFT},
> +	{CST816X_SWIPE_RIGHT, BTN_RIGHT},
> +	{CST816X_SINGLE_TAP, BTN_TOUCH},
> +	{CST816X_LONG_PRESS, BTN_TOOL_TRIPLETAP}
> +};
> +
> +static int cst816x_i2c_read_register(struct cst816x_priv *priv, u8 reg)

Maybe supply buffer and size as arguments?

> +{
> +	struct i2c_client *client;
> +	struct i2c_msg xfer[2];
> +	int rc;
> +
> +	client = priv->client;
> +
> +	xfer[0].addr = client->addr;
> +	xfer[0].flags = 0;
> +	xfer[0].len = sizeof(reg);
> +	xfer[0].buf = &reg;
> +
> +	xfer[1].addr = client->addr;
> +	xfer[1].flags = I2C_M_RD;
> +	xfer[1].len = sizeof(priv->rxtx);
> +	xfer[1].buf = priv->rxtx;
> +
> +	rc = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
> +	if (rc != ARRAY_SIZE(xfer)) {
		error = rc >= 0 ? -EIO : rc;
		dev_err(...);
		return error;
	}

	return 0;

> +		if (rc >= 0)
> +			rc = -EIO;
> +	} else {
> +		rc = 0;
> +	}
> +
> +	if (rc < 0)
> +		dev_err(&client->dev, "i2c rx err: %d\n", rc);
> +
> +	return rc;
> +}
> +
> +static int cst816x_process_touch(struct cst816x_priv *priv)
> +{
> +	u8 *raw;
> +	int rc;
> +
> +	rc = cst816x_i2c_read_register(priv, CST816X_FRAME);
> +	if (!rc) {
> +		raw = priv->rxtx;
> +
> +		priv->info.gesture = raw[0];
> +		priv->info.touch = raw[1];
> +		priv->info.abs_x = ((raw[2] & 0x0F) << 8) | raw[3];
> +		priv->info.abs_y = ((raw[4] & 0x0F) << 8) | raw[5];
> +
> +		dev_dbg(priv->dev, "x: %d, y: %d, t: %d, g: 0x%x\n",
> +			priv->info.abs_x, priv->info.abs_y, priv->info.touch,
> +			priv->info.gesture);
> +	}
> +
> +	return rc;
> +}
> +
> +static int cst816x_register_input(struct cst816x_priv *priv)
> +{
> +	priv->input = devm_input_allocate_device(priv->dev);
> +	if (!priv->input)
> +		return -ENOMEM;
> +
> +	priv->input->name = "Hynitron CST816X Touchscreen";
> +	priv->input->phys = "input/ts";
> +	priv->input->id.bustype = BUS_I2C;
> +	input_set_drvdata(priv->input, priv);
> +
> +	for (unsigned int i = 0; i < ARRAY_SIZE(cst816x_event_map); i++) {
> +		input_set_capability(priv->input, EV_KEY,
> +				     cst816x_event_map[i].event_code);
> +	}
> +
> +	input_set_abs_params(priv->input, ABS_X, 0, 240, 0, 0);
> +	input_set_abs_params(priv->input, ABS_Y, 0, 240, 0, 0);
> +
> +	return input_register_device(priv->input);
> +}
> +
> +static void cst816x_reset(struct cst816x_priv *priv)
> +{
> +	gpiod_set_value_cansleep(priv->reset, 1);
> +	msleep(50);
> +	gpiod_set_value_cansleep(priv->reset, 0);
> +	msleep(100);
> +}
> +
> +static void report_gesture_event(const struct cst816x_priv *priv,
> +				 enum cst816x_gestures gesture, bool touch)
> +{
> +	for (unsigned int i = 0; i < ARRAY_SIZE(cst816x_event_map); i++) {
> +		if (cst816x_event_map[i].gesture == gesture) {
> +			input_report_key(priv->input,
> +					 cst816x_event_map[i].event_code,
> +					 touch);

If you make cst816x_event_map an array of 16 entries with unised
positions mapped to KEY_RESERVED you can do:

	key = cst816x_event_map[raw[0] & 0x0f];
	if (key != KEY_RESERVED)
		input_report_key(priv->input, key, touch);

and you do not need to loop.

Thanks.

-- 
Dmitry

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

end of thread, other threads:[~2024-07-31 19:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-26 21:24 [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Oleh Kuzhylnyi
2024-05-26 21:24 ` [PATCH v3 2/2] input: add driver for Hynitron CST816X touchscreen Oleh Kuzhylnyi
2024-07-31 19:33   ` Dmitry Torokhov
2024-05-27  6:09 ` [PATCH v3 1/2] dt-bindings: input: touchscreen: add Hynitron CST816X Krzysztof Kozlowski

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