Blame view

drivers/hid/hid-multitouch.c 59.5 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
5519cab47   Benjamin Tissoires   HID: hid-multitou...
2
3
4
  /*
   *  HID driver for multitouch panels
   *
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
5
   *  Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
b0a786818   Benjamin Tissoires   HID: multitouch: ...
6
   *  Copyright (c) 2010-2013 Benjamin Tissoires <benjamin.tissoires@gmail.com>
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
7
   *  Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
b0a786818   Benjamin Tissoires   HID: multitouch: ...
8
   *  Copyright (c) 2012-2013 Red Hat, Inc
5519cab47   Benjamin Tissoires   HID: hid-multitou...
9
   *
4875ac114   Richard Nauber   HID: merge hid-eg...
10
11
12
13
14
15
   *  This code is partly based on hid-egalax.c:
   *
   *  Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
   *  Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
   *  Copyright (c) 2010 Canonical, Ltd.
   *
f786bba44   Benjamin Tissoires   HID: hid-multitou...
16
17
18
19
20
   *  This code is partly based on hid-3m-pct.c:
   *
   *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
   *  Copyright (c) 2010      Henrik Rydberg <rydberg@euromail.se>
   *  Copyright (c) 2010      Canonical, Ltd.
5519cab47   Benjamin Tissoires   HID: hid-multitou...
21
22
23
   */
  
  /*
5519cab47   Benjamin Tissoires   HID: hid-multitou...
24
   */
b0a786818   Benjamin Tissoires   HID: multitouch: ...
25
  /*
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
26
   * This driver is regularly tested thanks to the test suite in hid-tools[1].
b0a786818   Benjamin Tissoires   HID: multitouch: ...
27
28
29
   * Please run these regression tests before patching this module so that
   * your patch won't break existing known devices.
   *
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
30
   * [1] https://gitlab.freedesktop.org/libevdev/hid-tools
b0a786818   Benjamin Tissoires   HID: multitouch: ...
31
   */
5519cab47   Benjamin Tissoires   HID: hid-multitou...
32
33
34
35
  #include <linux/device.h>
  #include <linux/hid.h>
  #include <linux/module.h>
  #include <linux/slab.h>
5519cab47   Benjamin Tissoires   HID: hid-multitou...
36
  #include <linux/input/mt.h>
29cc309d8   Nicolas Boichat   HID: hid-multitou...
37
  #include <linux/jiffies.h>
49a5a827a   Benjamin Tissoires   HID: multitouch: ...
38
  #include <linux/string.h>
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
39
  #include <linux/timer.h>
5519cab47   Benjamin Tissoires   HID: hid-multitou...
40
41
42
  
  
  MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
ef2fafb3e   Benjamin Tissoires   HID: hid-multitou...
43
  MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
5519cab47   Benjamin Tissoires   HID: hid-multitou...
44
45
46
47
48
49
  MODULE_DESCRIPTION("HID multitouch panels");
  MODULE_LICENSE("GPL");
  
  #include "hid-ids.h"
  
  /* quirks to control the device */
fd9118965   Benjamin Tissoires   HID: multitouch: ...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  #define MT_QUIRK_NOT_SEEN_MEANS_UP	BIT(0)
  #define MT_QUIRK_SLOT_IS_CONTACTID	BIT(1)
  #define MT_QUIRK_CYPRESS		BIT(2)
  #define MT_QUIRK_SLOT_IS_CONTACTNUMBER	BIT(3)
  #define MT_QUIRK_ALWAYS_VALID		BIT(4)
  #define MT_QUIRK_VALID_IS_INRANGE	BIT(5)
  #define MT_QUIRK_VALID_IS_CONFIDENCE	BIT(6)
  #define MT_QUIRK_CONFIDENCE		BIT(7)
  #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	BIT(8)
  #define MT_QUIRK_NO_AREA		BIT(9)
  #define MT_QUIRK_IGNORE_DUPLICATES	BIT(10)
  #define MT_QUIRK_HOVERING		BIT(11)
  #define MT_QUIRK_CONTACT_CNT_ACCURATE	BIT(12)
  #define MT_QUIRK_FORCE_GET_FEATURE	BIT(13)
  #define MT_QUIRK_FIX_CONST_CONTACT_ID	BIT(14)
  #define MT_QUIRK_TOUCH_SIZE_SCALING	BIT(15)
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
66
  #define MT_QUIRK_STICKY_FINGERS		BIT(16)
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
67
  #define MT_QUIRK_ASUS_CUSTOM_UP		BIT(17)
d9c57a709   Benjamin Tissoires   HID: multitouch: ...
68
  #define MT_QUIRK_WIN8_PTP_BUTTONS	BIT(18)
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
69
  #define MT_QUIRK_SEPARATE_APP_REPORT	BIT(19)
40d5bb873   Benjamin Tissoires   HID: multitouch: ...
70
  #define MT_QUIRK_FORCE_MULTI_INPUT	BIT(20)
5519cab47   Benjamin Tissoires   HID: hid-multitou...
71

9abebedb1   Andrew Duggan   HID: multitouch: ...
72
73
  #define MT_INPUTMODE_TOUCHSCREEN	0x02
  #define MT_INPUTMODE_TOUCHPAD		0x03
2c6e0277e   Seth Forshee   HID: multitouch: ...
74
  #define MT_BUTTONTYPE_CLICKPAD		0
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
75
76
77
78
  enum latency_mode {
  	HID_LATENCY_NORMAL = 0,
  	HID_LATENCY_HIGH = 1,
  };
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
79
  #define MT_IO_FLAGS_RUNNING		0
960982745   Benjamin Tissoires   HID: multitouch: ...
80
81
  #define MT_IO_FLAGS_ACTIVE_SLOTS	1
  #define MT_IO_FLAGS_PENDING_SLOTS	2
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
82

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  static const bool mtrue = true;		/* default for true */
  static const bool mfalse;		/* default for false */
  static const __s32 mzero;		/* default for 0 */
  
  #define DEFAULT_TRUE	((void *)&mtrue)
  #define DEFAULT_FALSE	((void *)&mfalse)
  #define DEFAULT_ZERO	((void *)&mzero)
  
  struct mt_usages {
  	struct list_head list;
  	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
  	__s32 *contactid;	/* the device ContactID assigned to this slot */
  	bool *tip_state;	/* is the touch valid? */
  	bool *inrange_state;	/* is the finger in proximity of the sensor? */
  	bool *confidence_state;	/* is the touch made by a finger? */
5519cab47   Benjamin Tissoires   HID: hid-multitou...
98
  };
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
99
100
101
  struct mt_application {
  	struct list_head list;
  	unsigned int application;
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
102
  	unsigned int report_id;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
103
  	struct list_head mt_usages;	/* mt usages list */
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
104
105
  
  	__s32 quirks;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
106
107
  	__s32 *scantime;		/* scantime reported */
  	__s32 scantime_logical_max;	/* max value for raw scantime */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
108

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
109
  	__s32 *raw_cc;			/* contact count in the report */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
110
111
  	int left_button_state;		/* left button state */
  	unsigned int mt_flags;		/* flags to pass to input-mt */
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
112
113
  	unsigned long *pending_palm_slots;	/* slots where we reported palm
  						 * and need to release */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  	__u8 num_received;	/* how many contacts we received */
  	__u8 num_expected;	/* expected last contact index */
  	__u8 buttons_count;	/* number of physical buttons per touchpad */
  	__u8 touches_by_report;	/* how many touches are present in one report:
  				 * 1 means we should use a serial protocol
  				 * > 1 means hybrid (multitouch) protocol
  				 */
  
  	__s32 dev_time;		/* the scan time provided by the device */
  	unsigned long jiffies;	/* the frame's jiffies */
  	int timestamp;		/* the timestamp to be sent */
  	int prev_scantime;		/* scantime reported previously */
  
  	bool have_contact_count;
  };
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
129
130
131
132
133
134
135
136
  struct mt_class {
  	__s32 name;	/* MT_CLS */
  	__s32 quirks;
  	__s32 sn_move;	/* Signal/noise ratio for move events */
  	__s32 sn_width;	/* Signal/noise ratio for width events */
  	__s32 sn_height;	/* Signal/noise ratio for height events */
  	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
  	__u8 maxcontacts;
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
137
  	bool is_indirect;	/* true for touchpads */
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
138
  	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
139
  };
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
140
141
142
143
144
145
  struct mt_report_data {
  	struct list_head list;
  	struct hid_report *report;
  	struct mt_application *application;
  	bool is_mt_collection;
  };
5519cab47   Benjamin Tissoires   HID: hid-multitou...
146
  struct mt_device {
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
147
  	struct mt_class mtclass;	/* our mt device class */
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
148
  	struct timer_list release_timer;	/* to release sticky fingers */
0ee32774a   Kees Cook   HID: usbhid: Conv...
149
  	struct hid_device *hdev;	/* hid_device we're attached to */
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
150
  	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
151
  	__u8 inputmode_value;	/* InputMode HID feature value */
9498f954a   Benjamin Tissoires   HID: hid-multitou...
152
  	__u8 maxcontacts;
2c6e0277e   Seth Forshee   HID: multitouch: ...
153
  	bool is_buttonpad;	/* is this device a button pad? */
76f5902ae   Henrik Rydberg   HID: hid-multitou...
154
  	bool serial_maybe;	/* need to check for serial protocol */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
155
156
  
  	struct list_head applications;
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
157
  	struct list_head reports;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
158
  };
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
159
160
161
  static void mt_post_parse_default_settings(struct mt_device *td,
  					   struct mt_application *app);
  static void mt_post_parse(struct mt_device *td, struct mt_application *app);
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
162

5519cab47   Benjamin Tissoires   HID: hid-multitou...
163
  /* classes of device behavior */
22408283b   Benjamin Tissoires   HID: hid-multitou...
164
  #define MT_CLS_DEFAULT				0x0001
a062cc5a7   Stephane Chatty   HID: hid-multitou...
165
166
  #define MT_CLS_SERIAL				0x0002
  #define MT_CLS_CONFIDENCE			0x0003
5e7ea11f6   Benjamin Tissoires   HID: multitouch: ...
167
168
169
170
  #define MT_CLS_CONFIDENCE_CONTACT_ID		0x0004
  #define MT_CLS_CONFIDENCE_MINUS_ONE		0x0005
  #define MT_CLS_DUAL_INRANGE_CONTACTID		0x0006
  #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER	0x0007
0fa9c6161   Benjamin Tissoires   HID: multitouch: ...
171
  /* reserved					0x0008 */
b7ea95ff9   Aaron Tian   HID: multitouch: ...
172
  #define MT_CLS_INRANGE_CONTACTNUMBER		0x0009
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
173
  #define MT_CLS_NSMU				0x000a
0fa9c6161   Benjamin Tissoires   HID: multitouch: ...
174
175
  /* reserved					0x0010 */
  /* reserved					0x0011 */
f961bd351   Benjamin Tissoires   HID: detect Win 8...
176
  #define MT_CLS_WIN_8				0x0012
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
177
  #define MT_CLS_EXPORT_ALL_INPUTS		0x0013
27a6f7017   Kai-Heng Feng   HID: multitouch: ...
178
  /* reserved					0x0014 */
40d5bb873   Benjamin Tissoires   HID: multitouch: ...
179
  #define MT_CLS_WIN_8_FORCE_MULTI_INPUT		0x0015
22408283b   Benjamin Tissoires   HID: hid-multitou...
180
181
182
  
  /* vendor specific classes */
  #define MT_CLS_3M				0x0101
0fa9c6161   Benjamin Tissoires   HID: multitouch: ...
183
  /* reserved					0x0102 */
22408283b   Benjamin Tissoires   HID: hid-multitou...
184
  #define MT_CLS_EGALAX				0x0103
1b723e8dc   Benjamin Tissoires   HID: multitouch: ...
185
  #define MT_CLS_EGALAX_SERIAL			0x0104
847672cd1   Benjamin Tissoires   HID: multitouch: ...
186
  #define MT_CLS_TOPSEED				0x0105
2258e863b   Denis Kovalev   HID: multitouch: ...
187
  #define MT_CLS_PANASONIC			0x0106
77723e3bc   Henrik Rydberg   HID: hid-multitou...
188
  #define MT_CLS_FLATFROG				0x0107
cdcd3ac4e   Jiri Kosina   Merge branch 'mul...
189
190
  #define MT_CLS_GENERALTOUCH_TWOFINGERS		0x0108
  #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS	0x0109
f3287a995   Benjamin Tissoires   HID: multitouch: ...
191
  #define MT_CLS_LG				0x010a
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
192
  #define MT_CLS_ASUS				0x010b
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
193
  #define MT_CLS_VTL				0x0110
0e82232c4   Wei-Ning Huang   HID: multitouch: ...
194
  #define MT_CLS_GOOGLE				0x0111
843e475f9   Benjamin Tissoires   HID: multitouch: ...
195
  #define MT_CLS_RAZER_BLADE_STEALTH		0x0112
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
196
  #define MT_CLS_SMART_TECH			0x0113
5519cab47   Benjamin Tissoires   HID: hid-multitou...
197

9498f954a   Benjamin Tissoires   HID: hid-multitou...
198
  #define MT_DEFAULT_MAXCONTACT	10
afbcb04c1   Benjamin Tissoires   HID: multitouch: ...
199
  #define MT_MAX_MAXCONTACT	250
