diff mbox series

Add support for touch screens using the General Touch ST6001S controller.

Message ID 4c792c2e-9de3-4faa-9948-47ddae77640e@virgin.net (mailing list archive)
State New, archived
Headers show
Series Add support for touch screens using the General Touch ST6001S controller. | expand

Commit Message

Gareth Randall Oct. 25, 2023, 3:51 p.m. UTC
Add support for touch screens using the General Touch ST6001S controller,
as found in the GPEG model AOD22WZ-ST monitor. This controller can output
the ELO 10-byte protocol, but requires different initialisation.

Signed-off-by: Gareth Randall <gareth@garethrandall.com>
---
  drivers/input/touchscreen/elo.c | 81 ++++++++++++++++++++++++++++++++-
  1 file changed, 80 insertions(+), 1 deletion(-)

Comments

Gareth Randall Nov. 9, 2023, 4:13 p.m. UTC | #1
Dear Benjamin and Dmitry,

I wonder if you have had a chance to look at this patch. It was resubmitted on 3rd Oct 2023 then 
again to make it appear in Patchwork properly. This is my first patch so any feedback on both the 
patch and whether I'm following the process properly would be very useful.

Thanks very much.

Yours,

Gareth

On 25/10/2023 16:51, Gareth Randall wrote:
> Add support for touch screens using the General Touch ST6001S controller,
> as found in the GPEG model AOD22WZ-ST monitor. This controller can output
> the ELO 10-byte protocol, but requires different initialisation.
> 
> Signed-off-by: Gareth Randall <gareth@garethrandall.com>
> ---
>   drivers/input/touchscreen/elo.c | 81 ++++++++++++++++++++++++++++++++-
>   1 file changed, 80 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
> index 96173232e53f..b233869ffa2a 100644
[snip]
diff mbox series

Patch

diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 96173232e53f..b233869ffa2a 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -26,6 +26,27 @@  MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  MODULE_DESCRIPTION(DRIVER_DESC);
  MODULE_LICENSE("GPL");

+static uint gt_abs_x_min;
+module_param(gt_abs_x_min, uint, 0444);
+MODULE_PARM_DESC(gt_abs_x_min, "abs_x min value in General Touch mode (default: 0)");
+
+static uint gt_abs_x_max = 4095;
+module_param(gt_abs_x_max, uint, 0444);
+MODULE_PARM_DESC(gt_abs_x_max, "abs_x max value in General Touch mode (default: 4095)");
+
+static uint gt_abs_y_min;
+module_param(gt_abs_y_min, uint, 0444);
+MODULE_PARM_DESC(gt_abs_y_min, "abs_y min value in General Touch mode (default: 0)");
+
+static uint gt_abs_y_max = 4095;
+module_param(gt_abs_y_max, uint, 0444);
+MODULE_PARM_DESC(gt_abs_y_max, "abs_y max value in General Touch mode (default: 4095)");
+
+static bool gt_mode_override;
+module_param(gt_mode_override, bool, 0444);
+MODULE_PARM_DESC(gt_mode_override, "force the use of General Touch mode (default: false)");
+
+
  /*
   * Definitions & global arrays.
   */
@@ -44,6 +65,8 @@  MODULE_LICENSE("GPL");
  #define ELO10_ACK_PACKET	'A'
  #define ELI10_ID_PACKET		'I'

+#define ELO_GT_INIT_PACKET	"\001XfE\r"
+
  /*
   * Per-touchscreen data.
   */
@@ -201,6 +224,7 @@  static irqreturn_t elo_interrupt(struct serio *serio,

  	switch (elo->id) {
  	case 0:
+	case 4:
  		elo_process_data_10(elo, data);
  		break;

@@ -255,6 +279,50 @@  static int elo_command_10(struct elo *elo, unsigned char *packet)
  	return rc;
  }

+/*
+ * Initialise the General Touch ST6001S controller.
+ */
+static int elo_command_10_gt(struct elo *elo)
+{
+	int rc = -1;
+	int i;
+	unsigned char *packet = ELO_GT_INIT_PACKET;
+
+	mutex_lock(&elo->cmd_mutex);
+
+	serio_pause_rx(elo->serio);
+	init_completion(&elo->cmd_done);
+	serio_continue_rx(elo->serio);
+
+	for (i = 0; i < (int)strlen(packet); i++) {
+		if (serio_write(elo->serio, packet[i]))
+			goto out;
+	}
+
+	wait_for_completion_timeout(&elo->cmd_done, HZ);
+	rc = 0;
+
+ out:
+	mutex_unlock(&elo->cmd_mutex);
+	return rc;
+}
+
+static int elo_setup_10_gt(struct elo *elo)
+{
+	struct input_dev *dev = elo->dev;
+
+	if (elo_command_10_gt(elo))
+		return -EIO;
+
+	input_set_abs_params(dev, ABS_X, gt_abs_x_min, gt_abs_x_max, 0, 0);
+	input_set_abs_params(dev, ABS_Y, gt_abs_y_min, gt_abs_y_max, 0, 0);
+
+	dev_info(&elo->serio->dev,
+		 "GeneralTouch ST6001S touchscreen");
+
+	return 0;
+}
+
  static int elo_setup_10(struct elo *elo)
  {
  	static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
@@ -273,7 +341,7 @@  static int elo_setup_10(struct elo *elo)

  	dev_info(&elo->serio->dev,
  		 "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n",
-		 elo_types[(packet[1] -'0') & 0x03],
+		 elo_types[(packet[1] - '0') & 0x03],
  		 packet[5], packet[4], packet[3], packet[7]);

  	return 0;
@@ -332,12 +400,16 @@  static int elo_connect(struct serio *serio, struct serio_driver *drv)

  	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

  	serio_set_drvdata(serio, elo);
  	err = serio_open(serio, drv);
  	if (err)
  		goto fail2;

+	if (gt_mode_override)
+		elo->id = 4;
+
  	switch (elo->id) {

  	case 0: /* 10-byte protocol */
@@ -361,6 +433,13 @@  static int elo_connect(struct serio *serio, struct serio_driver *drv)
  		input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
  		input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
  		break;
+
+	case 4: /* 10-byte protocol with General Touch initialisation */
+		if (elo_setup_10_gt(elo)) {
+			err = -EIO;
+			goto fail3;
+		}
+		break;
  	}

  	err = input_register_device(elo->dev);