aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-magicmouse.c66
1 files changed, 22 insertions, 44 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index fd88f216720a..73647266daad 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/hid.h> 18#include <linux/hid.h>
19#include <linux/input/mt.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/usb.h> 22#include <linux/usb.h>
@@ -68,15 +69,6 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
68 69
69#define SCROLL_ACCEL_DEFAULT 7 70#define SCROLL_ACCEL_DEFAULT 7
70 71
71/* Single touch emulation should only begin when no touches are currently down.
72 * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
73 * are down and the touch providing for single touch emulation is lifted,
74 * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
75 * occurring, single_touch_id corresponds with the tracking id of the touch used.
76 */
77#define NO_TOUCHES -1
78#define SINGLE_TOUCH_UP -2
79
80/* Touch surface information. Dimension is in hundredths of a mm, min and max 72/* Touch surface information. Dimension is in hundredths of a mm, min and max
81 * are in units. */ 73 * are in units. */
82#define MOUSE_DIMENSION_X (float)9056 74#define MOUSE_DIMENSION_X (float)9056
@@ -125,7 +117,6 @@ struct magicmouse_sc {
125 u8 size; 117 u8 size;
126 } touches[16]; 118 } touches[16];
127 int tracking_ids[16]; 119 int tracking_ids[16];
128 int single_touch_id;
129}; 120};
130 121
131static int magicmouse_firm_touch(struct magicmouse_sc *msc) 122static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -264,16 +255,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
264 } 255 }
265 } 256 }
266 257
267 if (down) { 258 if (down)
268 msc->ntouches++; 259 msc->ntouches++;
269 if (msc->single_touch_id == NO_TOUCHES) 260
270 msc->single_touch_id = id; 261 input_mt_slot(input, id);
271 } else if (msc->single_touch_id == id) 262 input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
272 msc->single_touch_id = SINGLE_TOUCH_UP;
273 263
274 /* Generate the input events for this touch. */ 264 /* Generate the input events for this touch. */
275 if (down) { 265 if (down) {
276 input_report_abs(input, ABS_MT_TRACKING_ID, id);
277 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); 266 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
278 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); 267 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
279 input_report_abs(input, ABS_MT_ORIENTATION, -orientation); 268 input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
@@ -286,8 +275,6 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
286 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 275 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
287 input_event(input, EV_MSC, MSC_RAW, tdata[8]); 276 input_event(input, EV_MSC, MSC_RAW, tdata[8]);
288 } 277 }
289
290 input_mt_sync(input);
291 } 278 }
292} 279}
293 280
@@ -308,12 +295,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
308 for (ii = 0; ii < npoints; ii++) 295 for (ii = 0; ii < npoints; ii++)
309 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); 296 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
310 297
311 /* We don't need an MT sync here because trackpad emits a
312 * BTN_TOUCH event in a new frame when all touches are released.
313 */
314 if (msc->ntouches == 0)
315 msc->single_touch_id = NO_TOUCHES;
316
317 clicks = data[1]; 298 clicks = data[1];
318 299
319 /* The following bits provide a device specific timestamp. They 300 /* The following bits provide a device specific timestamp. They
@@ -331,9 +312,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
331 for (ii = 0; ii < npoints; ii++) 312 for (ii = 0; ii < npoints; ii++)
332 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 313 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
333 314
334 if (msc->ntouches == 0)
335 input_mt_sync(input);
336
337 /* When emulating three-button mode, it is important 315 /* When emulating three-button mode, it is important
338 * to have the current touch information before 316 * to have the current touch information before
339 * generating a click event. 317 * generating a click event.
@@ -366,25 +344,17 @@ static int magicmouse_raw_event(struct hid_device *hdev,
366 input_report_rel(input, REL_Y, y); 344 input_report_rel(input, REL_Y, y);
367 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 345 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
368 input_report_key(input, BTN_MOUSE, clicks & 1); 346 input_report_key(input, BTN_MOUSE, clicks & 1);
369 input_report_key(input, BTN_TOUCH, msc->ntouches > 0); 347 input_mt_report_pointer_emulation(input, true);
370 input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
371 input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
372 input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
373 input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
374 if (msc->single_touch_id >= 0) {
375 input_report_abs(input, ABS_X,
376 msc->touches[msc->single_touch_id].x);
377 input_report_abs(input, ABS_Y,
378 msc->touches[msc->single_touch_id].y);
379 }
380 } 348 }
381 349
382 input_sync(input); 350 input_sync(input);
383 return 1; 351 return 1;
384} 352}
385 353
386static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 354static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
387{ 355{
356 int error;
357
388 __set_bit(EV_KEY, input->evbit); 358 __set_bit(EV_KEY, input->evbit);
389 359
390 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 360 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
@@ -413,6 +383,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
413 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); 383 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
414 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); 384 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
415 __set_bit(BTN_TOOL_QUADTAP, input->keybit); 385 __set_bit(BTN_TOOL_QUADTAP, input->keybit);
386 __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
416 __set_bit(BTN_TOUCH, input->keybit); 387 __set_bit(BTN_TOUCH, input->keybit);
417 __set_bit(INPUT_PROP_POINTER, input->propbit); 388 __set_bit(INPUT_PROP_POINTER, input->propbit);
418 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 389 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
@@ -421,7 +392,9 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
421 392
422 __set_bit(EV_ABS, input->evbit); 393 __set_bit(EV_ABS, input->evbit);
423 394
424 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); 395 error = input_mt_init_slots(input, 16);
396 if (error)
397 return error;
425 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
426 4, 0); 399 4, 0);
427 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, 400 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
@@ -468,6 +441,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
468 __set_bit(EV_MSC, input->evbit); 441 __set_bit(EV_MSC, input->evbit);
469 __set_bit(MSC_RAW, input->mscbit); 442 __set_bit(MSC_RAW, input->mscbit);
470 } 443 }
444
445 return 0;
471} 446}
472 447
473static int magicmouse_input_mapping(struct hid_device *hdev, 448static int magicmouse_input_mapping(struct hid_device *hdev,
@@ -506,8 +481,6 @@ static int magicmouse_probe(struct hid_device *hdev,
506 msc->quirks = id->driver_data; 481 msc->quirks = id->driver_data;
507 hid_set_drvdata(hdev, msc); 482 hid_set_drvdata(hdev, msc);
508 483
509 msc->single_touch_id = NO_TOUCHES;
510
511 ret = hid_parse(hdev); 484 ret = hid_parse(hdev);
512 if (ret) { 485 if (ret) {
513 hid_err(hdev, "magicmouse hid parse failed\n"); 486 hid_err(hdev, "magicmouse hid parse failed\n");
@@ -523,8 +496,13 @@ static int magicmouse_probe(struct hid_device *hdev,
523 /* We do this after hid-input is done parsing reports so that 496 /* We do this after hid-input is done parsing reports so that
524 * hid-input uses the most natural button and axis IDs. 497 * hid-input uses the most natural button and axis IDs.
525 */ 498 */
526 if (msc->input) 499 if (msc->input) {
527 magicmouse_setup_input(msc->input, hdev); 500 ret = magicmouse_setup_input(msc->input, hdev);
501 if (ret) {
502 hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
503 goto err_stop_hw;
504 }
505 }
528 506
529 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 507 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
530 report = hid_register_report(hdev, HID_INPUT_REPORT, 508 report = hid_register_report(hdev, HID_INPUT_REPORT,