9498f954a   Benjamin Tissoires   HID: hid-multitou...
200

29cc309d8   Nicolas Boichat   HID: hid-multitou...
201
202
203
204
205
  /*
   * Resync device and local timestamps after that many microseconds without
   * receiving data.
   */
  #define MAX_TIMESTAMP_INTERVAL	1000000
2c2110e90   Henrik Rydberg   HID: hid-multitou...
206
207
  #define MT_USB_DEVICE(v, p)	HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p)
  #define MT_BT_DEVICE(v, p)	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p)
5519cab47   Benjamin Tissoires   HID: hid-multitou...
208
209
210
211
  /*
   * these device-dependent functions determine what slot corresponds
   * to a valid contact that was just read.
   */
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
212
213
  static int cypress_compute_slot(struct mt_application *application,
  				struct mt_usages *slot)
a3b5e577d   Benjamin Tissoires   HID: hid-multitou...
214
  {
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
215
216
  	if (*slot->contactid != 0 || application->num_received == 0)
  		return *slot->contactid;
a3b5e577d   Benjamin Tissoires   HID: hid-multitou...
217
218
219
  	else
  		return -1;
  }
cf6d15d7b   Benjamin Tissoires   HID: multitouch: ...
220
  static const struct mt_class mt_classes[] = {
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
221
  	{ .name = MT_CLS_DEFAULT,
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
222
223
224
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_CONTACT_CNT_ACCURATE },
  	{ .name = MT_CLS_NSMU,
9498f954a   Benjamin Tissoires   HID: hid-multitou...
225
  		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
a062cc5a7   Stephane Chatty   HID: hid-multitou...
226
227
  	{ .name = MT_CLS_SERIAL,
  		.quirks = MT_QUIRK_ALWAYS_VALID},
22408283b   Benjamin Tissoires   HID: hid-multitou...
228
229
  	{ .name = MT_CLS_CONFIDENCE,
  		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
5e7ea11f6   Benjamin Tissoires   HID: multitouch: ...
230
231
232
  	{ .name = MT_CLS_CONFIDENCE_CONTACT_ID,
  		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
  			MT_QUIRK_SLOT_IS_CONTACTID },
22408283b   Benjamin Tissoires   HID: hid-multitou...
233
234
235
  	{ .name = MT_CLS_CONFIDENCE_MINUS_ONE,
  		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
  			MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
1e9cf35b9   Benjamin Tissoires   HID: hid-multitou...
236
  	{ .name = MT_CLS_DUAL_INRANGE_CONTACTID,
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
237
238
239
  		.quirks = MT_QUIRK_VALID_IS_INRANGE |
  			MT_QUIRK_SLOT_IS_CONTACTID,
  		.maxcontacts = 2 },
1e9cf35b9   Benjamin Tissoires   HID: hid-multitou...
240
  	{ .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
241
242
243
  		.quirks = MT_QUIRK_VALID_IS_INRANGE |
  			MT_QUIRK_SLOT_IS_CONTACTNUMBER,
  		.maxcontacts = 2 },
b7ea95ff9   Aaron Tian   HID: multitouch: ...
244
245
246
  	{ .name = MT_CLS_INRANGE_CONTACTNUMBER,
  		.quirks = MT_QUIRK_VALID_IS_INRANGE |
  			MT_QUIRK_SLOT_IS_CONTACTNUMBER },
f961bd351   Benjamin Tissoires   HID: detect Win 8...
247
248
249
250
  	{ .name = MT_CLS_WIN_8,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_IGNORE_DUPLICATES |
  			MT_QUIRK_HOVERING |
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
251
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
d9c57a709   Benjamin Tissoires   HID: multitouch: ...
252
  			MT_QUIRK_STICKY_FINGERS |
c23e2043d   Benjamin Tissoires   HID: multitouch: ...
253
254
  			MT_QUIRK_WIN8_PTP_BUTTONS,
  		.export_all_inputs = true },
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
255
256
257
258
  	{ .name = MT_CLS_EXPORT_ALL_INPUTS,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_CONTACT_CNT_ACCURATE,
  		.export_all_inputs = true },
40d5bb873   Benjamin Tissoires   HID: multitouch: ...
259
260
261
262
263
264
265
266
267
  	{ .name = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_IGNORE_DUPLICATES |
  			MT_QUIRK_HOVERING |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_STICKY_FINGERS |
  			MT_QUIRK_WIN8_PTP_BUTTONS |
  			MT_QUIRK_FORCE_MULTI_INPUT,
  		.export_all_inputs = true },
22408283b   Benjamin Tissoires   HID: hid-multitou...
268
269
270
271
272
273
  
  	/*
  	 * vendor specific classes
  	 */
  	{ .name = MT_CLS_3M,
  		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
e9d0a26d3   HungNien Chen   HID: multitouch: ...
274
275
  			MT_QUIRK_SLOT_IS_CONTACTID |
  			MT_QUIRK_TOUCH_SIZE_SCALING,
22408283b   Benjamin Tissoires   HID: hid-multitou...
276
277
  		.sn_move = 2048,
  		.sn_width = 128,
c5d40be5f   Henrik Rydberg   HID: hid-multitou...
278
279
280
  		.sn_height = 128,
  		.maxcontacts = 60,
  	},
4875ac114   Richard Nauber   HID: merge hid-eg...
281
282
  	{ .name = MT_CLS_EGALAX,
  		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
2261bb9ff   Benjamin Tissoires   HID: multitouch: ...
283
  			MT_QUIRK_VALID_IS_INRANGE,
4875ac114   Richard Nauber   HID: merge hid-eg...
284
285
286
  		.sn_move = 4096,
  		.sn_pressure = 32,
  	},
1b723e8dc   Benjamin Tissoires   HID: multitouch: ...
287
288
289
  	{ .name = MT_CLS_EGALAX_SERIAL,
  		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
  			MT_QUIRK_ALWAYS_VALID,
4875ac114   Richard Nauber   HID: merge hid-eg...
290
291
292
  		.sn_move = 4096,
  		.sn_pressure = 32,
  	},
847672cd1   Benjamin Tissoires   HID: multitouch: ...
293
294
295
296
297
  	{ .name = MT_CLS_TOPSEED,
  		.quirks = MT_QUIRK_ALWAYS_VALID,
  		.is_indirect = true,
  		.maxcontacts = 2,
  	},
2258e863b   Denis Kovalev   HID: multitouch: ...
298
299
300
  	{ .name = MT_CLS_PANASONIC,
  		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
  		.maxcontacts = 4 },
f5ff4e1e6   Xianhan Yu   HID: multitouch: ...
301
302
303
  	{ .name	= MT_CLS_GENERALTOUCH_TWOFINGERS,
  		.quirks	= MT_QUIRK_NOT_SEEN_MEANS_UP |
  			MT_QUIRK_VALID_IS_INRANGE |
7b2262920   Luosong   HID: multitouch: ...
304
  			MT_QUIRK_SLOT_IS_CONTACTID,
f5ff4e1e6   Xianhan Yu   HID: multitouch: ...
305
306
307
308
  		.maxcontacts = 2
  	},
  	{ .name	= MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		.quirks	= MT_QUIRK_NOT_SEEN_MEANS_UP |
7b2262920   Luosong   HID: multitouch: ...
309
  			MT_QUIRK_SLOT_IS_CONTACTID
f5ff4e1e6   Xianhan Yu   HID: multitouch: ...
310
  	},
043b403ae   Benjamin Tissoires   HID: hid-multitou...
311

77723e3bc   Henrik Rydberg   HID: hid-multitou...
312
313
314
315
316
317
  	{ .name = MT_CLS_FLATFROG,
  		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
  			MT_QUIRK_NO_AREA,
  		.sn_move = 2048,
  		.maxcontacts = 40,
  	},
f3287a995   Benjamin Tissoires   HID: multitouch: ...
318
319
320
321
322
323
  	{ .name = MT_CLS_LG,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_FIX_CONST_CONTACT_ID |
  			MT_QUIRK_IGNORE_DUPLICATES |
  			MT_QUIRK_HOVERING |
  			MT_QUIRK_CONTACT_CNT_ACCURATE },
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
324
325
326
327
  	{ .name = MT_CLS_ASUS,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_ASUS_CUSTOM_UP },
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
328
329
330
331
332
  	{ .name = MT_CLS_VTL,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_FORCE_GET_FEATURE,
  	},
0e82232c4   Wei-Ning Huang   HID: multitouch: ...
333
334
335
336
337
338
  	{ .name = MT_CLS_GOOGLE,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_SLOT_IS_CONTACTID |
  			MT_QUIRK_HOVERING
  	},
843e475f9   Benjamin Tissoires   HID: multitouch: ...
339
340
341
342
343
344
345
  	{ .name = MT_CLS_RAZER_BLADE_STEALTH,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_IGNORE_DUPLICATES |
  			MT_QUIRK_HOVERING |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_WIN8_PTP_BUTTONS,
  	},
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
346
347
348
349
350
351
  	{ .name = MT_CLS_SMART_TECH,
  		.quirks = MT_QUIRK_ALWAYS_VALID |
  			MT_QUIRK_IGNORE_DUPLICATES |
  			MT_QUIRK_CONTACT_CNT_ACCURATE |
  			MT_QUIRK_SEPARATE_APP_REPORT,
  	},
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
352
  	{ }
5519cab47   Benjamin Tissoires   HID: hid-multitou...
353
  };
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
354
355
356
357
  static ssize_t mt_show_quirks(struct device *dev,
  			   struct device_attribute *attr,
  			   char *buf)
  {
ee79a8f84   Geliang Tang   HID: use to_hid_d...
358
  	struct hid_device *hdev = to_hid_device(dev);
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
359
360
361
362
363
364
365
366
367
368
  	struct mt_device *td = hid_get_drvdata(hdev);
  
  	return sprintf(buf, "%u
  ", td->mtclass.quirks);
  }
  
  static ssize_t mt_set_quirks(struct device *dev,
  			  struct device_attribute *attr,
  			  const char *buf, size_t count)
  {
ee79a8f84   Geliang Tang   HID: use to_hid_d...
369
  	struct hid_device *hdev = to_hid_device(dev);
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
370
  	struct mt_device *td = hid_get_drvdata(hdev);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
371
  	struct mt_application *application;
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
372
373
374
375
376
377
378
  
  	unsigned long val;
  
  	if (kstrtoul(buf, 0, &val))
  		return -EINVAL;
  
  	td->mtclass.quirks = val;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
379
  	list_for_each_entry(application, &td->applications, list) {
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
380
381
382
  		application->quirks = val;
  		if (!application->have_contact_count)
  			application->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
383
  	}
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
384
385
386
387
388
389
390
391
392
  	return count;
  }
  
  static DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks);
  
  static struct attribute *sysfs_attrs[] = {
  	&dev_attr_quirks.attr,
  	NULL
  };
9182fb98d   Arvind Yadav   HID: multitouch: ...
393
  static const struct attribute_group mt_attribute_group = {
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
394
395
  	.attrs = sysfs_attrs
  };
6d4f5440a   Mika Westerberg   HID: multitouch: ...
396
397
  static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
  {
3064a03b9   Aaron Ma   HID: Fix hid_repo...
398
399
  	int ret;
  	u32 size = hid_report_len(report);
6d4f5440a   Mika Westerberg   HID: multitouch: ...
400
401
402
  	u8 *buf;
  
  	/*
b897f6db3   Benjamin Tissoires   HID: multitouch: ...
403
404
  	 * Do not fetch the feature report if the device has been explicitly
  	 * marked as non-capable.
6d4f5440a   Mika Westerberg   HID: multitouch: ...
405
  	 */
adaabbf48   Benjamin Tissoires   HID: multitouch: ...
406
  	if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)
6d4f5440a   Mika Westerberg   HID: multitouch: ...
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  		return;
  
  	buf = hid_alloc_report_buf(report, GFP_KERNEL);
  	if (!buf)
  		return;
  
  	ret = hid_hw_raw_request(hdev, report->id, buf, size,
  				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
  	if (ret < 0) {
  		dev_warn(&hdev->dev, "failed to fetch feature %d
  ",
  			 report->id);
  	} else {
  		ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
  					   size, 0);
  		if (ret)
  			dev_warn(&hdev->dev, "failed to report feature
  ");
  	}
  
  	kfree(buf);
  }
f635bd11c   Henrik Rydberg   HID: Do not creat...
429
  static void mt_feature_mapping(struct hid_device *hdev,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
430
431
  		struct hid_field *field, struct hid_usage *usage)
  {
9498f954a   Benjamin Tissoires   HID: hid-multitou...
432
433
434
  	struct mt_device *td = hid_get_drvdata(hdev);
  
  	switch (usage->hid) {
9498f954a   Benjamin Tissoires   HID: hid-multitou...
435
  	case HID_DG_CONTACTMAX:
6d4f5440a   Mika Westerberg   HID: multitouch: ...
436
  		mt_get_feature(hdev, field->report);
9498f954a   Benjamin Tissoires   HID: hid-multitou...
437
  		td->maxcontacts = field->value[0];
afbcb04c1   Benjamin Tissoires   HID: multitouch: ...
438
439
440
  		if (!td->maxcontacts &&
  		    field->logical_maximum <= MT_MAX_MAXCONTACT)
  			td->maxcontacts = field->logical_maximum;
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
441
  		if (td->mtclass.maxcontacts)
9498f954a   Benjamin Tissoires   HID: hid-multitou...
442
  			/* check if the maxcontacts is given by the class */
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
443
  			td->maxcontacts = td->mtclass.maxcontacts;
9498f954a   Benjamin Tissoires   HID: hid-multitou...
444
445
  
  		break;
2c6e0277e   Seth Forshee   HID: multitouch: ...
446
447
448
449
450
451
  	case HID_DG_BUTTONTYPE:
  		if (usage->usage_index >= field->report_count) {
  			dev_err(&hdev->dev, "HID_DG_BUTTONTYPE out of range
  ");
  			break;
  		}
6d4f5440a   Mika Westerberg   HID: multitouch: ...
452
  		mt_get_feature(hdev, field->report);
2c6e0277e   Seth Forshee   HID: multitouch: ...
453
454
455
456
  		if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD)
  			td->is_buttonpad = true;
  
  		break;
45c5c6828   Benjamin Tissoires   HID: multitouch: ...
457
458
459
460
461
  	case 0xff0000c5:
  		/* Retrieve the Win8 blob once to enable some devices */
  		if (usage->usage_index == 0)
  			mt_get_feature(hdev, field->report);
  		break;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
462
463
464
465
466
467
468
469
470
471
  	}
  }
  
  static void set_abs(struct input_dev *input, unsigned int code,
  		struct hid_field *field, int snratio)
  {
  	int fmin = field->logical_minimum;
  	int fmax = field->logical_maximum;
  	int fuzz = snratio ? (fmax - fmin) / snratio : 0;
  	input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
37cf6e6fc   Benjamin Tissoires   HID: export hidin...
472
  	input_abs_set_res(input, code, hidinput_calc_abs_res(field, code));
5519cab47   Benjamin Tissoires   HID: hid-multitou...
473
  }
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  static struct mt_usages *mt_allocate_usage(struct hid_device *hdev,
  					   struct mt_application *application)
  {
  	struct mt_usages *usage;
  
  	usage = devm_kzalloc(&hdev->dev, sizeof(*usage), GFP_KERNEL);
  	if (!usage)
  		return NULL;
  
  	/* set some defaults so we do not need to check for null pointers */
  	usage->x = DEFAULT_ZERO;
  	usage->y = DEFAULT_ZERO;
  	usage->cx = DEFAULT_ZERO;
  	usage->cy = DEFAULT_ZERO;
  	usage->p = DEFAULT_ZERO;
  	usage->w = DEFAULT_ZERO;
  	usage->h = DEFAULT_ZERO;
  	usage->a = DEFAULT_ZERO;
  	usage->contactid = DEFAULT_ZERO;
  	usage->tip_state = DEFAULT_FALSE;
  	usage->inrange_state = DEFAULT_FALSE;
  	usage->confidence_state = DEFAULT_TRUE;
  
  	list_add_tail(&usage->list, &application->mt_usages);
  
  	return usage;
  }
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
501
  static struct mt_application *mt_allocate_application(struct mt_device *td,
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
502
  						      struct hid_report *report)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
503
  {
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
504
  	unsigned int application = report->application;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
505
506
507
508
509
510
511
512
  	struct mt_application *mt_application;
  
  	mt_application = devm_kzalloc(&td->hdev->dev, sizeof(*mt_application),
  				      GFP_KERNEL);
  	if (!mt_application)
  		return NULL;
  
  	mt_application->application = application;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
513
  	INIT_LIST_HEAD(&mt_application->mt_usages);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
514
515
516
517
518
519
520
521
522
523
524
  
  	if (application == HID_DG_TOUCHSCREEN)
  		mt_application->mt_flags |= INPUT_MT_DIRECT;
  
  	/*
  	 * Model touchscreens providing buttons as touchpads.
  	 */
  	if (application == HID_DG_TOUCHPAD) {
  		mt_application->mt_flags |= INPUT_MT_POINTER;
  		td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
  	}
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
525
526
  	mt_application->scantime = DEFAULT_ZERO;
  	mt_application->raw_cc = DEFAULT_ZERO;
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
527
  	mt_application->quirks = td->mtclass.quirks;
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
528
  	mt_application->report_id = report->id;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
529
530
531
532
533
534
535
  
  	list_add_tail(&mt_application->list, &td->applications);
  
  	return mt_application;
  }
  
  static struct mt_application *mt_find_application(struct mt_device *td,
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
536
  						  struct hid_report *report)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
537
  {
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
538
  	unsigned int application = report->application;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
539
540
541
542
  	struct mt_application *tmp, *mt_application = NULL;
  
  	list_for_each_entry(tmp, &td->applications, list) {
  		if (application == tmp->application) {
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
543
544
545
546
547
  			if (!(td->mtclass.quirks & MT_QUIRK_SEPARATE_APP_REPORT) ||
  			    tmp->report_id == report->id) {
  				mt_application = tmp;
  				break;
  			}
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
548
549
550
551
  		}
  	}
  
  	if (!mt_application)
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
552
  		mt_application = mt_allocate_application(td, report);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
553
554
555
  
  	return mt_application;
  }
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
556
557
558
559
560
561
562
563
564
565
566
567
  static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
  						      struct hid_report *report)
  {
  	struct mt_report_data *rdata;
  	struct hid_field *field;
  	int r, n;
  
  	rdata = devm_kzalloc(&td->hdev->dev, sizeof(*rdata), GFP_KERNEL);
  	if (!rdata)
  		return NULL;
  
  	rdata->report = report;
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
568
  	rdata->application = mt_find_application(td, report);
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
  
  	if (!rdata->application) {
  		devm_kfree(&td->hdev->dev, rdata);
  		return NULL;
  	}
  
  	for (r = 0; r < report->maxfield; r++) {
  		field = report->field[r];
  
  		if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
  			continue;
  
  		for (n = 0; n < field->report_count; n++) {
  			if (field->usage[n].hid == HID_DG_CONTACTID)
  				rdata->is_mt_collection = true;
  		}
  	}
  
  	list_add_tail(&rdata->list, &td->reports);
  
  	return rdata;
  }
  
  static struct mt_report_data *mt_find_report_data(struct mt_device *td,
  						  struct hid_report *report)
  {
  	struct mt_report_data *tmp, *rdata = NULL;
  
  	list_for_each_entry(tmp, &td->reports, list) {
  		if (report == tmp->report) {
  			rdata = tmp;
  			break;
  		}
  	}
  
  	if (!rdata)
  		rdata = mt_allocate_report_data(td, report);
  
  	return rdata;
  }
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
609
610
611
612
  static void mt_store_field(struct hid_device *hdev,
  			   struct mt_application *application,
  			   __s32 *value,
  			   size_t offset)
ed9d5c961   Benjamin Tissoires   HID: multitouch: ...
613
  {
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
614
615
616
617
618
619
620
621
622
  	struct mt_usages *usage;
  	__s32 **target;
  
  	if (list_empty(&application->mt_usages))
  		usage = mt_allocate_usage(hdev, application);
  	else
  		usage = list_last_entry(&application->mt_usages,
  					struct mt_usages,
  					list);
3ac36d155   Benjamin Tissoires   HID: hid-multitou...
623

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
624
  	if (!usage)
3ac36d155   Benjamin Tissoires   HID: hid-multitou...
625
  		return;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
626
627
628
629
630
631
  	target = (__s32 **)((char *)usage + offset);
  
  	/* the value has already been filled, create a new slot */
  	if (*target != DEFAULT_TRUE &&
  	    *target != DEFAULT_FALSE &&
  	    *target != DEFAULT_ZERO) {
81bcbad53   Benjamin Tissoires   HID: multitouch: ...
632
633
634
635
636
637
638
  		if (usage->contactid == DEFAULT_ZERO ||
  		    usage->x == DEFAULT_ZERO ||
  		    usage->y == DEFAULT_ZERO) {
  			hid_dbg(hdev,
  				"ignoring duplicate usage on incomplete");
  			return;
  		}
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
639
640
641
642
643
644
645
646
  		usage = mt_allocate_usage(hdev, application);
  		if (!usage)
  			return;
  
  		target = (__s32 **)((char *)usage + offset);
  	}
  
  	*target = value;
ed9d5c961   Benjamin Tissoires   HID: multitouch: ...
647
  }
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
648
649
650
651
  #define MT_STORE_FIELD(__name)						\
  	mt_store_field(hdev, app,					\
  		       &field->value[usage->usage_index],		\
  		       offsetof(struct mt_usages, __name))
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
652
  static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
653
  		struct hid_field *field, struct hid_usage *usage,
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
654
  		unsigned long **bit, int *max, struct mt_application *app)
5519cab47   Benjamin Tissoires   HID: hid-multitou...
655
656
  {
  	struct mt_device *td = hid_get_drvdata(hdev);
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
657
  	struct mt_class *cls = &td->mtclass;
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
658
  	int code;
349fd6705   Benjamin Tissoires   HID: multitouch: ...
659
  	struct hid_usage *prev_usage = NULL;
4875ac114   Richard Nauber   HID: merge hid-eg...
660

76f5902ae   Henrik Rydberg   HID: hid-multitou...
661
662
  	/*
  	 * Model touchscreens providing buttons as touchpads.
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
663
  	 */
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
664
665
  	if (field->application == HID_DG_TOUCHSCREEN &&
  	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
666
  		app->mt_flags |= INPUT_MT_POINTER;
9abebedb1   Andrew Duggan   HID: multitouch: ...
667
668
  		td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
  	}
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
669

015fdaa9f   Benjamin Tissoires   HID: multitouch: ...
670
671
  	/* count the buttons on touchpads */
  	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
672
  		app->buttons_count++;
015fdaa9f   Benjamin Tissoires   HID: multitouch: ...
673

349fd6705   Benjamin Tissoires   HID: multitouch: ...
674
675
  	if (usage->usage_index)
  		prev_usage = &field->usage[usage->usage_index - 1];
5519cab47   Benjamin Tissoires   HID: hid-multitou...
676
677
678
679
680
  	switch (usage->hid & HID_USAGE_PAGE) {
  
  	case HID_UP_GENDESK:
  		switch (usage->hid) {
  		case HID_GD_X:
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
681
  			if (prev_usage && (prev_usage->hid == usage->hid)) {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
682
  				code = ABS_MT_TOOL_X;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
683
684
  				MT_STORE_FIELD(cx);
  			} else {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
685
  				code = ABS_MT_POSITION_X;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
686
687
  				MT_STORE_FIELD(x);
  			}
349fd6705   Benjamin Tissoires   HID: multitouch: ...
688

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
689
  			set_abs(hi->input, code, field, cls->sn_move);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
690

ba6b055e0   Benjamin Tissoires   HID: input: enabl...
691
692
693
694
695
696
697
698
699
700
701
702
  			/*
  			 * A system multi-axis that exports X and Y has a high
  			 * chance of being used directly on a surface
  			 */
  			if (field->application == HID_GD_SYSTEM_MULTIAXIS) {
  				__set_bit(INPUT_PROP_DIRECT,
  					  hi->input->propbit);
  				input_set_abs_params(hi->input,
  						     ABS_MT_TOOL_TYPE,
  						     MT_TOOL_DIAL,
  						     MT_TOOL_DIAL, 0, 0);
  			}
5519cab47   Benjamin Tissoires   HID: hid-multitou...
703
704
  			return 1;
  		case HID_GD_Y:
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
705
  			if (prev_usage && (prev_usage->hid == usage->hid)) {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
706
  				code = ABS_MT_TOOL_Y;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
707
708
  				MT_STORE_FIELD(cy);
  			} else {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
709
  				code = ABS_MT_POSITION_Y;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
710
711
  				MT_STORE_FIELD(y);
  			}
349fd6705   Benjamin Tissoires   HID: multitouch: ...
712

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
713
  			set_abs(hi->input, code, field, cls->sn_move);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
714

5519cab47   Benjamin Tissoires   HID: hid-multitou...
715
716
717
718
719
720
721
  			return 1;
  		}
  		return 0;
  
  	case HID_UP_DIGITIZER:
  		switch (usage->hid) {
  		case HID_DG_INRANGE:
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
722
  			if (app->quirks & MT_QUIRK_HOVERING) {
9b3bb9b8b   Benjamin Tissoires   HID: multitouch: ...
723
724
725
  				input_set_abs_params(hi->input,
  					ABS_MT_DISTANCE, 0, 1, 0, 0);
  			}
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
726
  			MT_STORE_FIELD(inrange_state);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
727
728
  			return 1;
  		case HID_DG_CONFIDENCE:
27a6f7017   Kai-Heng Feng   HID: multitouch: ...
729
  			if (cls->name == MT_CLS_WIN_8 &&
f90243745   Dmitry Torokhov   HID: multitouch: ...
730
731
  				(field->application == HID_DG_TOUCHPAD ||
  				 field->application == HID_DG_TOUCHSCREEN))
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
732
  				app->quirks |= MT_QUIRK_CONFIDENCE;
9152c7d77   Dmitry Torokhov   HID: multitouch: ...
733
734
735
736
737
738
  
  			if (app->quirks & MT_QUIRK_CONFIDENCE)
  				input_set_abs_params(hi->input,
  						     ABS_MT_TOOL_TYPE,
  						     MT_TOOL_FINGER,
  						     MT_TOOL_PALM, 0, 0);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
739
  			MT_STORE_FIELD(confidence_state);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
740
741
  			return 1;
  		case HID_DG_TIPSWITCH:
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
742
743
744
  			if (field->application != HID_GD_SYSTEM_MULTIAXIS)
  				input_set_capability(hi->input,
  						     EV_KEY, BTN_TOUCH);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
745
  			MT_STORE_FIELD(tip_state);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
746
747
  			return 1;
  		case HID_DG_CONTACTID:
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
748
  			MT_STORE_FIELD(contactid);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
749
  			app->touches_by_report++;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
750
751
  			return 1;
  		case HID_DG_WIDTH:
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
752
  			if (!(app->quirks & MT_QUIRK_NO_AREA))
77723e3bc   Henrik Rydberg   HID: hid-multitou...
753
754
  				set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
  					cls->sn_width);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
755
  			MT_STORE_FIELD(w);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
756
757
  			return 1;
  		case HID_DG_HEIGHT:
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
758
  			if (!(app->quirks & MT_QUIRK_NO_AREA)) {
77723e3bc   Henrik Rydberg   HID: hid-multitou...
759
760
  				set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
  					cls->sn_height);
00720277a   Wei-Ning Huang   HID: hid-multitou...
761
762
763
764
765
766
767
768
769
  
  				/*
  				 * Only set ABS_MT_ORIENTATION if it is not
  				 * already set by the HID_DG_AZIMUTH usage.
  				 */
  				if (!test_bit(ABS_MT_ORIENTATION,
  						hi->input->absbit))
  					input_set_abs_params(hi->input,
  						ABS_MT_ORIENTATION, 0, 1, 0, 0);
77723e3bc   Henrik Rydberg   HID: hid-multitou...
770
  			}
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
771
  			MT_STORE_FIELD(h);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
772
773
  			return 1;
  		case HID_DG_TIPPRESSURE:
5519cab47   Benjamin Tissoires   HID: hid-multitou...
774
775
  			set_abs(hi->input, ABS_MT_PRESSURE, field,
  				cls->sn_pressure);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
776
  			MT_STORE_FIELD(p);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
777
  			return 1;
29cc309d8   Nicolas Boichat   HID: hid-multitou...
778
  		case HID_DG_SCANTIME:
29cc309d8   Nicolas Boichat   HID: hid-multitou...
779
  			input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
780
781
  			app->scantime = &field->value[usage->usage_index];
  			app->scantime_logical_max = field->logical_maximum;
29cc309d8   Nicolas Boichat   HID: hid-multitou...
782
  			return 1;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
783
  		case HID_DG_CONTACTCOUNT:
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
784
785
  			app->have_contact_count = true;
  			app->raw_cc = &field->value[usage->usage_index];
5519cab47   Benjamin Tissoires   HID: hid-multitou...
786
  			return 1;
00720277a   Wei-Ning Huang   HID: hid-multitou...
787
  		case HID_DG_AZIMUTH:
00720277a   Wei-Ning Huang   HID: hid-multitou...
788
789
790
791
792
793
794
795
796
797
  			/*
  			 * Azimuth has the range of [0, MAX) representing a full
  			 * revolution. Set ABS_MT_ORIENTATION to a quarter of
  			 * MAX according the definition of ABS_MT_ORIENTATION
  			 */
  			input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
  				-field->logical_maximum / 4,
  				field->logical_maximum / 4,
  				cls->sn_move ?
  				field->logical_maximum / cls->sn_move : 0, 0);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
798
  			MT_STORE_FIELD(a);
00720277a   Wei-Ning Huang   HID: hid-multitou...
799
  			return 1;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
800
  		case HID_DG_CONTACTMAX:
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
801
  			/* contact max are global to the report */
5519cab47   Benjamin Tissoires   HID: hid-multitou...
802
  			return -1;
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
803
804
805
806
  		case HID_DG_TOUCH:
  			/* Legacy devices use TIPSWITCH and not TOUCH.
  			 * Let's just ignore this field. */
  			return -1;
65b258e9b   Alan Cox   HID: multitouch: ...
807
  		}
