hid-multitouch.c (a18f22a968de17b29f2310cdb7ba69163e65ec15) hid-multitouch.c (df167c4a0d68a9dbde044a39a77f255ac666f93e)
1/*
2 * HID driver for multitouch panels
3 *
4 * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr>
5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
7 *
8 * This code is partly based on hid-egalax.c:
9 *
10 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
11 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
12 * Copyright (c) 2010 Canonical, Ltd.
13 *
1/*
2 * HID driver for multitouch panels
3 *
4 * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr>
5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
7 *
8 * This code is partly based on hid-egalax.c:
9 *
10 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
11 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
12 * Copyright (c) 2010 Canonical, Ltd.
13 *
14 * This code is partly based on hid-3m-pct.c:
15 *
16 * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
17 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
18 * Copyright (c) 2010 Canonical, Ltd.
19 *
14 */
15
16/*
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at your option)
20 * any later version.
21 */

--- 17 unchanged lines hidden (view full) ---

39/* quirks to control the device */
40#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0)
41#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
42#define MT_QUIRK_CYPRESS (1 << 2)
43#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
44#define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
45#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)
46#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6)
20 */
21
22/*
23 * This program is free software; you can redistribute it and/or modify it
24 * under the terms of the GNU General Public License as published by the Free
25 * Software Foundation; either version 2 of the License, or (at your option)
26 * any later version.
27 */

--- 17 unchanged lines hidden (view full) ---

