From patchwork Tue Dec 15 11:22:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?QsO2c3rDtnJtw6lueWkgWm9sdMOhbg==?= X-Patchwork-Id: 7853921 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 72576BEEE1 for ; Tue, 15 Dec 2015 11:44:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2C1C6202EC for ; Tue, 15 Dec 2015 11:44:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C06012025A for ; Tue, 15 Dec 2015 11:44:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965010AbbLOLoX (ORCPT ); Tue, 15 Dec 2015 06:44:23 -0500 Received: from mail9.pr.hu ([87.242.0.9]:60413 "EHLO mail9.pr.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964922AbbLOLoV (ORCPT ); Tue, 15 Dec 2015 06:44:21 -0500 X-Greylist: delayed 1316 seconds by postgrey-1.27 at vger.kernel.org; Tue, 15 Dec 2015 06:44:20 EST Received: from [2a02:808:3:101::5] (helo=mail.pr.hu) by frontdoor.pr.hu with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1a8ngU-000086-4x; Tue, 15 Dec 2015 12:22:22 +0100 Received: from host-87-242-63-18.prtelecom.hu ([87.242.63.18] helo=s002.sicom.com) by mail.pr.hu with esmtpa (Exim 4.80) (envelope-from ) id 1a8ngM-0001yr-Db; Tue, 15 Dec 2015 12:22:20 +0100 From: =?UTF-8?q?B=C3=B6sz=C3=B6rm=C3=A9nyi=20Zolt=C3=A1n?= To: Dmitry Torokhov Cc: linux-input@vger.kernel.org, =?UTF-8?q?B=C3=B6sz=C3=B6rm=C3=A9nyi=20Zolt=C3=A1n?= Subject: [PATCH] input/touchscreen: New EETI eGalaxTouch serial touchscreen driver Date: Tue, 15 Dec 2015 12:22:07 +0100 Message-Id: <1450178527-26745-1-git-send-email-zboszormenyi@sicom.com> X-Mailer: git-send-email 2.5.0 MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Scan-Signature: 8cc9fd311c3eb92dda5d2e4925991480 X-Spam-Tracer: backend.mail.pr.hu 1.3 20151215112220Z Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Böszörményi Zoltán There are two EETI touchscreen drivers in the kernel (eeti_ts and egalax_ts) but both are for I2C-connected panels. This is for a different, serial and not multi-touch touchscreen panel. The protocol documentation is at http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf Signed-off-by: Böszörményi Zoltán --- drivers/input/touchscreen/Kconfig | 10 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/egalax.c | 210 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/serio.h | 1 + 4 files changed, 222 insertions(+) create mode 100644 drivers/input/touchscreen/egalax.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index ae33da7..816a9dc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -301,20 +301,30 @@ config TOUCHSCREEN_FT6236 depends on GPIOLIB || COMPILE_TEST help Say Y here to enable support for the I2C connected FT6x06 and FT6x36 family of capacitive touchscreen drivers. If unsure, say N. To compile this driver as a module, choose M here: the module will be called ft6236. +config TOUCHSCREEN_EGALAX_SERIO + tristate "EETI eGalax serial touchscreen" + select SERIO + help + Say Y here to enable support for serial connected EETI + eGalax touch panels. + + To compile this driver as a module, choose M here: the + module will be called egalax. + config TOUCHSCREEN_FUJITSU tristate "Fujitsu serial touchscreen" select SERIO help Say Y here if you have the Fujitsu touchscreen (such as one installed in Lifebook P series laptop) connected to your system. If unsure, say N. diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index cbaa6ab..6f63b51 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -28,20 +28,21 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_SPI) += cyttsp4_spi.o obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o +obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIO) += egalax.o obj-$(CONFIG_TOUCHSCREEN_FT6236) += ft6236.o obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o diff --git a/drivers/input/touchscreen/egalax.c b/drivers/input/touchscreen/egalax.c new file mode 100644 index 0000000..94ac9bd --- /dev/null +++ b/drivers/input/touchscreen/egalax.c @@ -0,0 +1,210 @@ +/* + * EETI Egalax serial touchscreen driver + * + * Copyright (c) 2015 Zoltán Böszörményi + * + * based on the + * + * Hampshire serial touchscreen driver (Copyright (c) 2010 Adam Bennett) + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "EETI Egalax serial touchscreen driver" + +MODULE_AUTHOR("Zoltán Böszörményi "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/* + * Definitions & global arrays. + */ + +#define EGALAX_FORMAT_MAX_LENGTH 6 +#define EGALAX_RESPONSE_BEGIN_BYTE 0x80 +#define EGALAX_FORMAT_PRESSURE_BIT 0x40 +#define EGALAX_FORMAT_TOUCH_BIT 0x01 +#define EGALAX_FORMAT_RESOLUTION 0x06 + +#define EGALAX_MIN_XC 0 +#define EGALAX_MAX_XC 0x4000 +#define EGALAX_MIN_YC 0 +#define EGALAX_MAX_YC 0x4000 + +#define EGALAX_GET_XC(data, resbits, shift) ((((data[1] & (resbits)) << 7) | (data[2] & 0x7f)) << shift) +#define EGALAX_GET_YC(data, resbits, shift) ((((data[3] & (resbits)) << 7) | (data[4] & 0x7f)) << shift) +#define EGALAX_GET_TOUCHED(data) (EGALAX_FORMAT_TOUCH_BIT & data[0]) + +/* + * Per-touchscreen data. + */ + +struct egalax { + struct input_dev *dev; + struct serio *serio; + int idx; + int bytes; + int resbits; + int shift; + unsigned char data[EGALAX_FORMAT_MAX_LENGTH]; + char phys[32]; +}; + +static void egalax_process_data(struct egalax *pegalax) +{ + struct input_dev *dev = pegalax->dev; + + if (++pegalax->idx == pegalax->bytes) { + input_report_abs(dev, ABS_X, EGALAX_GET_XC(pegalax->data, pegalax->resbits, pegalax->shift)); + input_report_abs(dev, ABS_Y, EGALAX_GET_YC(pegalax->data, pegalax->resbits, pegalax->shift)); + input_report_key(dev, BTN_TOUCH, EGALAX_GET_TOUCHED(pegalax->data)); + input_sync(dev); + + pegalax->idx = 0; + } +} + +static irqreturn_t egalax_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) +{ + struct egalax *pegalax = serio_get_drvdata(serio); + + pegalax->data[pegalax->idx] = data; + + if (EGALAX_RESPONSE_BEGIN_BYTE & pegalax->data[0]) { + pegalax->bytes = (EGALAX_FORMAT_PRESSURE_BIT & pegalax->data[0] ? 6 : 5); + switch ((EGALAX_FORMAT_RESOLUTION & pegalax->data[0]) >> 1) { + case 0: + pegalax->resbits = 0x0f; + pegalax->shift = 3; + break; + case 1: + pegalax->resbits = 0x1f; + pegalax->shift = 2; + break; + case 2: + pegalax->resbits = 0x3f; + pegalax->shift = 1; + break; + default: + pegalax->resbits = 0x7f; + pegalax->shift = 0; + break; + } + egalax_process_data(pegalax); + } + else + dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n", + pegalax->data[0]); + + return IRQ_HANDLED; +} + +static void egalax_disconnect(struct serio *serio) +{ + struct egalax *pegalax = serio_get_drvdata(serio); + + input_get_device(pegalax->dev); + input_unregister_device(pegalax->dev); + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_put_device(pegalax->dev); + kfree(pegalax); +} + +/* + * egalax_connect() is the routine that is called when someone adds a + * new serio device that supports egalax protocol and registers it as + * an input device. This is usually accomplished using inputattach. + */ + +static int egalax_connect(struct serio *serio, struct serio_driver *drv) +{ + struct egalax *pegalax; + struct input_dev *input_dev; + int err; + + pegalax = kzalloc(sizeof(struct egalax), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!pegalax || !input_dev) { + err = -ENOMEM; + goto fail1; + } + + pegalax->serio = serio; + pegalax->dev = input_dev; + snprintf(pegalax->phys, sizeof(pegalax->phys), + "%s/input0", serio->phys); + + input_dev->name = "EETI eGalaxTouch Serial TouchScreen"; + input_dev->phys = pegalax->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_EGALAX; + input_dev->id.product = 0; + input_dev->id.version = 0x0001; + input_dev->dev.parent = &serio->dev; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_set_abs_params(pegalax->dev, ABS_X, + EGALAX_MIN_XC, EGALAX_MAX_XC, 0, 0); + input_set_abs_params(pegalax->dev, ABS_Y, + EGALAX_MIN_YC, EGALAX_MAX_YC, 0, 0); + + serio_set_drvdata(serio, pegalax); + + err = serio_open(serio, drv); + if (err) + goto fail2; + + err = input_register_device(pegalax->dev); + if (err) + goto fail3; + + return 0; + + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); + kfree(pegalax); + return err; +} + +/* + * The serio driver structure. + */ + +static struct serio_device_id egalax_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_EGALAX, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, egalax_serio_ids); + +static struct serio_driver egalax_drv = { + .driver = { + .name = "egalax", + }, + .description = DRIVER_DESC, + .id_table = egalax_serio_ids, + .interrupt = egalax_interrupt, + .connect = egalax_connect, + .disconnect = egalax_disconnect, +}; + +module_serio_driver(egalax_drv); diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h index becdd78..c2ea169 100644 --- a/include/uapi/linux/serio.h +++ b/include/uapi/linux/serio.h @@ -70,12 +70,13 @@ #define SERIO_FUJITSU 0x35 #define SERIO_ZHENHUA 0x36 #define SERIO_INEXIO 0x37 #define SERIO_TOUCHIT213 0x38 #define SERIO_W8001 0x39 #define SERIO_DYNAPRO 0x3a #define SERIO_HAMPSHIRE 0x3b #define SERIO_PS2MULT 0x3c #define SERIO_TSC40 0x3d #define SERIO_WACOM_IV 0x3e +#define SERIO_EGALAX 0x3f #endif /* _UAPI_SERIO_H */