5519cab47   Benjamin Tissoires   HID: hid-multitou...
808
809
  		/* let hid-input decide for the others */
  		return 0;
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
810
811
  	case HID_UP_BUTTON:
  		code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
594312b88   Benjamin Tissoires   HID: multitouch: ...
812
813
814
815
  		/*
  		 * MS PTP spec says that external buttons left and right have
  		 * usages 2 and 3.
  		 */
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
816
  		if ((app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
594312b88   Benjamin Tissoires   HID: multitouch: ...
817
818
819
  		    field->application == HID_DG_TOUCHPAD &&
  		    (usage->hid & HID_USAGE) > 1)
  			code--;
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
820
821
822
  
  		if (field->application == HID_GD_SYSTEM_MULTIAXIS)
  			code = BTN_0  + ((usage->hid - 1) & HID_USAGE);
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
823
  		hid_map_usage(hi, usage, bit, max, EV_KEY, code);
35556bed8   Marc Zyngier   HID: core: Saniti...
824
825
  		if (!*bit)
  			return -1;
c2ef8f21e   Benjamin Tissoires   HID: multitouch: ...
826
827
  		input_set_capability(hi->input, EV_KEY, code);
  		return 1;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
828
829
830
831
832
833
834
  	case 0xff000000:
  		/* we do not want to map these: no input-oriented meaning */
  		return -1;
  	}
  
  	return 0;
  }
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
835
  static int mt_compute_slot(struct mt_device *td, struct mt_application *app,
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
836
  			   struct mt_usages *slot,
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
837
  			   struct input_dev *input)
