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 --- |