45/* quirks to control the device */
46#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0)
47#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
48#define MT_QUIRK_CYPRESS (1 << 2)
49#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
50#define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
51#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)
52#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6)
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7)
47
48struct mt_slot {
49 __s32 x, y, p, w, h;
50 __s32 contactid; /* the device ContactID assigned to this slot */
51 bool touch_state; /* is the touch valid? */
52 bool seen_in_this_frame;/* has this slot been updated */
53};
54
55struct mt_device {
56 struct mt_slot curdata; /* placeholder of incoming data */
57 struct mt_class *mtclass; /* our mt device class */
58 unsigned last_field_index; /* last field index of the report */
59 unsigned last_slot_field; /* the last field of a slot */
60 __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
61 __u8 num_received; /* how many contacts we received */
62 __u8 num_expected; /* expected last contact index */
54
55struct mt_slot {
56 __s32 x, y, p, w, h;
57 __s32 contactid; /* the device ContactID assigned to this slot */
58 bool touch_state; /* is the touch valid? */
59 bool seen_in_this_frame;/* has this slot been updated */
60};
61
62struct mt_device {
63 struct mt_slot curdata; /* placeholder of incoming data */
64 struct mt_class *mtclass; /* our mt device class */
65 unsigned last_field_index; /* last field index of the report */
66 unsigned last_slot_field; /* the last field of a slot */
67 __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
68 __u8 num_received; /* how many contacts we received */
69 __u8 num_expected; /* expected last contact index */
70 __u8 maxcontacts;
63 bool curvalid; /* is the current contact valid? */
71 bool curvalid; /* is the current contact valid? */
64 struct mt_slot slots[0]; /* first slot */
72 struct mt_slot *slots;
65};
66
67struct mt_class {
68 __s32 name; /* MT_CLS */
69 __s32 quirks;
70 __s32 sn_move; /* Signal/noise ratio for move events */
73};
74
75struct mt_class {
76 __s32 name; /* MT_CLS */
77 __s32 quirks;
78 __s32 sn_move; /* Signal/noise ratio for move events */
79 __s32 sn_width; /* Signal/noise ratio for width events */
80 __s32 sn_height; /* Signal/noise ratio for height events */
71 __s32 sn_pressure; /* Signal/noise ratio for pressure events */
72 __u8 maxcontacts;
73};
74
75/* classes of device behavior */
76#define MT_CLS_DEFAULT 1
77#define MT_CLS_DUAL_INRANGE_CONTACTID 2
78#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3
79#define MT_CLS_CYPRESS 4
80#define MT_CLS_EGALAX 5
81 __s32 sn_pressure; /* Signal/noise ratio for pressure events */
82 __u8 maxcontacts;
83};
84
85/* classes of device behavior */
86#define MT_CLS_DEFAULT 1
87#define MT_CLS_DUAL_INRANGE_CONTACTID 2
88#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3
89#define MT_CLS_CYPRESS 4
90#define MT_CLS_EGALAX 5
91#define MT_CLS_STANTUM 6
92#define MT_CLS_3M 7
93#define MT_CLS_CONFIDENCE 8
94#define MT_CLS_CONFIDENCE_MINUS_ONE 9
81
95
96#define MT_DEFAULT_MAXCONTACT 10
97
82/*
83 * these device-dependent functions determine what slot corresponds
84 * to a valid contact that was just read.
85 */
86
87static int cypress_compute_slot(struct mt_device *td)
88{
89 if (td->curdata.contactid != 0 || td->num_received == 0)
90 return td->curdata.contactid;
91 else
92 return -1;
93}
94
95static int find_slot_from_contactid(struct mt_device *td)
96{
97 int i;
98/*
99 * these device-dependent functions determine what slot corresponds
100 * to a valid contact that was just read.
101 */
102
103static int cypress_compute_slot(struct mt_device *td)
104{
105 if (td->curdata.contactid != 0 || td->num_received == 0)
106 return td->curdata.contactid;
107 else
108 return -1;
109}
110
111static int find_slot_from_contactid(struct mt_device *td)
112{
113 int i;
98 for (i = 0; i < td->mtclass->maxcontacts; ++i) {
114 for (i = 0; i < td->maxcontacts; ++i) {
99 if (td->slots[i].contactid == td->curdata.contactid &&
100 td->slots[i].touch_state)
101 return i;
102 }
115 if (td->slots[i].contactid == td->curdata.contactid &&
116 td->slots[i].touch_state)
117 return i;
118 }
103 for (i = 0; i < td->mtclass->maxcontacts; ++i) {
119 for (i = 0; i < td->maxcontacts; ++i) {
104 if (!td->slots[i].seen_in_this_frame &&
105 !td->slots[i].touch_state)
106 return i;
107 }
108 /* should not occurs. If this happens that means
109 * that the device sent more touches that it says
110 * in the report descriptor. It is ignored then. */
111 return -1;
112}
113
114struct mt_class mt_classes[] = {
115 { .name = MT_CLS_DEFAULT,
120 if (!td->slots[i].seen_in_this_frame &&
121 !td->slots[i].touch_state)
122 return i;
123 }
124 /* should not occurs. If this happens that means
125 * that the device sent more touches that it says
126 * in the report descriptor. It is ignored then. */
127 return -1;
128}
129
130struct mt_class mt_classes[] = {
131 { .name = MT_CLS_DEFAULT,
116 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
117 .maxcontacts = 10 },
132 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
118 { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
119 .quirks = MT_QUIRK_VALID_IS_INRANGE |
120 MT_QUIRK_SLOT_IS_CONTACTID,
121 .maxcontacts = 2 },
122 { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
123 .quirks = MT_QUIRK_VALID_IS_INRANGE |
124 MT_QUIRK_SLOT_IS_CONTACTNUMBER,
125 .maxcontacts = 2 },
126 { .name = MT_CLS_CYPRESS,
127 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
128 MT_QUIRK_CYPRESS,
129 .maxcontacts = 10 },
133 { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
134 .quirks = MT_QUIRK_VALID_IS_INRANGE |
135 MT_QUIRK_SLOT_IS_CONTACTID,
136 .maxcontacts = 2 },
137 { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
138 .quirks = MT_QUIRK_VALID_IS_INRANGE |
139 MT_QUIRK_SLOT_IS_CONTACTNUMBER,
140 .maxcontacts = 2 },
141 { .name = MT_CLS_CYPRESS,
142 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
143 MT_QUIRK_CYPRESS,
144 .maxcontacts = 10 },
130
145 { .name = MT_CLS_CONFIDENCE_MINUS_ONE,
146 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
147 MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
131 { .name = MT_CLS_EGALAX,
132 .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
133 MT_QUIRK_VALID_IS_INRANGE |
134 MT_QUIRK_EGALAX_XYZ_FIXUP,
135 .maxcontacts = 2,
136 .sn_move = 4096,
137 .sn_pressure = 32,
138 },
148 { .name = MT_CLS_EGALAX,
149 .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
150 MT_QUIRK_VALID_IS_INRANGE |
151 MT_QUIRK_EGALAX_XYZ_FIXUP,
152 .maxcontacts = 2,
153 .sn_move = 4096,
154 .sn_pressure = 32,
155 },
156 { .name = MT_CLS_STANTUM,
157 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
158 { .name = MT_CLS_3M,
159 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
160 MT_QUIRK_SLOT_IS_CONTACTID,
161 .sn_move = 2048,
162 .sn_width = 128,
163 .sn_height = 128 },
164 { .name = MT_CLS_CONFIDENCE,
165 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
166
139 { }
140};
141
142static void mt_feature_mapping(struct hid_device *hdev,
143 struct hid_field *field, struct hid_usage *usage)
144{
167 { }
168};
169
170static void mt_feature_mapping(struct hid_device *hdev,
171 struct hid_field *field, struct hid_usage *usage)
172{
145 if (usage->hid == HID_DG_INPUTMODE) {
146 struct mt_device *td = hid_get_drvdata(hdev);
173 struct mt_device *td = hid_get_drvdata(hdev);
174
175 switch (usage->hid) {
176 case HID_DG_INPUTMODE:
147 td->inputmode = field->report->id;
177 td->inputmode = field->report->id;
178 break;
179 case HID_DG_CONTACTMAX:
180 td->maxcontacts = field->value[0];
181 if (td->mtclass->maxcontacts)
182 /* check if the maxcontacts is given by the class */
183 td->maxcontacts = td->mtclass->maxcontacts;
184
185 break;
148 }
149}
150
151static void set_abs(struct input_dev *input, unsigned int code,
152 struct hid_field *field, int snratio)
153{
154 int fmin = field->logical_minimum;
155 int fmax = field->logical_maximum;

--- 18 unchanged lines hidden (view full) ---

174 field->logical_maximum = 32760;
175 hid_map_usage(hi, usage, bit, max,
176 EV_ABS, ABS_MT_POSITION_X);
177 set_abs(hi->input, ABS_MT_POSITION_X, field,
178 cls->sn_move);
179 /* touchscreen emulation */
180 set_abs(hi->input, ABS_X, field, cls->sn_move);
181 td->last_slot_field = usage->hid;
186 }
187}
188
189static void set_abs(struct input_dev *input, unsigned int code,
190 struct hid_field *field, int snratio)
191{
192 int fmin = field->logical_minimum;
193 int fmax = field->logical_maximum;

--- 18 unchanged lines hidden (view full) ---

212 field->logical_maximum = 32760;
213 hid_map_usage(hi, usage, bit, max,
214 EV_ABS, ABS_MT_POSITION_X);
215 set_abs(hi->input, ABS_MT_POSITION_X, field,
216 cls->sn_move);
217 /* touchscreen emulation */
218 set_abs(hi->input, ABS_X, field, cls->sn_move);
219 td->last_slot_field = usage->hid;
220 td->last_field_index = field->index;
182 return 1;
183 case HID_GD_Y:
184 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
185 field->logical_maximum = 32760;
186 hid_map_usage(hi, usage, bit, max,
187 EV_ABS, ABS_MT_POSITION_Y);
188 set_abs(hi->input, ABS_MT_POSITION_Y, field,
189 cls->sn_move);
190 /* touchscreen emulation */
191 set_abs(hi->input, ABS_Y, field, cls->sn_move);
192 td->last_slot_field = usage->hid;
221 return 1;
222 case HID_GD_Y:
223 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
224 field->logical_maximum = 32760;
225 hid_map_usage(hi, usage, bit, max,
226 EV_ABS, ABS_MT_POSITION_Y);
227 set_abs(hi->input, ABS_MT_POSITION_Y, field,
228 cls->sn_move);
229 /* touchscreen emulation */
230 set_abs(hi->input, ABS_Y, field, cls->sn_move);
231 td->last_slot_field = usage->hid;
232 td->last_field_index = field->index;
193 return 1;
194 }
195 return 0;
196
197 case HID_UP_DIGITIZER:
198 switch (usage->hid) {
199 case HID_DG_INRANGE:
200 td->last_slot_field = usage->hid;
233 return 1;
234 }
235 return 0;
236
237 case HID_UP_DIGITIZER:
238 switch (usage->hid) {
239 case HID_DG_INRANGE:
240 td->last_slot_field = usage->hid;
241 td->last_field_index = field->index;
201 return 1;
202 case HID_DG_CONFIDENCE:
203 td->last_slot_field = usage->hid;
242 return 1;
243 case HID_DG_CONFIDENCE:
244 td->last_slot_field = usage->hid;
245 td->last_field_index = field->index;
204 return 1;
205 case HID_DG_TIPSWITCH:
206 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
207 input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
208 td->last_slot_field = usage->hid;
246 return 1;
247 case HID_DG_TIPSWITCH:
248 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
249 input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
250 td->last_slot_field = usage->hid;
251 td->last_field_index = field->index;
209 return 1;
210 case HID_DG_CONTACTID:
252 return 1;
253 case HID_DG_CONTACTID:
211 input_mt_init_slots(hi->input,
212 td->mtclass->maxcontacts);
254 input_mt_init_slots(hi->input, td->maxcontacts);
213 td->last_slot_field = usage->hid;
255 td->last_slot_field = usage->hid;
256 td->last_field_index = field->index;
214 return 1;
215 case HID_DG_WIDTH:
216 hid_map_usage(hi, usage, bit, max,
217 EV_ABS, ABS_MT_TOUCH_MAJOR);
257 return 1;
258 case HID_DG_WIDTH:
259 hid_map_usage(hi, usage, bit, max,
260 EV_ABS, ABS_MT_TOUCH_MAJOR);
261 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
262 cls->sn_width);
218 td->last_slot_field = usage->hid;
263 td->last_slot_field = usage->hid;
264 td->last_field_index = field->index;
219 return 1;
220 case HID_DG_HEIGHT:
221 hid_map_usage(hi, usage, bit, max,
222 EV_ABS, ABS_MT_TOUCH_MINOR);
265 return 1;
266 case HID_DG_HEIGHT:
267 hid_map_usage(hi, usage, bit, max,
268 EV_ABS, ABS_MT_TOUCH_MINOR);
223 field->logical_maximum = 1;
224 field->logical_minimum = 0;
225 set_abs(hi->input, ABS_MT_ORIENTATION, field, 0);
269 set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
270 cls->sn_height);
271 input_set_abs_params(hi->input,
272 ABS_MT_ORIENTATION, 0, 1, 0, 0);
226 td->last_slot_field = usage->hid;
273 td->last_slot_field = usage->hid;
274 td->last_field_index = field->index;
227 return 1;
228 case HID_DG_TIPPRESSURE:
229 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
230 field->logical_minimum = 0;
231 hid_map_usage(hi, usage, bit, max,
232 EV_ABS, ABS_MT_PRESSURE);
233 set_abs(hi->input, ABS_MT_PRESSURE, field,
234 cls->sn_pressure);
235 /* touchscreen emulation */
236 set_abs(hi->input, ABS_PRESSURE, field,
237 cls->sn_pressure);
238 td->last_slot_field = usage->hid;
275 return 1;
276 case HID_DG_TIPPRESSURE:
277 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
278 field->logical_minimum = 0;
279 hid_map_usage(hi, usage, bit, max,
280 EV_ABS, ABS_MT_PRESSURE);
281 set_abs(hi->input, ABS_MT_PRESSURE, field,
282 cls->sn_pressure);
283 /* touchscreen emulation */
284 set_abs(hi->input, ABS_PRESSURE, field,
285 cls->sn_pressure);
286 td->last_slot_field = usage->hid;
287 td->last_field_index = field->index;
239 return 1;
240 case HID_DG_CONTACTCOUNT:
288 return 1;
289 case HID_DG_CONTACTCOUNT:
241 td->last_field_index = field->report->maxfield - 1;
290 td->last_field_index = field->index;
242 return 1;
243 case HID_DG_CONTACTMAX:
244 /* we don't set td->last_slot_field as contactcount and
245 * contact max are global to the report */
291 return 1;
292 case HID_DG_CONTACTMAX:
293 /* we don't set td->last_slot_field as contactcount and
294 * contact max are global to the report */
295 td->last_field_index = field->index;
246 return -1;
247 }
248 /* let hid-input decide for the others */
249 return 0;
250
251 case 0xff000000:
252 /* we do not want to map these: no input-oriented meaning */
253 return -1;

--- 20 unchanged lines hidden (view full) ---

274 return td->curdata.contactid;
275
276 if (quirks & MT_QUIRK_CYPRESS)
277 return cypress_compute_slot(td);
278
279 if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
280 return td->num_received;
281
296 return -1;
297 }
298 /* let hid-input decide for the others */
299 return 0;
300
301 case 0xff000000:
302 /* we do not want to map these: no input-oriented meaning */
303 return -1;

--- 20 unchanged lines hidden (view full) ---

324 return td->curdata.contactid;
325
326 if (quirks & MT_QUIRK_CYPRESS)
327 return cypress_compute_slot(td);
328
329 if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
330 return td->num_received;
331
332 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
333 return td->curdata.contactid - 1;
334
282 return find_slot_from_contactid(td);
283}
284
285/*
286 * this function is called when a whole contact has been processed,
287 * so that it can assign it to a slot and store the data there
288 */
289static void mt_complete_slot(struct mt_device *td)
290{
291 td->curdata.seen_in_this_frame = true;
292 if (td->curvalid) {
293 int slotnum = mt_compute_slot(td);
294
335 return find_slot_from_contactid(td);
336}
337
338/*
339 * this function is called when a whole contact has been processed,
340 * so that it can assign it to a slot and store the data there
341 */
342static void mt_complete_slot(struct mt_device *td)
343{
344 td->curdata.seen_in_this_frame = true;
345 if (td->curvalid) {
346 int slotnum = mt_compute_slot(td);
347
295 if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
348 if (slotnum >= 0 && slotnum < td->maxcontacts)
296 td->slots[slotnum] = td->curdata;
297 }
298 td->num_received++;
299}
300
301
302/*
303 * this function is called when a whole packet has been received and processed,
304 * so that it can decide what to send to the input layer.
305 */
306static void mt_emit_event(struct mt_device *td, struct input_dev *input)
307{
308 int i;
309
349 td->slots[slotnum] = td->curdata;
350 }
351 td->num_received++;
352}
353
354
355/*
356 * this function is called when a whole packet has been received and processed,
357 * so that it can decide what to send to the input layer.
358 */
359static void mt_emit_event(struct mt_device *td, struct input_dev *input)
360{
361 int i;
362
310 for (i = 0; i < td->mtclass->maxcontacts; ++i) {
363 for (i = 0; i < td->maxcontacts; ++i) {
311 struct mt_slot *s = &(td->slots[i]);
312 if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
313 !s->seen_in_this_frame) {
314 s->touch_state = false;
315 }
316
317 input_mt_slot(input, i);
318 input_mt_report_slot_state(input, MT_TOOL_FINGER,
319 s->touch_state);
320 if (s->touch_state) {
364 struct mt_slot *s = &(td->slots[i]);
365 if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
366 !s->seen_in_this_frame) {
367 s->touch_state = false;
368 }
369
370 input_mt_slot(input, i);
371 input_mt_report_slot_state(input, MT_TOOL_FINGER,
372 s->touch_state);
373 if (s->touch_state) {
374 /* this finger is on the screen */
375 int wide = (s->w > s->h);
376 /* divided by two to match visual scale of touch */
377 int major = max(s->w, s->h) >> 1;
378 int minor = min(s->w, s->h) >> 1;
379
321 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
322 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
380 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
381 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
382 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
323 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
383 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
324 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w);
325 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h);
384 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
385 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
326 }
327 s->seen_in_this_frame = false;
328
329 }
330
331 input_mt_report_pointer_emulation(input, true);
332 input_sync(input);
333 td->num_received = 0;
334}
335
336
337
338static int mt_event(struct hid_device *hid, struct hid_field *field,
339 struct hid_usage *usage, __s32 value)
340{
341 struct mt_device *td = hid_get_drvdata(hid);
342 __s32 quirks = td->mtclass->quirks;
343
386 }
387 s->seen_in_this_frame = false;
388
389 }
390
391 input_mt_report_pointer_emulation(input, true);
392 input_sync(input);
393 td->num_received = 0;
394}
395
396
397
398static int mt_event(struct hid_device *hid, struct hid_field *field,
399 struct hid_usage *usage, __s32 value)
400{
401 struct mt_device *td = hid_get_drvdata(hid);
402 __s32 quirks = td->mtclass->quirks;
403
344 if (hid->claimed & HID_CLAIMED_INPUT) {
404 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
345 switch (usage->hid) {
346 case HID_DG_INRANGE:
347 if (quirks & MT_QUIRK_VALID_IS_INRANGE)
348 td->curvalid = value;
349 break;
350 case HID_DG_TIPSWITCH:
351 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
352 td->curvalid = value;

--- 32 unchanged lines hidden (view full) ---

385
386 default:
387 /* fallback to the generic hidinput handling */
388 return 0;
389 }
390
391 if (usage->hid == td->last_slot_field) {
392 mt_complete_slot(td);
405 switch (usage->hid) {
406 case HID_DG_INRANGE:
407 if (quirks & MT_QUIRK_VALID_IS_INRANGE)
408 td->curvalid = value;
409 break;
410 case HID_DG_TIPSWITCH:
411 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
412 td->curvalid = value;

--- 32 unchanged lines hidden (view full) ---

445
446 default:
447 /* fallback to the generic hidinput handling */
448 return 0;
449 }
450
451 if (usage->hid == td->last_slot_field) {
452 mt_complete_slot(td);
393 if (!td->last_field_index)
394 mt_emit_event(td, field->hidinput->input);
395 }
396
397 if (field->index == td->last_field_index
398 && td->num_received >= td->num_expected)
399 mt_emit_event(td, field->hidinput->input);
400
401 }
402

--- 34 unchanged lines hidden (view full) ---

437 }
438 }
439
440 /* This allows the driver to correctly support devices
441 * that emit events over several HID messages.
442 */
443 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
444
453 }
454
455 if (field->index == td->last_field_index
456 && td->num_received >= td->num_expected)
457 mt_emit_event(td, field->hidinput->input);
458
459 }
460

