* [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 = ®
+
+ 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 = ®
> +
> + 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.