5519cab47   Benjamin Tissoires   HID: hid-multitou...
838
  {
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
839
  	__s32 quirks = app->quirks;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
840

2d93666e7   Benjamin Tissoires   HID: hid-multitou...
841
  	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
842
  		return *slot->contactid;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
843

2d93666e7   Benjamin Tissoires   HID: hid-multitou...
844
  	if (quirks & MT_QUIRK_CYPRESS)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
845
  		return cypress_compute_slot(app, slot);
a3b5e577d   Benjamin Tissoires   HID: hid-multitou...
846

2d93666e7   Benjamin Tissoires   HID: hid-multitou...
847
  	if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
848
  		return app->num_received;
5572da08a   Benjamin Tissoires   HID: hid-mulitouc...
849

4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
850
  	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
851
  		return *slot->contactid - 1;
4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
852

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
853
  	return input_mt_get_slot_by_key(input, *slot->contactid);
3e1b5015d   Henrik Rydberg   HID: hid-multitou...
854
  }
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
855
856
857
858
859
860
861
862
863
864
865
  static void mt_release_pending_palms(struct mt_device *td,
  				     struct mt_application *app,
  				     struct input_dev *input)
  {
  	int slotnum;
  	bool need_sync = false;
  
  	for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
  		clear_bit(slotnum, app->pending_palm_slots);
  
  		input_mt_slot(input, slotnum);
5fc70e350   Jiada Wang   Input: introduce ...
866
  		input_mt_report_slot_inactive(input);
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
867
868
869
870
871
872
873
874
875
  
  		need_sync = true;
  	}
  
  	if (need_sync) {
  		input_mt_sync_frame(input);
  		input_sync(input);
  	}
  }
3e1b5015d   Henrik Rydberg   HID: hid-multitou...
876
877
878
879
  /*
   * this function is called when a whole packet has been received and processed,
   * so that it can decide what to send to the input layer.
   */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
880
881
  static void mt_sync_frame(struct mt_device *td, struct mt_application *app,
  			  struct input_dev *input)
3e1b5015d   Henrik Rydberg   HID: hid-multitou...
882
  {
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
883
  	if (app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
884
  		input_event(input, EV_KEY, BTN_LEFT, app->left_button_state);
127e71bd4   Hans de Goede   HID: multitouch: ...
885

76f5902ae   Henrik Rydberg   HID: hid-multitou...
886
  	input_mt_sync_frame(input);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
887
  	input_event(input, EV_MSC, MSC_TIMESTAMP, app->timestamp);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
888
  	input_sync(input);
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
889
890
  
  	mt_release_pending_palms(td, app, input);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
891
892
  	app->num_received = 0;
  	app->left_button_state = 0;
960982745   Benjamin Tissoires   HID: multitouch: ...
893
894
895
896
897
  	if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
  		set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
  	else
  		clear_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
  	clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
898
  }
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
899
  static int mt_compute_timestamp(struct mt_application *app, __s32 value)
29cc309d8   Nicolas Boichat   HID: hid-multitou...
900
  {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
901
902
  	long delta = value - app->prev_scantime;
  	unsigned long jdelta = jiffies_to_usecs(jiffies - app->jiffies);
29cc309d8   Nicolas Boichat   HID: hid-multitou...
903

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
904
  	app->jiffies = jiffies;
29cc309d8   Nicolas Boichat   HID: hid-multitou...
905
906
  
  	if (delta < 0)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
907
  		delta += app->scantime_logical_max;
29cc309d8   Nicolas Boichat   HID: hid-multitou...
908
909
910
911
912
913
914
915
  
  	/* HID_DG_SCANTIME is expressed in 100us, we want it in us. */
  	delta *= 100;
  
  	if (jdelta > MAX_TIMESTAMP_INTERVAL)
  		/* No data received for a while, resync the timestamp. */
  		return 0;
  	else
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
916
  		return app->timestamp + delta;
29cc309d8   Nicolas Boichat   HID: hid-multitou...
917
  }
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
918
  static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
919
920
  				struct hid_usage *usage, __s32 value)
  {
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
921
922
923
924
925
926
  	/* we will handle the hidinput part later, now remains hiddev */
  	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
  		hid->hiddev_hid_event(hid, field, usage, value);
  
  	return 1;
  }
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
927
928
929
  static int mt_process_slot(struct mt_device *td, struct input_dev *input,
  			    struct mt_application *app,
  			    struct mt_usages *slot)
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
930
  {
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
931
  	struct input_mt *mt = input->mt;
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
932
  	__s32 quirks = app->quirks;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
933
934
935
936
937
  	bool valid = true;
  	bool confidence_state = true;
  	bool inrange_state = false;
  	int active;
  	int slotnum;
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
938
  	int tool = MT_TOOL_FINGER;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
939

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
  	if (!slot)
  		return -EINVAL;
  
  	if ((quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) &&
  	    app->num_received >= app->num_expected)
  		return -EAGAIN;
  
  	if (!(quirks & MT_QUIRK_ALWAYS_VALID)) {
  		if (quirks & MT_QUIRK_VALID_IS_INRANGE)
  			valid = *slot->inrange_state;
  		if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
  			valid = *slot->tip_state;
  		if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
  			valid = *slot->confidence_state;
  
  		if (!valid)
  			return 0;
  	}
  
  	slotnum = mt_compute_slot(td, app, slot, input);
  	if (slotnum < 0 || slotnum >= td->maxcontacts)
  		return 0;
  
  	if ((quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) {
  		struct input_mt_slot *i_slot = &mt->slots[slotnum];
  
  		if (input_mt_is_active(i_slot) &&
  		    input_mt_is_used(mt, i_slot))
  			return -EAGAIN;
  	}
  
  	if (quirks & MT_QUIRK_CONFIDENCE)
  		confidence_state = *slot->confidence_state;
  
  	if (quirks & MT_QUIRK_HOVERING)
  		inrange_state = *slot->inrange_state;
9152c7d77   Dmitry Torokhov   HID: multitouch: ...
976
  	active = *slot->tip_state || inrange_state;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
977

ba6b055e0   Benjamin Tissoires   HID: input: enabl...
978
979
  	if (app->application == HID_GD_SYSTEM_MULTIAXIS)
  		tool = MT_TOOL_DIAL;
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
980
  	else if (unlikely(!confidence_state)) {
9152c7d77   Dmitry Torokhov   HID: multitouch: ...
981
  		tool = MT_TOOL_PALM;
306d5acbf   Pan Zhang   drivers/hid/hid-m...
982
  		if (!active && mt &&
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
983
984
985
986
987
988
989
990
991
992
993
994
995
996
  		    input_mt_is_active(&mt->slots[slotnum])) {
  			/*
  			 * The non-confidence was reported for
  			 * previously valid contact that is also no
  			 * longer valid. We can't simply report
  			 * lift-off as userspace will not be aware
  			 * of non-confidence, so we need to split
  			 * it into 2 events: active MT_TOOL_PALM
  			 * and a separate liftoff.
  			 */
  			active = true;
  			set_bit(slotnum, app->pending_palm_slots);
  		}
  	}
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
997

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
998
  	input_mt_slot(input, slotnum);
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
999
  	input_mt_report_slot_state(input, tool, active);
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  	if (active) {
  		/* this finger is in proximity of the sensor */
  		int wide = (*slot->w > *slot->h);
  		int major = max(*slot->w, *slot->h);
  		int minor = min(*slot->w, *slot->h);
  		int orientation = wide;
  		int max_azimuth;
  		int azimuth;
  
  		if (slot->a != DEFAULT_ZERO) {
00720277a   Wei-Ning Huang   HID: hid-multitou...
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
  			/*
  			 * Azimuth is counter-clockwise and ranges from [0, MAX)
  			 * (a full revolution). Convert it to clockwise ranging
  			 * [-MAX/2, MAX/2].
  			 *
  			 * Note that ABS_MT_ORIENTATION require us to report
  			 * the limit of [-MAX/4, MAX/4], but the value can go
  			 * out of range to [-MAX/2, MAX/2] to report an upside
  			 * down ellipsis.
  			 */
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1020
1021
1022
1023
1024
1025
1026
  			azimuth = *slot->a;
  			max_azimuth = input_abs_get_max(input,
  							ABS_MT_ORIENTATION);
  			if (azimuth > max_azimuth * 2)
  				azimuth -= max_azimuth * 4;
  			orientation = -azimuth;
  		}
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1027

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1028
  		if (quirks & MT_QUIRK_TOUCH_SIZE_SCALING) {
9152c7d77   Dmitry Torokhov   HID: multitouch: ...
1029
1030
1031
1032
  			/*
  			 * divided by two to match visual scale of touch
  			 * for devices with this quirk
  			 */
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1033
1034
1035
  			major = major >> 1;
  			minor = minor >> 1;
  		}
55746d28d   Hans de Goede   HID: multitouch: ...
1036

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  		input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x);
  		input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y);
  		input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx);
  		input_event(input, EV_ABS, ABS_MT_TOOL_Y, *slot->cy);
  		input_event(input, EV_ABS, ABS_MT_DISTANCE, !*slot->tip_state);
  		input_event(input, EV_ABS, ABS_MT_ORIENTATION, orientation);
  		input_event(input, EV_ABS, ABS_MT_PRESSURE, *slot->p);
  		input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
  		input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
  
  		set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
  	}