--- 34 unchanged lines hidden (view full) ---

495 }
496 }
497
498 /* This allows the driver to correctly support devices
499 * that emit events over several HID messages.
500 */
501 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
502
445 td = kzalloc(sizeof(struct mt_device) +
446 mtclass->maxcontacts * sizeof(struct mt_slot),
447 GFP_KERNEL);
503 td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
448 if (!td) {
449 dev_err(&hdev->dev, "cannot allocate multitouch data\n");
450 return -ENOMEM;
451 }
452 td->mtclass = mtclass;
453 td->inputmode = -1;
454 hid_set_drvdata(hdev, td);
455
456 ret = hid_parse(hdev);
457 if (ret != 0)
458 goto fail;
459
460 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
461 if (ret)
462 goto fail;
463
504 if (!td) {
505 dev_err(&hdev->dev, "cannot allocate multitouch data\n");
506 return -ENOMEM;
507 }
508 td->mtclass = mtclass;
509 td->inputmode = -1;
510 hid_set_drvdata(hdev, td);
511
512 ret = hid_parse(hdev);
513 if (ret != 0)
514 goto fail;
515
516 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
517 if (ret)
518 goto fail;
519
520 if (!td->maxcontacts)
521 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
522
523 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
524 GFP_KERNEL);
525 if (!td->slots) {
526 dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
527 hid_hw_stop(hdev);
528 ret = -ENOMEM;
529 goto fail;
530 }
531
464 mt_set_input_mode(hdev);
465
466 return 0;
467
468fail:
469 kfree(td);
470 return ret;
471}

