diff options
| author | Scott Liu <scott.liu@emc.com.tw> | 2014-11-19 20:26:44 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-12-08 02:09:23 -0500 |
| commit | 66aee90088da2f5fb73ba97ee8b5f4fda92e2b53 (patch) | |
| tree | 9dfd705f23a1579504b12ba648f394c851f4726f /drivers | |
| parent | af906faabcf91eb12397d8954f89e289a8b96af5 (diff) | |
Input: add support for Elan eKTH I2C touchscreens
This driver supports Elan eKTH I2C touchscreen controllers. Note that these
are using custom protocol, as opposed to other Elan parts that use
HID-over-I2C and are supported by the standard HID-multitouch driver.
Signed-off-by: Scott Liu <scott.liu@emc.com.tw>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/input/touchscreen/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/input/touchscreen/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/touchscreen/elants_i2c.c | 1271 |
3 files changed, 1284 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 568a0200fbc2..58917525126e 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -347,6 +347,18 @@ config TOUCHSCREEN_GUNZE | |||
| 347 | To compile this driver as a module, choose M here: the | 347 | To compile this driver as a module, choose M here: the |
| 348 | module will be called gunze. | 348 | module will be called gunze. |
| 349 | 349 | ||
| 350 | config TOUCHSCREEN_ELAN | ||
| 351 | tristate "Elan eKTH I2C touchscreen" | ||
| 352 | depends on I2C | ||
| 353 | help | ||
| 354 | Say Y here if you have an Elan eKTH I2C touchscreen | ||
| 355 | connected to your system. | ||
| 356 | |||
| 357 | If unsure, say N. | ||
| 358 | |||
| 359 | To compile this driver as a module, choose M here: the | ||
| 360 | module will be called elants_i2c. | ||
| 361 | |||
| 350 | config TOUCHSCREEN_ELO | 362 | config TOUCHSCREEN_ELO |
| 351 | tristate "Elo serial touchscreens" | 363 | tristate "Elo serial touchscreens" |
| 352 | select SERIO | 364 | select SERIO |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index dab4a56ac98e..0242fea2102a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -31,6 +31,7 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o | |||
| 31 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o | 31 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o |
| 32 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 32 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
| 33 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | 33 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o |
| 34 | obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o | ||
| 34 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 35 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
| 35 | obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o | 36 | obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o |
| 36 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 37 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c new file mode 100644 index 000000000000..a510f7ef9b66 --- /dev/null +++ b/drivers/input/touchscreen/elants_i2c.c | |||
| @@ -0,0 +1,1271 @@ | |||
| 1 | /* | ||
| 2 | * Elan Microelectronics touch panels with I2C interface | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Elan Microelectronics Corporation. | ||
| 5 | * Scott Liu <scott.liu@emc.com.tw> | ||
| 6 | * | ||
| 7 | * This code is partly based on hid-multitouch.c: | ||
| 8 | * | ||
| 9 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> | ||
| 10 | * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 11 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France | ||
| 12 | * | ||
| 13 | * | ||
| 14 | * This code is partly based on i2c-hid.c: | ||
| 15 | * | ||
| 16 | * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 17 | * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France | ||
| 18 | * Copyright (c) 2012 Red Hat, Inc | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * This software is licensed under the terms of the GNU General Public | ||
| 23 | * License version 2, as published by the Free Software Foundation, and | ||
| 24 | * may be copied, distributed, and modified under those terms. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/input.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/async.h> | ||
| 32 | #include <linux/i2c.h> | ||
| 33 | #include <linux/delay.h> | ||
| 34 | #include <linux/uaccess.h> | ||
| 35 | #include <linux/buffer_head.h> | ||
| 36 | #include <linux/version.h> | ||
| 37 | #include <linux/slab.h> | ||
| 38 | #include <linux/firmware.h> | ||
| 39 | #include <linux/version.h> | ||
| 40 | #include <linux/input/mt.h> | ||
| 41 | #include <linux/acpi.h> | ||
| 42 | #include <linux/of.h> | ||
| 43 | #include <asm/unaligned.h> | ||
| 44 | |||
| 45 | /* Device, Driver information */ | ||
| 46 | #define DEVICE_NAME "elants_i2c" | ||
| 47 | #define DRV_VERSION "1.0.9" | ||
| 48 | |||
| 49 | /* Convert from rows or columns into resolution */ | ||
| 50 | #define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m)) | ||
| 51 | |||
| 52 | /* FW header data */ | ||
| 53 | #define HEADER_SIZE 4 | ||
| 54 | #define FW_HDR_TYPE 0 | ||
| 55 | #define FW_HDR_COUNT 1 | ||
| 56 | #define FW_HDR_LENGTH 2 | ||
| 57 | |||
| 58 | /* Buffer mode Queue Header information */ | ||
| 59 | #define QUEUE_HEADER_SINGLE 0x62 | ||
| 60 | #define QUEUE_HEADER_NORMAL 0X63 | ||
| 61 | #define QUEUE_HEADER_WAIT 0x64 | ||
| 62 | |||
| 63 | /* Command header definition */ | ||
| 64 | #define CMD_HEADER_WRITE 0x54 | ||
| 65 | #define CMD_HEADER_READ 0x53 | ||
| 66 | #define CMD_HEADER_6B_READ 0x5B | ||
| 67 | #define CMD_HEADER_RESP 0x52 | ||
| 68 | #define CMD_HEADER_6B_RESP 0x9B | ||
| 69 | #define CMD_HEADER_HELLO 0x55 | ||
| 70 | #define CMD_HEADER_REK 0x66 | ||
| 71 | |||
| 72 | /* FW position data */ | ||
| 73 | #define PACKET_SIZE 55 | ||
| 74 | #define MAX_CONTACT_NUM 10 | ||
| 75 | #define FW_POS_HEADER 0 | ||
| 76 | #define FW_POS_STATE 1 | ||
| 77 | #define FW_POS_TOTAL 2 | ||
| 78 | #define FW_POS_XY 3 | ||
| 79 | #define FW_POS_CHECKSUM 34 | ||
| 80 | #define FW_POS_WIDTH 35 | ||
| 81 | #define FW_POS_PRESSURE 45 | ||
| 82 | |||
| 83 | #define HEADER_REPORT_10_FINGER 0x62 | ||
| 84 | |||
| 85 | /* Header (4 bytes) plus 3 fill 10-finger packets */ | ||
| 86 | #define MAX_PACKET_SIZE 169 | ||
| 87 | |||
| 88 | #define BOOT_TIME_DELAY_MS 50 | ||
| 89 | |||
| 90 | /* FW read command, 0x53 0x?? 0x0, 0x01 */ | ||
| 91 | #define E_ELAN_INFO_FW_VER 0x00 | ||
| 92 | #define E_ELAN_INFO_BC_VER 0x10 | ||
| 93 | #define E_ELAN_INFO_TEST_VER 0xE0 | ||
| 94 | #define E_ELAN_INFO_FW_ID 0xF0 | ||
| 95 | #define E_INFO_OSR 0xD6 | ||
| 96 | #define E_INFO_PHY_SCAN 0xD7 | ||
| 97 | #define E_INFO_PHY_DRIVER 0xD8 | ||
| 98 | |||
| 99 | #define MAX_RETRIES 3 | ||
| 100 | #define MAX_FW_UPDATE_RETRIES 30 | ||
| 101 | |||
| 102 | #define ELAN_FW_PAGESIZE 132 | ||
| 103 | #define ELAN_FW_FILENAME "elants_i2c.bin" | ||
| 104 | |||
| 105 | /* calibration timeout definition */ | ||
| 106 | #define ELAN_CALI_TIMEOUT_MSEC 10000 | ||
| 107 | |||
| 108 | enum elants_state { | ||
| 109 | ELAN_STATE_NORMAL, | ||
| 110 | ELAN_WAIT_QUEUE_HEADER, | ||
| 111 | ELAN_WAIT_RECALIBRATION, | ||
| 112 | }; | ||
| 113 | |||
| 114 | enum elants_iap_mode { | ||
| 115 | ELAN_IAP_OPERATIONAL, | ||
| 116 | ELAN_IAP_RECOVERY, | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* struct elants_data - represents state of Elan touchscreen device */ | ||
| 120 | struct elants_data { | ||
| 121 | struct i2c_client *client; | ||
| 122 | struct input_dev *input; | ||
| 123 | |||
| 124 | u16 fw_version; | ||
| 125 | u8 test_version; | ||
| 126 | u8 solution_version; | ||
| 127 | u8 bc_version; | ||
| 128 | u8 iap_version; | ||
| 129 | u16 hw_version; | ||
| 130 | unsigned int x_res; /* resolution in units/mm */ | ||
| 131 | unsigned int y_res; | ||
| 132 | unsigned int x_max; | ||
| 133 | unsigned int y_max; | ||
| 134 | |||
| 135 | enum elants_state state; | ||
| 136 | enum elants_iap_mode iap_mode; | ||
| 137 | |||
| 138 | /* Guards against concurrent access to the device via sysfs */ | ||
| 139 | struct mutex sysfs_mutex; | ||
| 140 | |||
| 141 | u8 cmd_resp[HEADER_SIZE]; | ||
| 142 | struct completion cmd_done; | ||
| 143 | |||
| 144 | u8 buf[MAX_PACKET_SIZE]; | ||
| 145 | |||
| 146 | bool wake_irq_enabled; | ||
| 147 | }; | ||
| 148 | |||
| 149 | static int elants_i2c_send(struct i2c_client *client, | ||
| 150 | |||