127e71bd4   Hans de Goede   HID: multitouch: ...
1049

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
  	return 0;
  }
  
  static void mt_process_mt_event(struct hid_device *hid,
  				struct mt_application *app,
  				struct hid_field *field,
  				struct hid_usage *usage,
  				__s32 value,
  				bool first_packet)
  {
  	__s32 quirks = app->quirks;
  	struct input_dev *input = field->hidinput->input;
  
  	if (!usage->type || !(hid->claimed & HID_CLAIMED_INPUT))
  		return;
  
  	if (quirks & MT_QUIRK_WIN8_PTP_BUTTONS) {
  
  		/*
  		 * For Win8 PTP touchpads we should only look at
  		 * non finger/touch events in the first_packet of a
  		 * (possible) multi-packet frame.
  		 */
  		if (!first_packet)
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1074
  			return;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1075

01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
  		/*
  		 * For Win8 PTP touchpads we map both the clickpad click
  		 * and any "external" left buttons to BTN_LEFT if a
  		 * device claims to have both we need to report 1 for
  		 * BTN_LEFT if either is pressed, so we or all values
  		 * together and report the result in mt_sync_frame().
  		 */
  		if (usage->type == EV_KEY && usage->code == BTN_LEFT) {
  			app->left_button_state |= value;
  			return;
54f4c0c3e   Benjamin Tissoires   HID: multitouch: ...
1086
  		}
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
1087
  	}
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1088
1089
  
  	input_event(input, usage->type, usage->code, value);
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1090
  }
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1091

8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1092
1093
  static void mt_touch_report(struct hid_device *hid,
  			    struct mt_report_data *rdata)
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1094
1095
  {
  	struct mt_device *td = hid_get_drvdata(hid);
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1096
1097
  	struct hid_report *report = rdata->report;
  	struct mt_application *app = rdata->application;
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1098
  	struct hid_field *field;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1099
1100
  	struct input_dev *input;
  	struct mt_usages *slot;
55746d28d   Hans de Goede   HID: multitouch: ...
1101
  	bool first_packet;
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1102
  	unsigned count;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1103
1104
1105
  	int r, n;
  	int scantime = 0;
  	int contact_count = -1;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1106

4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1107
1108
1109
  	/* sticky fingers release in progress, abort */
  	if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
  		return;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1110
1111
1112
1113
  	scantime = *app->scantime;
  	app->timestamp = mt_compute_timestamp(app, scantime);
  	if (app->raw_cc != DEFAULT_ZERO)
  		contact_count = *app->raw_cc;
c2517f62d   Benjamin Tissoires   HID: multitouch: ...
1114
1115
1116
1117
  	/*
  	 * Includes multi-packet support where subsequent
  	 * packets are sent with zero contactcount.
  	 */
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1118
  	if (contact_count >= 0) {
af8dc4d09   Hans de Goede   HID: multitouch: ...
1119
1120
1121
1122
1123
1124
1125
  		/*
  		 * For Win8 PTPs the first packet (td->num_received == 0) may
  		 * have a contactcount of 0 if there only is a button event.
  		 * We double check that this is not a continuation packet
  		 * of a possible multi-packet frame be checking that the
  		 * timestamp has changed.
  		 */
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1126
  		if ((app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1127
1128
1129
  		    app->num_received == 0 &&
  		    app->prev_scantime != scantime)
  			app->num_expected = contact_count;
af8dc4d09   Hans de Goede   HID: multitouch: ...
1130
  		/* A non 0 contact count always indicates a first packet */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1131
1132
  		else if (contact_count)
  			app->num_expected = contact_count;
7e3cc447f   Benjamin Tissoires   HID: multitouch: ...
1133
  	}
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1134
  	app->prev_scantime = scantime;
c2517f62d   Benjamin Tissoires   HID: multitouch: ...
1135

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1136
  	first_packet = app->num_received == 0;
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1137
1138
1139
1140
1141
1142
1143
  
  	input = report->field[0]->hidinput->input;
  
  	list_for_each_entry(slot, &app->mt_usages, list) {
  		if (!mt_process_slot(td, input, app, slot))
  			app->num_received++;
  	}
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1144
1145
1146
1147
1148
1149
1150
1151
  	for (r = 0; r < report->maxfield; r++) {
  		field = report->field[r];
  		count = field->report_count;
  
  		if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
  			continue;
  
  		for (n = 0; n < count; n++)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1152
1153
1154
  			mt_process_mt_event(hid, app, field,
  					    &field->usage[n], field->value[n],
  					    first_packet);
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
1155
  	}
5b62efd82   Benjamin Tissoires   HID: multitouch: ...
1156

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1157
  	if (app->num_received >= app->num_expected)
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1158
  		mt_sync_frame(td, app, input);
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  
  	/*
  	 * Windows 8 specs says 2 things:
  	 * - once a contact has been reported, it has to be reported in each
  	 *   subsequent report
  	 * - the report rate when fingers are present has to be at least
  	 *   the refresh rate of the screen, 60 or 120 Hz
  	 *
  	 * I interprete this that the specification forces a report rate of
  	 * at least 60 Hz for a touchscreen to be certified.
  	 * Which means that if we do not get a report whithin 16 ms, either
  	 * something wrong happens, either the touchscreen forgets to send
  	 * a release. Taking a reasonable margin allows to remove issues
  	 * with USB communication or the load of the machine.
  	 *
  	 * Given that Win 8 devices are forced to send a release, this will
  	 * only affect laggish machines and the ones that have a firmware
  	 * defect.
  	 */
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1178
  	if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
960982745   Benjamin Tissoires   HID: multitouch: ...
1179
1180
1181
1182
1183
1184
  		if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
  			mod_timer(&td->release_timer,
  				  jiffies + msecs_to_jiffies(100));
  		else
  			del_timer(&td->release_timer);
  	}
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1185
1186
  
  	clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1187
  }
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1188
  static int mt_touch_input_configured(struct hid_device *hdev,
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1189
1190
  				     struct hid_input *hi,
  				     struct mt_application *app)
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1191
1192
1193
1194
  {
  	struct mt_device *td = hid_get_drvdata(hdev);
  	struct mt_class *cls = &td->mtclass;
  	struct input_dev *input = hi->input;
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1195
  	int ret;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1196
1197
1198
  
  	if (!td->maxcontacts)
  		td->maxcontacts = MT_DEFAULT_MAXCONTACT;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1199
  	mt_post_parse(td, app);
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1200
  	if (td->serial_maybe)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1201
  		mt_post_parse_default_settings(td, app);
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1202
1203
  
  	if (cls->is_indirect)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1204
  		app->mt_flags |= INPUT_MT_POINTER;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1205

3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1206
  	if (app->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1207
  		app->mt_flags |= INPUT_MT_DROP_UNUSED;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1208

015fdaa9f   Benjamin Tissoires   HID: multitouch: ...
1209
  	/* check for clickpads */
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1210
1211
  	if ((app->mt_flags & INPUT_MT_POINTER) &&
  	    (app->buttons_count == 1))
2c6e0277e   Seth Forshee   HID: multitouch: ...
1212
1213
1214
  		td->is_buttonpad = true;
  
  	if (td->is_buttonpad)
015fdaa9f   Benjamin Tissoires   HID: multitouch: ...
1215
  		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
28a042a3b   Dmitry Torokhov   HID: multitouch: ...
1216
1217
1218
1219
1220
1221
  	app->pending_palm_slots = devm_kcalloc(&hi->input->dev,
  					       BITS_TO_LONGS(td->maxcontacts),
  					       sizeof(long),
  					       GFP_KERNEL);
  	if (!app->pending_palm_slots)
  		return -ENOMEM;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1222
  	ret = input_mt_init_slots(input, td->maxcontacts, app->mt_flags);
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1223
1224
  	if (ret)
  		return ret;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1225

f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1226
  	app->mt_flags = 0;
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1227
  	return 0;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1228
  }
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1229
1230
  #define mt_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, \
  						    max, EV_KEY, (c))
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1231
1232
1233
1234
  static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  		struct hid_field *field, struct hid_usage *usage,
  		unsigned long **bit, int *max)
  {
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1235
  	struct mt_device *td = hid_get_drvdata(hdev);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1236
  	struct mt_application *application;
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1237
1238
1239
1240
1241
1242
1243
1244
  	struct mt_report_data *rdata;
  
  	rdata = mt_find_report_data(td, field->report);
  	if (!rdata) {
  		hid_err(hdev, "failed to allocate data for report
  ");
  		return 0;
  	}
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1245

8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1246
  	application = rdata->application;
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1247

6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1248
1249
1250
1251
1252
1253
1254
1255
  	/*
  	 * If mtclass.export_all_inputs is not set, only map fields from
  	 * TouchScreen or TouchPad collections. We need to ignore fields
  	 * that belong to other collections such as Mouse that might have
  	 * the same GenericDesktop usages.
  	 */
  	if (!td->mtclass.export_all_inputs &&
  	    field->application != HID_DG_TOUCHSCREEN &&
fa11aa72b   Benjamin Tissoires   HID: multitouch: ...
1256
  	    field->application != HID_DG_PEN &&
8fe89ef07   Benjamin Tissoires   HID: multitouch: ...
1257
1258
  	    field->application != HID_DG_TOUCHPAD &&
  	    field->application != HID_GD_KEYBOARD &&
e57f4e67a   Hans de Goede   HID: multitouch: ...
1259
  	    field->application != HID_GD_SYSTEM_CONTROL &&
1fbf74efe   João Paulo Rechi Vita   HID: multitouch: ...
1260
  	    field->application != HID_CP_CONSUMER_CONTROL &&
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1261
  	    field->application != HID_GD_WIRELESS_RADIO_CTLS &&
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
1262
  	    field->application != HID_GD_SYSTEM_MULTIAXIS &&
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1263
  	    !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1264
  	      application->quirks & MT_QUIRK_ASUS_CUSTOM_UP))
6f492f287   Benjamin Tissoires   HID: multitouch: ...
1265
  		return -1;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1266

6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1267
  	/*
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1268
1269
1270
1271
  	 * Some Asus keyboard+touchpad devices have the hotkeys defined in the
  	 * touchpad report descriptor. We need to treat these as an array to
  	 * map usages to input keys.
  	 */
39bbf4022   Jiri Kosina   HID: multitouch: ...
1272
  	if (field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1273
  	    application->quirks & MT_QUIRK_ASUS_CUSTOM_UP &&
957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
  	    (usage->hid & HID_USAGE_PAGE) == HID_UP_CUSTOM) {
  		set_bit(EV_REP, hi->input->evbit);
  		if (field->flags & HID_MAIN_ITEM_VARIABLE)
  			field->flags &= ~HID_MAIN_ITEM_VARIABLE;
  		switch (usage->hid & HID_USAGE) {
  		case 0x10: mt_map_key_clear(KEY_BRIGHTNESSDOWN);	break;
  		case 0x20: mt_map_key_clear(KEY_BRIGHTNESSUP);		break;
  		case 0x35: mt_map_key_clear(KEY_DISPLAY_OFF);		break;
  		case 0x6b: mt_map_key_clear(KEY_F21);			break;
  		case 0x6c: mt_map_key_clear(KEY_SLEEP);			break;
  		default:
  			return -1;
  		}
  		return 1;
  	}
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
1289
  	if (rdata->is_mt_collection)
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1290
1291
  		return mt_touch_input_mapping(hdev, hi, field, usage, bit, max,
  					      application);
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1292

7ffa13be4   Benjamin Tissoires   HID: multitouch: ...
1293
1294
1295
1296
1297
1298
  	/*
  	 * some egalax touchscreens have "application == DG_TOUCHSCREEN"
  	 * for the stylus. Overwrite the hid_input application
  	 */
  	if (field->physical == HID_DG_STYLUS)
  		hi->application = HID_DG_STYLUS;
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1299
1300
  	/* let hid-core decide for the others */
  	return 0;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1301
1302
1303
1304
1305
1306
  }
  
  static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
  		struct hid_field *field, struct hid_usage *usage,
  		unsigned long **bit, int *max)
  {
ba6b055e0   Benjamin Tissoires   HID: input: enabl...
1307
1308
  	struct mt_device *td = hid_get_drvdata(hdev);
  	struct mt_report_data *rdata;
fa11aa72b   Benjamin Tissoires   HID: multitouch: ...
1309

ba6b055e0   Benjamin Tissoires   HID: input: enabl...
1310
1311
  	rdata = mt_find_report_data(td, field->report);
  	if (rdata && rdata->is_mt_collection) {
4cf56a89c   Dmitry Torokhov   HID: multitouch: ...
1312
1313
1314
  		/* We own these mappings, tell hid-input to ignore them */
  		return -1;
  	}
6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1315
1316
1317
  
  	/* let hid-core decide for the others */
  	return 0;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1318
1319
1320
1321
1322
1323
  }
  
  static int mt_event(struct hid_device *hid, struct hid_field *field,
  				struct hid_usage *usage, __s32 value)
  {
  	struct mt_device *td = hid_get_drvdata(hid);
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1324
  	struct mt_report_data *rdata;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1325

8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1326
1327
  	rdata = mt_find_report_data(td, field->report);
  	if (rdata && rdata->is_mt_collection)
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1328
  		return mt_touch_event(hid, field, usage, value);
e55f62008   Benjamin Tissoires   HID: multitouch: ...
1329
  	return 0;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1330
1331
1332
1333
1334
  }
  
  static void mt_report(struct hid_device *hid, struct hid_report *report)
  {
  	struct mt_device *td = hid_get_drvdata(hid);
e55f62008   Benjamin Tissoires   HID: multitouch: ...
1335
  	struct hid_field *field = report->field[0];
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1336
  	struct mt_report_data *rdata;
a69c5f8b1   Benjamin Tissoires   HID: multitouch: ...
1337
1338
1339
  
  	if (!(hid->claimed & HID_CLAIMED_INPUT))
  		return;
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1340
1341
1342
  	rdata = mt_find_report_data(td, report);
  	if (rdata && rdata->is_mt_collection)
  		return mt_touch_report(hid, rdata);
fa11aa72b   Benjamin Tissoires   HID: multitouch: ...
1343

e55f62008   Benjamin Tissoires   HID: multitouch: ...
1344
1345
  	if (field && field->hidinput && field->hidinput->input)
  		input_sync(field->hidinput->input);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1346
  }
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1347
1348
  static bool mt_need_to_apply_feature(struct hid_device *hdev,
  				     struct hid_field *field,
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1349
1350
1351
  				     struct hid_usage *usage,
  				     enum latency_mode latency,
  				     bool surface_switch,
ec6adef5f   Benjamin Tissoires   HID: multitouch: ...
1352
1353
  				     bool button_switch,
  				     bool *inputmode_found)
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1354
1355
  {
  	struct mt_device *td = hid_get_drvdata(hdev);
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1356
  	struct mt_class *cls = &td->mtclass;
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1357
1358
  	struct hid_report *report = field->report;
  	unsigned int index = usage->usage_index;
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1359
  	char *buf;
3064a03b9   Aaron Ma   HID: Fix hid_repo...
1360
  	u32 report_len;
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1361
  	int max;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1362

7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1363
1364
  	switch (usage->hid) {
  	case HID_DG_INPUTMODE:
ec6adef5f   Benjamin Tissoires   HID: multitouch: ...
1365
1366
1367
1368
1369
1370
1371
  		/*
  		 * Some elan panels wrongly declare 2 input mode features,
  		 * and silently ignore when we set the value in the second
  		 * field. Skip the second feature and hope for the best.
  		 */
  		if (*inputmode_found)
  			return false;
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1372
  		if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1373
1374
  			report_len = hid_report_len(report);
  			buf = hid_alloc_report_buf(report, GFP_KERNEL);
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1375
  			if (!buf) {
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1376
1377
1378
1379
  				hid_err(hdev,
  					"failed to allocate buffer for report
  ");
  				return false;
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1380
  			}
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1381
  			hid_hw_raw_request(hdev, report->id, buf, report_len,
da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1382
1383
1384
1385
  					   HID_FEATURE_REPORT,
  					   HID_REQ_GET_REPORT);
  			kfree(buf);
  		}
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1386

7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1387
  		field->value[index] = td->inputmode_value;
ec6adef5f   Benjamin Tissoires   HID: multitouch: ...
1388
  		*inputmode_found = true;
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1389
  		return true;
31ae9bddb   Benjamin Tissoires   HID: multitouch: ...
1390

7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1391
  	case HID_DG_CONTACTMAX:
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1392
  		if (cls->maxcontacts) {
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1393
  			max = min_t(int, field->logical_maximum,
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1394
  				    cls->maxcontacts);
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1395
1396
1397
1398
1399
1400
  			if (field->value[index] != max) {
  				field->value[index] = max;
  				return true;
  			}
  		}
  		break;
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1401
1402
1403
  
  	case HID_DG_LATENCYMODE:
  		field->value[index] = latency;
99c703aca   Jiri Kosina   HID: multitouch: ...
1404
  		return true;
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1405
1406
1407
  
  	case HID_DG_SURFACESWITCH:
  		field->value[index] = surface_switch;
99c703aca   Jiri Kosina   HID: multitouch: ...
1408
  		return true;
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1409
1410
1411
  
  	case HID_DG_BUTTONSWITCH:
  		field->value[index] = button_switch;
99c703aca   Jiri Kosina   HID: multitouch: ...
1412
  		return true;
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1413
  	}
31ae9bddb   Benjamin Tissoires   HID: multitouch: ...
1414

7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1415
1416
  	return false; /* no need to update the report */
  }