--- 5 unchanged lines hidden (view full) ---

477 return 0;
478}
479#endif
480
481static void mt_remove(struct hid_device *hdev)
482{
483 struct mt_device *td = hid_get_drvdata(hdev);
484 hid_hw_stop(hdev);
532 mt_set_input_mode(hdev);
533
534 return 0;
535
536fail:
537 kfree(td);
538 return ret;
539}

--- 5 unchanged lines hidden (view full) ---

545 return 0;
546}
547#endif
548
549static void mt_remove(struct hid_device *hdev)
550{
551 struct mt_device *td = hid_get_drvdata(hdev);
552 hid_hw_stop(hdev);
553 kfree(td->slots);
485 kfree(td);
486 hid_set_drvdata(hdev, NULL);
487}
488
489static const struct hid_device_id mt_devices[] = {
490
554 kfree(td);
555 hid_set_drvdata(hdev, NULL);
556}
557
558static const struct hid_device_id mt_devices[] = {
559
560 /* 3M panels */
561 { .driver_data = MT_CLS_3M,
562 HID_USB_DEVICE(USB_VENDOR_ID_3M,
563 USB_DEVICE_ID_3M1968) },
564 { .driver_data = MT_CLS_3M,
565 HID_USB_DEVICE(USB_VENDOR_ID_3M,
566 USB_DEVICE_ID_3M2256) },
567
568 /* Cando panels */
569 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
570 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
571 USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
572 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
573 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
574 USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
575 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
576 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
577 USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
578 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
579 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
580 USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
581
491 /* Cypress panel */
492 { .driver_data = MT_CLS_CYPRESS,
493 HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
494 USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
495
496 /* GeneralTouch panel */
497 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
498 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
499 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
500
582 /* Cypress panel */
583 { .driver_data = MT_CLS_CYPRESS,
584 HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
585 USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
586
587 /* GeneralTouch panel */
588 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
589 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
590 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
591
592 /* Ilitek dual touch panel */
593 { .driver_data = MT_CLS_DEFAULT,
594 HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
595 USB_DEVICE_ID_ILITEK_MULTITOUCH) },
596
501 /* IRTOUCH panels */
502 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
503 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
504 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
505
597 /* IRTOUCH panels */
598 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
599 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
600 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
601
602 /* Lumio panels */
603 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
604 HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
605 USB_DEVICE_ID_CRYSTALTOUCH) },
606
607 /* MosArt panels */
608 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
609 HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
610 USB_DEVICE_ID_ASUS_T91MT)},
611 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
612 HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
613 USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
614 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
615 HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
616 USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
617
618 /* PenMount panels */
619 { .driver_data = MT_CLS_CONFIDENCE,
620 HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
621 USB_DEVICE_ID_PENMOUNT_PCI) },
622
506 /* PixCir-based panels */
507 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
508 HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
509 USB_DEVICE_ID_HANVON_MULTITOUCH) },
510 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
511 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
512 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
513

