1 /* 2 * HID driver for N-Trig touchscreens 3 * 4 * Copyright (c) 2008 Rafi Rubin 5 * Copyright (c) 2009 Stephane Chatty 6 * 7 */ 8 9 /* 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 */ 15 16 #include <linux/device.h> 17 #include <linux/hid.h> 18 #include <linux/module.h> 19 #include <linux/slab.h> 20 21 #include "hid-ids.h" 22 23 #define NTRIG_DUPLICATE_USAGES 0x001 24 25 #define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 26 EV_KEY, (c)) 27 28 struct ntrig_data { 29 /* Incoming raw values for a single contact */ 30 __u16 x, y, w, h; 31 __u16 id; 32 __u8 confidence; 33 34 bool reading_mt; 35 __u8 first_contact_confidence; 36 37 __u8 mt_footer[4]; 38 __u8 mt_foot_count; 39 }; 40 41 /* 42 * this driver is aimed at two firmware versions in circulation: 43 * - dual pen/finger single touch 44 * - finger multitouch, pen not working 45 */ 46 47 static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, 48 struct hid_field *field, struct hid_usage *usage, 49 unsigned long **bit, int *max) 50 { 51 /* No special mappings needed for the pen and single touch */ 52 if (field->physical) 53 return 0; 54 55 switch (usage->hid & HID_USAGE_PAGE) { 56 case HID_UP_GENDESK: 57 switch (usage->hid) { 58 case HID_GD_X: 59 hid_map_usage(hi, usage, bit, max, 60 EV_ABS, ABS_MT_POSITION_X); 61 input_set_abs_params(hi->input, ABS_X, 62 field->logical_minimum, 63 field->logical_maximum, 0, 0); 64 return 1; 65 case HID_GD_Y: 66 hid_map_usage(hi, usage, bit, max, 67 EV_ABS, ABS_MT_POSITION_Y); 68 input_set_abs_params(hi->input, ABS_Y, 69 field->logical_minimum, 70 field->logical_maximum, 0, 0); 71 return 1; 72 } 73 return 0; 74 75 case HID_UP_DIGITIZER: 76 switch (usage->hid) { 77 /* we do not want to map these for now */ 78 case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ 79 case HID_DG_INPUTMODE: 80 case HID_DG_DEVICEINDEX: 81 case HID_DG_CONTACTMAX: 82 return -1; 83 84 /* width/height mapped on TouchMajor/TouchMinor/Orientation */ 85 case HID_DG_WIDTH: 86 hid_map_usage(hi, usage, bit, max, 87 EV_ABS, ABS_MT_TOUCH_MAJOR); 88 return 1; 89 case HID_DG_HEIGHT: 90 hid_map_usage(hi, usage, bit, max, 91 EV_ABS, ABS_MT_TOUCH_MINOR); 92 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 93 0, 1, 0, 0); 94 return 1; 95 } 96 return 0; 97 98 case 0xff000000: 99 /* we do not want to map these: no input-oriented meaning */ 100 return -1; 101 } 102 103 return 0; 104 } 105 106 static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, 107 struct hid_field *field, struct hid_usage *usage, 108 unsigned long **bit, int *max) 109 { 110 /* No special mappings needed for the pen and single touch */ 111 if (field->physical) 112 return 0; 113 114 if (usage->type == EV_KEY || usage->type == EV_REL 115 || usage->type == EV_ABS) 116 clear_bit(usage->code, *bit); 117 118 return 0; 119 } 120 121 /* 122 * this function is called upon all reports 123 * so that we can filter contact point information, 124 * decide whether we are in multi or single touch mode 125 * and call input_mt_sync after each point if necessary 126 */ 127 static int ntrig_event (struct hid_device *hid, struct hid_field *field, 128 struct hid_usage *usage, __s32 value) 129 { 130 struct input_dev *input = field->hidinput->input; 131 struct ntrig_data *nd = hid_get_drvdata(hid); 132 133 /* No special handling needed for the pen */ 134 if (field->application == HID_DG_PEN) 135 return 0; 136 137 if (hid->claimed & HID_CLAIMED_INPUT) { 138 switch (usage->hid) { 139 case 0xff000001: 140 /* Tag indicating the start of a multitouch group */ 141 nd->reading_mt = 1; 142 nd->first_contact_confidence = 0; 143 break; 144 case HID_DG_TIPSWITCH: 145 /* Prevent emission of touch until validated */ 146 return 1; 147 case HID_DG_CONFIDENCE: 148 nd->confidence = value; 149 break; 150 case HID_GD_X: 151 nd->x = value; 152 /* Clear the contact footer */ 153 nd->mt_foot_count = 0; 154 break; 155 case HID_GD_Y: 156 nd->y = value; 157 break; 158 case HID_DG_CONTACTID: 159 nd->id = value; 160 break; 161 case HID_DG_WIDTH: 162 nd->w = value; 163 break; 164 case HID_DG_HEIGHT: 165 nd->h = value; 166 /* 167 * when in single touch mode, this is the last 168 * report received in a finger event. We want 169 * to emit a normal (X, Y) position 170 */ 171 if (!nd->reading_mt) { 172 input_report_key(input, BTN_TOOL_DOUBLETAP, 173 (nd->confidence != 0)); 174 input_event(input, EV_ABS, ABS_X, nd->x); 175 input_event(input, EV_ABS, ABS_Y, nd->y); 176 } 177 break; 178 case 0xff000002: 179 /* 180 * we receive this when the device is in multitouch 181 * mode. The first of the three values tagged with 182 * this usage tells if the contact point is real 183 * or a placeholder 184 */ 185 186 /* Shouldn't get more than 4 footer packets, so skip */ 187 if (nd->mt_foot_count >= 4) 188 break; 189 190 nd->mt_footer[nd->mt_foot_count++] = value; 191 192 /* if the footer isn't complete break */ 193 if (nd->mt_foot_count != 4) 194 break; 195 196 /* Pen activity signal, trigger end of touch. */ 197 if (nd->mt_footer[2]) { 198 nd->confidence = 0; 199 break; 200 } 201 202 /* If the contact was invalid */ 203 if (!(nd->confidence && nd->mt_footer[0]) 204 || nd->w <= 250 205 || nd->h <= 190) { 206 nd->confidence = 0; 207 break; 208 } 209 210 /* emit a normal (X, Y) for the first point only */ 211 if (nd->id == 0) { 212 nd->first_contact_confidence = nd->confidence; 213 input_event(input, EV_ABS, ABS_X, nd->x); 214 input_event(input, EV_ABS, ABS_Y, nd->y); 215 } 216 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); 217 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); 218 if (nd->w > nd->h) { 219 input_event(input, EV_ABS, 220 ABS_MT_ORIENTATION, 1); 221 input_event(input, EV_ABS, 222 ABS_MT_TOUCH_MAJOR, nd->w); 223 input_event(input, EV_ABS, 224 ABS_MT_TOUCH_MINOR, nd->h); 225 } else { 226 input_event(input, EV_ABS, 227 ABS_MT_ORIENTATION, 0); 228 input_event(input, EV_ABS, 229 ABS_MT_TOUCH_MAJOR, nd->h); 230 input_event(input, EV_ABS, 231 ABS_MT_TOUCH_MINOR, nd->w); 232 } 233 input_mt_sync(field->hidinput->input); 234 break; 235 236 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ 237 if (!nd->reading_mt) 238 break; 239 240 nd->reading_mt = 0; 241 242 if (nd->first_contact_confidence) { 243 switch (value) { 244 case 0: /* for single touch devices */ 245 case 1: 246 input_report_key(input, 247 BTN_TOOL_DOUBLETAP, 1); 248 break; 249 case 2: 250 input_report_key(input, 251 BTN_TOOL_TRIPLETAP, 1); 252 break; 253 case 3: 254 default: 255 input_report_key(input, 256 BTN_TOOL_QUADTAP, 1); 257 } 258 input_report_key(input, BTN_TOUCH, 1); 259 } else { 260 input_report_key(input, 261 BTN_TOOL_DOUBLETAP, 0); 262 input_report_key(input, 263 BTN_TOOL_TRIPLETAP, 0); 264 input_report_key(input, 265 BTN_TOOL_QUADTAP, 0); 266 input_report_key(input, BTN_TOUCH, 0); 267 } 268 break; 269 270 default: 271 /* fallback to the generic hidinput handling */ 272 return 0; 273 } 274 } 275 276 /* we have handled the hidinput part, now remains hiddev */ 277 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) 278 hid->hiddev_hid_event(hid, field, usage, value); 279 280 return 1; 281 } 282 283 static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) 284 { 285 int ret; 286 struct ntrig_data *nd; 287 struct hid_input *hidinput; 288 struct input_dev *input; 289 290 if (id->driver_data) 291 hdev->quirks |= HID_QUIRK_MULTI_INPUT; 292 293 nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); 294 if (!nd) { 295 dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); 296 return -ENOMEM; 297 } 298 299 nd->reading_mt = 0; 300 hid_set_drvdata(hdev, nd); 301 302 ret = hid_parse(hdev); 303 if (ret) { 304 dev_err(&hdev->dev, "parse failed\n"); 305 goto err_free; 306 } 307 308 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); 309 if (ret) { 310 dev_err(&hdev->dev, "hw start failed\n"); 311 goto err_free; 312 } 313 314 315 list_for_each_entry(hidinput, &hdev->inputs, list) { 316 if (hidinput->report->maxfield < 1) 317 continue; 318 319 input = hidinput->input; 320 switch (hidinput->report->field[0]->application) { 321 case HID_DG_PEN: 322 input->name = "N-Trig Pen"; 323 break; 324 case HID_DG_TOUCHSCREEN: 325 /* These keys are redundant for fingers, clear them 326 * to prevent incorrect identification */ 327 __clear_bit(BTN_TOOL_PEN, input->keybit); 328 __clear_bit(BTN_TOOL_FINGER, input->keybit); 329 __clear_bit(BTN_0, input->keybit); 330 /* 331 * A little something special to enable 332 * two and three finger taps. 333 */ 334 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); 335 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); 336 __set_bit(BTN_TOOL_QUADTAP, input->keybit); 337 /* 338 * The physical touchscreen (single touch) 339 * input has a value for physical, whereas 340 * the multitouch only has logical input 341 * fields. 342 */ 343 input->name = 344 (hidinput->report->field[0] 345 ->physical) ? 346 "N-Trig Touchscreen" : 347 "N-Trig MultiTouch"; 348 break; 349 } 350 } 351 352 return 0; 353 err_free: 354 kfree(nd); 355 return ret; 356 } 357 358 static void ntrig_remove(struct hid_device *hdev) 359 { 360 hid_hw_stop(hdev); 361 kfree(hid_get_drvdata(hdev)); 362 } 363 364 static const struct hid_device_id ntrig_devices[] = { 365 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), 366 .driver_data = NTRIG_DUPLICATE_USAGES }, 367 { } 368 }; 369 MODULE_DEVICE_TABLE(hid, ntrig_devices); 370 371 static const struct hid_usage_id ntrig_grabbed_usages[] = { 372 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, 373 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } 374 }; 375 376 static struct hid_driver ntrig_driver = { 377 .name = "ntrig", 378 .id_table = ntrig_devices, 379 .probe = ntrig_probe, 380 .remove = ntrig_remove, 381 .input_mapping = ntrig_input_mapping, 382 .input_mapped = ntrig_input_mapped, 383 .usage_table = ntrig_grabbed_usages, 384 .event = ntrig_event, 385 }; 386 387 static int __init ntrig_init(void) 388 { 389 return hid_register_driver(&ntrig_driver); 390 } 391 392 static void __exit ntrig_exit(void) 393 { 394 hid_unregister_driver(&ntrig_driver); 395 } 396 397 module_init(ntrig_init); 398 module_exit(ntrig_exit); 399 MODULE_LICENSE("GPL"); 400