31ae9bddb   Benjamin Tissoires   HID: multitouch: ...
1417

02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1418
1419
  static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
  			 bool surface_switch, bool button_switch)
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1420
1421
1422
1423
1424
1425
  {
  	struct hid_report_enum *rep_enum;
  	struct hid_report *rep;
  	struct hid_usage *usage;
  	int i, j;
  	bool update_report;
ec6adef5f   Benjamin Tissoires   HID: multitouch: ...
1426
  	bool inputmode_found = false;
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
  
  	rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
  	list_for_each_entry(rep, &rep_enum->report_list, list) {
  		update_report = false;
  
  		for (i = 0; i < rep->maxfield; i++) {
  			/* Ignore if report count is out of bounds. */
  			if (rep->field[i]->report_count < 1)
  				continue;
  
  			for (j = 0; j < rep->field[i]->maxusage; j++) {
  				usage = &rep->field[i]->usage[j];
  
  				if (mt_need_to_apply_feature(hdev,
  							     rep->field[i],
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1442
1443
1444
  							     usage,
  							     latency,
  							     surface_switch,
ec6adef5f   Benjamin Tissoires   HID: multitouch: ...
1445
1446
  							     button_switch,
  							     &inputmode_found))
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1447
1448
  					update_report = true;
  			}
31ae9bddb   Benjamin Tissoires   HID: multitouch: ...
1449
  		}
7f81c8db5   Benjamin Tissoires   HID: multitouch: ...
1450
1451
1452
  
  		if (update_report)
  			hid_hw_request(hdev, rep, HID_REQ_SET_REPORT);
31ae9bddb   Benjamin Tissoires   HID: multitouch: ...
1453
1454
  	}
  }
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1455
1456
  static void mt_post_parse_default_settings(struct mt_device *td,
  					   struct mt_application *app)
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
1457
  {
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1458
  	__s32 quirks = app->quirks;
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
1459
1460
  
  	/* unknown serial device needs special quirks */
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1461
  	if (list_is_singular(&app->mt_usages)) {
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
1462
1463
1464
1465
  		quirks |= MT_QUIRK_ALWAYS_VALID;
  		quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
  		quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
  		quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
e0bb8f9ad   Benjamin Tissoires   HID: multitouch: ...
1466
  		quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
1467
  	}
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1468
  	app->quirks = quirks;
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
1469
  }
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1470
  static void mt_post_parse(struct mt_device *td, struct mt_application *app)
3ac36d155   Benjamin Tissoires   HID: hid-multitou...
1471
  {
01eaac7e5   Benjamin Tissoires   HID: multitouch: ...
1472
  	if (!app->have_contact_count)
3ceb38264   Benjamin Tissoires   HID: multitouch: ...
1473
  		app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
3ac36d155   Benjamin Tissoires   HID: hid-multitou...
1474
  }
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1475
  static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
