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@xxxxxxxxxxxxxxxxx> --- 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 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -26,6 +26,27 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@xxxxxx>"); 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); -- 2.27.0