--- 11 unchanged lines hidden (view full) ---

525 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
526 { .driver_data = MT_CLS_EGALAX,
527 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
528 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
529 { .driver_data = MT_CLS_EGALAX,
530 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
531 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
532
623 /* PixCir-based panels */
624 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
625 HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
626 USB_DEVICE_ID_HANVON_MULTITOUCH) },
627 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
628 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
629 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
630

--- 11 unchanged lines hidden (view full) ---

642 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
643 { .driver_data = MT_CLS_EGALAX,
644 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
645 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
646 { .driver_data = MT_CLS_EGALAX,
647 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
648 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
649
650 /* Stantum panels */
651 { .driver_data = MT_CLS_STANTUM,
652 HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
653 USB_DEVICE_ID_MTP)},
654 { .driver_data = MT_CLS_STANTUM,
655 HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
656 USB_DEVICE_ID_MTP_STM)},
657 { .driver_data = MT_CLS_STANTUM,
658 HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
659 USB_DEVICE_ID_MTP_SITRONIX)},
660
533 { }
534};
535MODULE_DEVICE_TABLE(hid, mt_devices);
536
537static const struct hid_usage_id mt_grabbed_usages[] = {
538 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
539 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
540};

--- 28 unchanged lines hidden ---
661 { }
662};
663MODULE_DEVICE_TABLE(hid, mt_devices);
664
665static const struct hid_usage_id mt_grabbed_usages[] = {
666 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
667 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
668};

--- 28 unchanged lines hidden ---