76f5902ae   Henrik Rydberg   HID: hid-multitou...
1476
1477
  {
  	struct mt_device *td = hid_get_drvdata(hdev);
c08d46aa8   Benjamin Tissoires   HID: multitouch: ...
1478
1479
  	char *name;
  	const char *suffix = NULL;
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1480
  	struct mt_report_data *rdata;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1481
  	struct mt_application *mt_application = NULL;
40ec26036   Benjamin Tissoires   HID: multitouch: ...
1482
  	struct hid_report *report;
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1483
  	int ret;
76f5902ae   Henrik Rydberg   HID: hid-multitou...
1484

40ec26036   Benjamin Tissoires   HID: multitouch: ...
1485
  	list_for_each_entry(report, &hi->reports, hidinput_list) {
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1486
1487
1488
1489
1490
1491
1492
1493
  		rdata = mt_find_report_data(td, report);
  		if (!rdata) {
  			hid_err(hdev, "failed to allocate data for report
  ");
  			return -ENOMEM;
  		}
  
  		mt_application = rdata->application;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1494

8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1495
  		if (rdata->is_mt_collection) {
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1496
1497
  			ret = mt_touch_input_configured(hdev, hi,
  							mt_application);
40ec26036   Benjamin Tissoires   HID: multitouch: ...
1498
1499
1500
  			if (ret)
  				return ret;
  		}
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1501
  	}
76f5902ae   Henrik Rydberg   HID: hid-multitou...
1502

7ffa13be4   Benjamin Tissoires   HID: multitouch: ...
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
  	switch (hi->application) {
  	case HID_GD_KEYBOARD:
  	case HID_GD_KEYPAD:
  	case HID_GD_MOUSE:
  	case HID_DG_TOUCHPAD:
  	case HID_GD_SYSTEM_CONTROL:
  	case HID_CP_CONSUMER_CONTROL:
  	case HID_GD_WIRELESS_RADIO_CTLS:
  	case HID_GD_SYSTEM_MULTIAXIS:
  		/* already handled by hid core */
  		break;
  	case HID_DG_TOUCHSCREEN:
  		/* we do not set suffix = "Touchscreen" */
  		hi->input->name = hdev->name;
  		break;
  	case HID_DG_STYLUS:
  		/* force BTN_STYLUS to allow tablet matching in udev */
  		__set_bit(BTN_STYLUS, hi->input->keybit);
  		break;
  	case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
  		suffix = "Custom Media Keys";
  		break;
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
1525
1526
1527
  	case HID_DG_PEN:
  		suffix = "Stylus";
  		break;
7ffa13be4   Benjamin Tissoires   HID: multitouch: ...
1528
1529
1530
  	default:
  		suffix = "UNKNOWN";
  		break;
c08d46aa8   Benjamin Tissoires   HID: multitouch: ...
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
  	}
  
  	if (suffix) {
  		name = devm_kzalloc(&hi->input->dev,
  				    strlen(hdev->name) + strlen(suffix) + 2,
  				    GFP_KERNEL);
  		if (name) {
  			sprintf(name, "%s %s", hdev->name, suffix);
  			hi->input->name = name;
  		}
  	}
b2c68a2f1   Dmitry Torokhov   HID: hid-input: a...
1542
1543
  
  	return 0;
76f5902ae   Henrik Rydberg   HID: hid-multitou...
1544
  }
f3287a995   Benjamin Tissoires   HID: multitouch: ...
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
  static void mt_fix_const_field(struct hid_field *field, unsigned int usage)
  {
  	if (field->usage[0].hid != usage ||
  	    !(field->flags & HID_MAIN_ITEM_CONSTANT))
  		return;
  
  	field->flags &= ~HID_MAIN_ITEM_CONSTANT;
  	field->flags |= HID_MAIN_ITEM_VARIABLE;
  }
  
  static void mt_fix_const_fields(struct hid_device *hdev, unsigned int usage)
  {
  	struct hid_report *report;
  	int i;
  
  	list_for_each_entry(report,
  			    &hdev->report_enum[HID_INPUT_REPORT].report_list,
  			    list) {
  
  		if (!report->maxfield)
  			continue;
  
  		for (i = 0; i < report->maxfield; i++)
  			if (report->field[i]->maxusage >= 1)
  				mt_fix_const_field(report->field[i], usage);
  	}
  }
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1572
1573
1574
  static void mt_release_contacts(struct hid_device *hid)
  {
  	struct hid_input *hidinput;
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1575
  	struct mt_application *application;
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
  	struct mt_device *td = hid_get_drvdata(hid);
  
  	list_for_each_entry(hidinput, &hid->inputs, list) {
  		struct input_dev *input_dev = hidinput->input;
  		struct input_mt *mt = input_dev->mt;
  		int i;
  
  		if (mt) {
  			for (i = 0; i < mt->num_slots; i++) {
  				input_mt_slot(input_dev, i);
5fc70e350   Jiada Wang   Input: introduce ...
1586
  				input_mt_report_slot_inactive(input_dev);
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1587
1588
1589
1590
1591
  			}
  			input_mt_sync_frame(input_dev);
  			input_sync(input_dev);
  		}
  	}
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1592
1593
1594
  	list_for_each_entry(application, &td->applications, list) {
  		application->num_received = 0;
  	}
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1595
  }
0ee32774a   Kees Cook   HID: usbhid: Conv...
1596
  static void mt_expired_timeout(struct timer_list *t)
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1597
  {
0ee32774a   Kees Cook   HID: usbhid: Conv...
1598
1599
  	struct mt_device *td = from_timer(td, t, release_timer);
  	struct hid_device *hdev = td->hdev;
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1600
1601
1602
1603
1604
1605
1606
  
  	/*
  	 * An input report came in just before we release the sticky fingers,
  	 * it will take care of the sticky fingers.
  	 */
  	if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
  		return;
960982745   Benjamin Tissoires   HID: multitouch: ...
1607
1608
  	if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
  		mt_release_contacts(hdev);
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1609
1610
  	clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
  }
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1611
1612
  static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
  {
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
1613
  	int ret, i;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1614
  	struct mt_device *td;
cf6d15d7b   Benjamin Tissoires   HID: multitouch: ...
1615
  	const struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
1616

94b5485cd   Henrik Rydberg   HID: hid-multitou...
1617
1618
1619
1620
  	for (i = 0; mt_classes[i].name ; i++) {
  		if (id->driver_data == mt_classes[i].name) {
  			mtclass = &(mt_classes[i]);
  			break;
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
1621
1622
  		}
  	}
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1623

c08d46aa8   Benjamin Tissoires   HID: multitouch: ...
1624
  	td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1625
1626
1627
1628
1629
  	if (!td) {
  		dev_err(&hdev->dev, "cannot allocate multitouch data
  ");
  		return -ENOMEM;
  	}
0ee32774a   Kees Cook   HID: usbhid: Conv...
1630
  	td->hdev = hdev;
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
1631
  	td->mtclass = *mtclass;
9abebedb1   Andrew Duggan   HID: multitouch: ...
1632
  	td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1633
  	hid_set_drvdata(hdev, td);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1634
  	INIT_LIST_HEAD(&td->applications);
8dfe14b3b   Benjamin Tissoires   HID: multitouch: ...
1635
  	INIT_LIST_HEAD(&td->reports);
f146d1c4d   Benjamin Tissoires   HID: multitouch: ...
1636

76f5902ae   Henrik Rydberg   HID: hid-multitou...
1637
1638
  	if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
  		td->serial_maybe = true;
b897f6db3   Benjamin Tissoires   HID: multitouch: ...
1639
1640
1641
1642
1643
1644
1645
  	/* This allows the driver to correctly support devices
  	 * that emit events over several HID messages.
  	 */
  	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
  
  	/*
  	 * This allows the driver to handle different input sensors
40ec26036   Benjamin Tissoires   HID: multitouch: ...
1646
  	 * that emits events through different applications on the same HID
b897f6db3   Benjamin Tissoires   HID: multitouch: ...
1647
1648
  	 * device.
  	 */
40ec26036   Benjamin Tissoires   HID: multitouch: ...
1649
  	hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
b897f6db3   Benjamin Tissoires   HID: multitouch: ...
1650

0d6c30114   Benjamin Tissoires   HID: core: fix gr...
1651
1652
  	if (id->group != HID_GROUP_MULTITOUCH_WIN_8)
  		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
40d5bb873   Benjamin Tissoires   HID: multitouch: ...
1653
1654
1655
1656
  	if (mtclass->quirks & MT_QUIRK_FORCE_MULTI_INPUT) {
  		hdev->quirks &= ~HID_QUIRK_INPUT_PER_APP;
  		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
  	}
0ee32774a   Kees Cook   HID: usbhid: Conv...
1657
  	timer_setup(&td->release_timer, mt_expired_timeout, 0);
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1658

5519cab47   Benjamin Tissoires   HID: hid-multitou...
1659
1660
  	ret = hid_parse(hdev);
  	if (ret != 0)
c08d46aa8   Benjamin Tissoires   HID: multitouch: ...
1661
  		return ret;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1662

f3287a995   Benjamin Tissoires   HID: multitouch: ...
1663
1664
  	if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)
  		mt_fix_const_fields(hdev, HID_DG_CONTACTID);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1665
  	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2d93666e7   Benjamin Tissoires   HID: hid-multitou...
1666
  	if (ret)
c08d46aa8   Benjamin Tissoires   HID: multitouch: ...
1667
  		return ret;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1668

eec29e3da   Benjamin Tissoires   HID: multitouch: ...
1669
  	ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
0c4b3c637   Nicholas Krause   HID: multitouch: ...
1670
1671
1672
1673
  	if (ret)
  		dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s
  ",
  				hdev->name);
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
1674

02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1675
  	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1676
1677
  
  	return 0;
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1678
1679
1680
1681
1682
  }
  
  #ifdef CONFIG_PM
  static int mt_reset_resume(struct hid_device *hdev)
  {
d3e69b9a0   Benson Leung   HID: multitouch: ...
1683
  	mt_release_contacts(hdev);
02946f4b4   Benjamin Tissoires   HID: multitouch: ...
1684
  	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1685
1686
  	return 0;
  }
dfeefd108   Scott Liu   HID: multitouch: ...
1687
1688
1689
  
  static int mt_resume(struct hid_device *hdev)
  {
dfeefd108   Scott Liu   HID: multitouch: ...
1690
1691
1692
  	/* Some Elan legacy devices require SET_IDLE to be set on resume.
  	 * It should be safe to send it to other devices too.
  	 * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */
4ba25d3f8   Benjamin Tissoires   HID: multitouch: ...
1693
  	hid_hw_idle(hdev, 0, 0, HID_REQ_SET_IDLE);
dfeefd108   Scott Liu   HID: multitouch: ...
1694
1695
1696
  
  	return 0;
  }
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1697
1698
1699
1700
  #endif
  
  static void mt_remove(struct hid_device *hdev)
  {
b897f6db3   Benjamin Tissoires   HID: multitouch: ...
1701
  	struct mt_device *td = hid_get_drvdata(hdev);
4f4001bc7   Benjamin Tissoires   HID: multitouch: ...
1702
  	del_timer_sync(&td->release_timer);
eec29e3da   Benjamin Tissoires   HID: multitouch: ...
1703
  	sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
5939212df   Benjamin Tissoires   HID: multitouch: ...
1704
  	hid_hw_stop(hdev);
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1705
  }
0fa9c6161   Benjamin Tissoires   HID: multitouch: ...
1706
1707
1708
1709
1710
1711
  /*
   * This list contains only:
   * - VID/PID of products not working with the default multitouch handling
   * - 2 generic rules.
   * So there is no point in adding here any device with MT_CLS_DEFAULT.
   */
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1712
  static const struct hid_device_id mt_devices[] = {
f786bba44   Benjamin Tissoires   HID: hid-multitou...
1713
1714
  	/* 3M panels */
  	{ .driver_data = MT_CLS_3M,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1715
  		MT_USB_DEVICE(USB_VENDOR_ID_3M,
f786bba44   Benjamin Tissoires   HID: hid-multitou...
1716
1717
  			USB_DEVICE_ID_3M1968) },
  	{ .driver_data = MT_CLS_3M,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1718
  		MT_USB_DEVICE(USB_VENDOR_ID_3M,
f786bba44   Benjamin Tissoires   HID: hid-multitou...
1719
  			USB_DEVICE_ID_3M2256) },
c4fad877c   Benjamin Tissoires   HID: multitouch: ...
1720
  	{ .driver_data = MT_CLS_3M,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1721
  		MT_USB_DEVICE(USB_VENDOR_ID_3M,
c4fad877c   Benjamin Tissoires   HID: multitouch: ...
1722
  			USB_DEVICE_ID_3M3266) },
f786bba44   Benjamin Tissoires   HID: hid-multitou...
1723

6aef704e3   Benjamin Tissoires   HID: multitouch: ...
1724
1725
1726
1727
  	/* Anton devices */
  	{ .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
  		MT_USB_DEVICE(USB_VENDOR_ID_ANTON,
  			USB_DEVICE_ID_ANTON_TOUCH_PAD) },
e6aac3427   Benjamin Tissoires   HID: hid-multitou...
1728

957b8dffa   João Paulo Rechi Vita   HID: multitouch: ...
1729
1730
1731
1732
1733
  	/* Asus T304UA */
  	{ .driver_data = MT_CLS_ASUS,
  		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
  			USB_VENDOR_ID_ASUSTEK,
  			USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD) },
b10571246   Benjamin Tissoires   HID: multitouch: ...
1734
1735
  	/* Atmel panels */
  	{ .driver_data = MT_CLS_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1736
  		MT_USB_DEVICE(USB_VENDOR_ID_ATMEL,
841cb1570   Benjamin Tissoires   HID: multitouch: ...
1737
  			USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) },
b10571246   Benjamin Tissoires   HID: multitouch: ...
1738

9ed326951   Jiri Kosina   HID: multitouch: ...
1739
  	/* Baanto multitouch devices */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1740
  	{ .driver_data = MT_CLS_NSMU,
16b79bb8e   Jiri Kosina   HID: multitouch: ...
1741
  		MT_USB_DEVICE(USB_VENDOR_ID_BAANTO,
9ed326951   Jiri Kosina   HID: multitouch: ...
1742
  			USB_DEVICE_ID_BAANTO_MT_190W2) },
0fa9c6161   Benjamin Tissoires   HID: multitouch: ...
1743

a841b62c5   Benjamin Tissoires   HID: hid-multitou...
1744
1745
  	/* Cando panels */
  	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1746
  		MT_USB_DEVICE(USB_VENDOR_ID_CANDO,
a841b62c5   Benjamin Tissoires   HID: hid-multitou...
1747
  			USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
a841b62c5   Benjamin Tissoires   HID: hid-multitou...
1748
  	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1749
  		MT_USB_DEVICE(USB_VENDOR_ID_CANDO,
a841b62c5   Benjamin Tissoires   HID: hid-multitou...
1750
  			USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
942fd4225   Austin Zhang   HID: hid-multitou...
1751
  	/* Chunghwa Telecom touch panels */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1752
  	{  .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1753
  		MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
942fd4225   Austin Zhang   HID: hid-multitou...
1754
  			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
070f63b46   Yang Bo   HID: multitouch: ...
1755
1756
1757
1758
1759
1760
1761
  	/* CJTouch panels */
  	{ .driver_data = MT_CLS_NSMU,
  		MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH,
  			USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020) },
  	{ .driver_data = MT_CLS_NSMU,
  		MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH,
  			USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040) },
79603dc9a   Benjamin Tissoires   HID: hid-multitou...
1762
  	/* CVTouch panels */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1763
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1764
  		MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
79603dc9a   Benjamin Tissoires   HID: hid-multitou...
1765
  			USB_DEVICE_ID_CVTOUCH_SCREEN) },
22408283b   Benjamin Tissoires   HID: hid-multitou...
1766
  	/* eGalax devices (resistive) */
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1767
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1768
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1769
1770
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1771
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1772
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
22408283b   Benjamin Tissoires   HID: hid-multitou...
1773
1774
  
  	/* eGalax devices (capacitive) */
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1775
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1776
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1777
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) },
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1778
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1779
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1780
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1781
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1782
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1783
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
2ce09df47   Benjamin Tissoires   HID: multitouch: ...
1784
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1785
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
2ce09df47   Benjamin Tissoires   HID: multitouch: ...
1786
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) },
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1787
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1788
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1789
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1790
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1791
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1792
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) },
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1793
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1794
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1795
1796
1797
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
  	{ .driver_data = MT_CLS_EGALAX,
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1798
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1799
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1800
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1801
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) },
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1802
  	{ .driver_data = MT_CLS_EGALAX,
aa672da1b   Andy Shevchenko   HID: sort IDs for...
1803
1804
1805
1806
1807
1808
  		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) },
  	{ .driver_data = MT_CLS_EGALAX,
  		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0) },
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1809
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
66f06127f   Benjamin Tissoires   HID: multitouch: ...
1810
1811
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
  	{ .driver_data = MT_CLS_EGALAX,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1812
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
bb9ff2107   Marek Vasut   HID: multitouch: ...
1813
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
1b723e8dc   Benjamin Tissoires   HID: multitouch: ...
1814
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1815
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
fd1d15258   Benjamin Tissoires   HID: multitouch: ...
1816
1817
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) },
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1818
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
ae01c9e53   Thierry Reding   HID: multitouch: ...
1819
1820
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7) },
  	{ .driver_data = MT_CLS_EGALAX_SERIAL,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1821
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
e36f690b3   Benjamin Tissoires   HID: multitouch: ...
1822
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
f9e82295e   Sebastian Reichel   HID: multitouch: ...
1823
1824
1825
  	{ .driver_data = MT_CLS_EGALAX,
  		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
  			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) },
22408283b   Benjamin Tissoires   HID: hid-multitou...
1826

40d5bb873   Benjamin Tissoires   HID: multitouch: ...
1827
1828
1829
1830
  	/* Elan devices */
  	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
  		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
  			USB_VENDOR_ID_ELAN, 0x313a) },
7c7606a24   Tomas Sokorai   HID: multitouch: ...
1831
1832
1833
1834
  	/* Elitegroup panel */
  	{ .driver_data = MT_CLS_SERIAL,
  		MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
  			USB_DEVICE_ID_ELITEGROUP_05D8) },
77723e3bc   Henrik Rydberg   HID: hid-multitou...
1835
1836
1837
1838
  	/* Flatfrog Panels */
  	{ .driver_data = MT_CLS_FLATFROG,
  		MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG,
  			USB_DEVICE_ID_MULTITOUCH_3200) },
3db187e7b   Benjamin Tissoires   HID: multitouch: ...
1839
1840
1841
1842
  	/* FocalTech Panels */
  	{ .driver_data = MT_CLS_SERIAL,
  		MT_USB_DEVICE(USB_VENDOR_ID_CYGNAL,
  			USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH) },
5572da08a   Benjamin Tissoires   HID: hid-mulitouc...
1843
  	/* GeneralTouch panel */
f5ff4e1e6   Xianhan Yu   HID: multitouch: ...
1844
  	{ .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1845
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
5572da08a   Benjamin Tissoires   HID: hid-mulitouc...
1846
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
f5ff4e1e6   Xianhan Yu   HID: multitouch: ...
1847
1848
1849
  	{ .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) },
7b2262920   Luosong   HID: multitouch: ...
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
  	{ .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0101) },
  	{ .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0102) },
  	{ .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0106) },
  	{ .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A) },
  	{ .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
  		MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
  			USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100) },
5572da08a   Benjamin Tissoires   HID: hid-mulitouc...
1865

4d5df5d11   Andreas Nielsen   HID: multitouch: ...
1866
  	/* Gametel game controller */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1867
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1868
  		MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL,
4d5df5d11   Andreas Nielsen   HID: multitouch: ...
1869
  			USB_DEVICE_ID_GAMETEL_MT_MODE) },
ee0fbd149   Benjamin Tissoires   HID: hid-multitou...
1870
  	/* GoodTouch panels */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1871
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1872
  		MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
ee0fbd149   Benjamin Tissoires   HID: hid-multitou...
1873
  			USB_DEVICE_ID_GOODTOUCH_000f) },
545803651   Benjamin Tissoires   HID: hid-multitou...
1874
1875
  	/* Hanvon panels */
  	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1876
  		MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
545803651   Benjamin Tissoires   HID: hid-multitou...
1877
  			USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
4e61f0d75   Austin Zhang   HID: hid-multitou...
1878
  	/* Ilitek dual touch panel */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1879
  	{  .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1880
  		MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
4e61f0d75   Austin Zhang   HID: hid-multitou...
1881
  			USB_DEVICE_ID_ILITEK_MULTITOUCH) },
f3287a995   Benjamin Tissoires   HID: multitouch: ...
1882
1883
1884
1885
  	/* LG Melfas panel */
  	{ .driver_data = MT_CLS_LG,
  		HID_USB_DEVICE(USB_VENDOR_ID_LG,
  			USB_DEVICE_ID_LG_MELFAS_MT) },
348b80b27   Aaron Ma   HID: multitouch: ...
1886
1887
1888
  	{ .driver_data = MT_CLS_LG,
  		HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC,
  			USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) },
f3287a995   Benjamin Tissoires   HID: multitouch: ...
1889

4a6a4c966   Mikael Wikström   HID: multitouch: ...
1890
1891
1892
1893
1894
  	/* Lenovo X1 TAB Gen 2 */
  	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
  		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
  			   USB_VENDOR_ID_LENOVO,
  			   USB_DEVICE_ID_LENOVO_X1_TAB) },
140958da9   Mikael Wikström   HID: multitouch: ...
1895
1896
1897
1898
1899
  	/* Lenovo X1 TAB Gen 3 */
  	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
  		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
  			   USB_VENDOR_ID_LENOVO,
  			   USB_DEVICE_ID_LENOVO_X1_TAB3) },
4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
1900
1901
  	/* MosArt panels */
  	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1902
  		MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
1903
1904
  			USB_DEVICE_ID_ASUS_T91MT)},
  	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1905
  		MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
1906
1907
  			USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
  	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1908
  		MT_USB_DEVICE(USB_VENDOR_ID_TURBOX,
4a6ee685f   Benjamin Tissoires   HID: hid-multitou...
1909
  			USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
4db703ead   Austin Hendrix   HID: multitouch: ...
1910
  	/* Novatek Panel */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1911
  	{ .driver_data = MT_CLS_NSMU,
4380d8198   Jiri Kosina   HID: multitouch: ...
1912
  		MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK,
4db703ead   Austin Hendrix   HID: multitouch: ...
1913
  			USB_DEVICE_ID_NOVATEK_PCT) },
a80e803a2   Benjamin Tissoires   HID: multitouch: ...
1914
1915
1916
1917
  	/* Ntrig Panel */
  	{ .driver_data = MT_CLS_NSMU,
  		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
  			USB_VENDOR_ID_NTRIG, 0x1b05) },
fb55b4026   Hans de Goede   HID: multitouch: ...
1918
1919
1920
1921
1922
1923
1924
  	/* Panasonic panels */
  	{ .driver_data = MT_CLS_PANASONIC,
  		MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
  			USB_DEVICE_ID_PANABOARD_UBT780) },
  	{ .driver_data = MT_CLS_PANASONIC,
  		MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
  			USB_DEVICE_ID_PANABOARD_UBT880) },
b7ea95ff9   Aaron Tian   HID: multitouch: ...
1925
1926
  	/* PixArt optical touch screen */
  	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1927
  		MT_USB_DEVICE(USB_VENDOR_ID_PIXART,
b7ea95ff9   Aaron Tian   HID: multitouch: ...
1928
1929
  			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
  	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1930
  		MT_USB_DEVICE(USB_VENDOR_ID_PIXART,
b7ea95ff9   Aaron Tian   HID: multitouch: ...
1931
1932
  			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
  	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1933
  		MT_USB_DEVICE(USB_VENDOR_ID_PIXART,
b7ea95ff9   Aaron Tian   HID: multitouch: ...
1934
  			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1935
  	/* PixCir-based panels */
1e9cf35b9   Benjamin Tissoires   HID: hid-multitou...
1936
  	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1937
  		MT_USB_DEVICE(USB_VENDOR_ID_CANDO,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
1938
  			USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
5e7ea11f6   Benjamin Tissoires   HID: multitouch: ...
1939
1940
  	/* Quanta-based panels */
  	{ .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1941
  		MT_USB_DEVICE(USB_VENDOR_ID_QUANTA,
5e7ea11f6   Benjamin Tissoires   HID: multitouch: ...
1942
  			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
a6802e008   Forest Bond   HID: hid-multitou...
1943

843e475f9   Benjamin Tissoires   HID: multitouch: ...
1944
1945
1946
1947
  	/* Razer touchpads */
  	{ .driver_data = MT_CLS_RAZER_BLADE_STEALTH,
  		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
  			USB_VENDOR_ID_SYNAPTICS, 0x8323) },
69ecd44d6   Benjamin Tissoires   HID: multitouch: ...
1948
1949
1950
  	/* Smart Tech panels */
  	{ .driver_data = MT_CLS_SMART_TECH,
  		MT_USB_DEVICE(0x0b8c, 0x0092)},
043b403ae   Benjamin Tissoires   HID: hid-multitou...
1951
  	/* Stantum panels */
bf5af9b5b   Benjamin Tissoires   HID: hid-multitou...
1952
  	{ .driver_data = MT_CLS_CONFIDENCE,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1953
  		MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
043b403ae   Benjamin Tissoires   HID: hid-multitou...
1954
  			USB_DEVICE_ID_MTP_STM)},
043b403ae   Benjamin Tissoires   HID: hid-multitou...
1955

40d5bb873   Benjamin Tissoires   HID: multitouch: ...
1956
1957
1958
1959
  	/* Synaptics devices */
  	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
  		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
  			USB_VENDOR_ID_SYNAPTICS, 0xce08) },
847672cd1   Benjamin Tissoires   HID: multitouch: ...
1960
1961
  	/* TopSeed panels */
  	{ .driver_data = MT_CLS_TOPSEED,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1962
  		MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2,
847672cd1   Benjamin Tissoires   HID: multitouch: ...
1963
  			USB_DEVICE_ID_TOPSEED2_PERIPAD_701) },
5e74e56da   Benjamin Tissoires   HID: hid-multitou...
1964
  	/* Touch International panels */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1965
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1966
  		MT_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
5e74e56da   Benjamin Tissoires   HID: hid-multitou...
1967
  			USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
617b64f97   Benjamin Tissoires   HID: hid-multitou...
1968
  	/* Unitec panels */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1969
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1970
  		MT_USB_DEVICE(USB_VENDOR_ID_UNITEC,
617b64f97   Benjamin Tissoires   HID: hid-multitou...
1971
  			USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1972
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1973
  		MT_USB_DEVICE(USB_VENDOR_ID_UNITEC,
617b64f97   Benjamin Tissoires   HID: hid-multitou...
1974
  			USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
bf9d121ef   KaiChung Cheng   HID: multicouh: a...
1975

da10bc252   Mathieu Magnaudet   HID: multitouch: ...
1976
1977
1978
1979
  	/* VTL panels */
  	{ .driver_data = MT_CLS_VTL,
  		MT_USB_DEVICE(USB_VENDOR_ID_VTL,
  			USB_DEVICE_ID_VTL_MULTITOUCH_FF3F) },
bf9d121ef   KaiChung Cheng   HID: multicouh: a...
1980
1981
1982
1983
  	/* Wistron panels */
  	{ .driver_data = MT_CLS_NSMU,
  		MT_USB_DEVICE(USB_VENDOR_ID_WISTRON,
  			USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH) },
bc8a2a9b4   ice chien   HID: hid-multitou...
1984
  	/* XAT */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1985
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1986
  		MT_USB_DEVICE(USB_VENDOR_ID_XAT,
bc8a2a9b4   ice chien   HID: hid-multitou...
1987
  			USB_DEVICE_ID_XAT_CSR) },
617b64f97   Benjamin Tissoires   HID: hid-multitou...
1988

11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
1989
  	/* Xiroku */
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1990
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1991
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
1992
  			USB_DEVICE_ID_XIROKU_SPX) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1993
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1994
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
1995
  			USB_DEVICE_ID_XIROKU_MPX) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1996
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
1997
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
1998
  			USB_DEVICE_ID_XIROKU_CSR) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
1999
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2000
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2001
  			USB_DEVICE_ID_XIROKU_SPX1) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
2002
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2003
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2004
  			USB_DEVICE_ID_XIROKU_MPX1) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
2005
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2006
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2007
  			USB_DEVICE_ID_XIROKU_CSR1) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
2008
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2009
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2010
  			USB_DEVICE_ID_XIROKU_SPX2) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
2011
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2012
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2013
  			USB_DEVICE_ID_XIROKU_MPX2) },
dc3e1d805   Benjamin Tissoires   HID: multitouch: ...
2014
  	{ .driver_data = MT_CLS_NSMU,
2c2110e90   Henrik Rydberg   HID: hid-multitou...
2015
  		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
11576c611   Masatoshi Hoshikawa   HID: hid-multitou...
2016
  			USB_DEVICE_ID_XIROKU_CSR2) },
0e82232c4   Wei-Ning Huang   HID: multitouch: ...
2017
2018
2019
2020
  	/* Google MT devices */
  	{ .driver_data = MT_CLS_GOOGLE,
  		HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,
  			USB_DEVICE_ID_GOOGLE_TOUCH_ROSE) },
4fa3a5837   Henrik Rydberg   HID: hid-multitou...
2021
2022
  	/* Generic MT device */
  	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
f961bd351   Benjamin Tissoires   HID: detect Win 8...
2023
2024
2025
2026
2027
  
  	/* Generic Win 8 certified MT device */
  	{  .driver_data = MT_CLS_WIN_8,
  		HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8,
  			HID_ANY_ID, HID_ANY_ID) },
5519cab47   Benjamin Tissoires   HID: hid-multitou...
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
  	{ }
  };
  MODULE_DEVICE_TABLE(hid, mt_devices);
  
  static const struct hid_usage_id mt_grabbed_usages[] = {
  	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
  	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
  };
  
  static struct hid_driver mt_driver = {
  	.name = "hid-multitouch",
  	.id_table = mt_devices,
  	.probe = mt_probe,
  	.remove = mt_remove,
  	.input_mapping = mt_input_mapping,
  	.input_mapped = mt_input_mapped,
76f5902ae   Henrik Rydberg   HID: hid-multitou...
2044
  	.input_configured = mt_input_configured,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
2045
2046
2047
  	.feature_mapping = mt_feature_mapping,
  	.usage_table = mt_grabbed_usages,
  	.event = mt_event,
55978fa9d   Benjamin Tissoires   HID: multitouch: ...
2048
  	.report = mt_report,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
2049
2050
  #ifdef CONFIG_PM
  	.reset_resume = mt_reset_resume,
dfeefd108   Scott Liu   HID: multitouch: ...
2051
  	.resume = mt_resume,
5519cab47   Benjamin Tissoires   HID: hid-multitou...
2052
2053
  #endif
  };
f425458ea   H Hartley Sweeten   HID: Use module_h...
2054
  module_hid_driver(mt_driver);