summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-magicmouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-magicmouse.c')
-rw-r--r--drivers/hid/hid-magicmouse.c151
1 files changed, 63 insertions, 88 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 7cf3ffe4b7bc..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>
@@ -48,10 +49,6 @@ static bool scroll_acceleration = false;
48module_param(scroll_acceleration, bool, 0644); 49module_param(scroll_acceleration, bool, 0644);
49MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); 50MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
50 51
51static bool report_touches = true;
52module_param(report_touches, bool, 0644);
53MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
54
55static bool report_undeciphered; 52static bool report_undeciphered;
56module_param(report_undeciphered, bool, 0644); 53module_param(report_undeciphered, bool, 0644);
57MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
@@ -72,15 +69,6 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
72 69
73#define SCROLL_ACCEL_DEFAULT 7 70#define SCROLL_ACCEL_DEFAULT 7
74 71
75/* Single touch emulation should only begin when no touches are currently down.
76 * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
77 * are down and the touch providing for single touch emulation is lifted,
78 * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
79 * occurring, single_touch_id corresponds with the tracking id of the touch used.
80 */
81#define NO_TOUCHES -1
82#define SINGLE_TOUCH_UP -2
83
84/* 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
85 * are in units. */ 73 * are in units. */
86#define MOUSE_DIMENSION_X (float)9056 74#define MOUSE_DIMENSION_X (float)9056
@@ -129,7 +117,6 @@ struct magicmouse_sc {
129 u8 size; 117 u8 size;
130 } touches[16]; 118 } touches[16];
131 int tracking_ids[16]; 119 int tracking_ids[16];
132 int single_touch_id;
133}; 120};
134 121
135static int magicmouse_firm_touch(struct magicmouse_sc *msc) 122static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -268,16 +255,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
268 } 255 }
269 } 256 }
270 257
271 if (down) { 258 if (down)
272 msc->ntouches++; 259 msc->ntouches++;
273 if (msc->single_touch_id == NO_TOUCHES) 260
274 msc->single_touch_id = id; 261 input_mt_slot(input, id);
275 } else if (msc->single_touch_id == id) 262 input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
276 msc->single_touch_id = SINGLE_TOUCH_UP;
277 263
278 /* Generate the input events for this touch. */ 264 /* Generate the input events for this touch. */
279 if (report_touches && down) { 265 if (down) {
280 input_report_abs(input, ABS_MT_TRACKING_ID, id);
281 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); 266 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
282 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); 267 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
283 input_report_abs(input, ABS_MT_ORIENTATION, -orientation); 268 input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
@@ -290,8 +275,6 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
290 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 275 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
291 input_event(input, EV_MSC, MSC_RAW, tdata[8]); 276 input_event(input, EV_MSC, MSC_RAW, tdata[8]);
292 } 277 }
293
294 input_mt_sync(input);
295 } 278 }
296} 279}
297 280
@@ -312,12 +295,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
312 for (ii = 0; ii < npoints; ii++) 295 for (ii = 0; ii < npoints; ii++)
313 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); 296 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
314 297
315 /* We don't need an MT sync here because trackpad emits a
316 * BTN_TOUCH event in a new frame when all touches are released.
317 */
318 if (msc->ntouches == 0)
319 msc->single_touch_id = NO_TOUCHES;
320
321 clicks = data[1]; 298 clicks = data[1];
322 299
323 /* The following bits provide a device specific timestamp. They 300 /* The following bits provide a device specific timestamp. They
@@ -335,9 +312,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
335 for (ii = 0; ii < npoints; ii++) 312 for (ii = 0; ii < npoints; ii++)
336 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 313 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
337 314
338 if (report_touches && msc->ntouches == 0)
339 input_mt_sync(input);
340
341 /* When emulating three-button mode, it is important 315 /* When emulating three-button mode, it is important
342 * to have the current touch information before 316 * to have the current touch information before
343 * generating a click event. 317 * generating a click event.
@@ -370,25 +344,17 @@ static int magicmouse_raw_event(struct hid_device *hdev,
370 input_report_rel(input, REL_Y, y); 344 input_report_rel(input, REL_Y, y);
371 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 345 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
372 input_report_key(input, BTN_MOUSE, clicks & 1); 346 input_report_key(input, BTN_MOUSE, clicks & 1);
373 input_report_key(input, BTN_TOUCH, msc->ntouches > 0); 347 input_mt_report_pointer_emulation(input, true);
374 input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
375 input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
376 input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
377 input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
378 if (msc->single_touch_id >= 0) {
379 input_report_abs(input, ABS_X,
380 msc->touches[msc->single_touch_id].x);
381 input_report_abs(input, ABS_Y,
382 msc->touches[msc->single_touch_id].y);
383 }
384 } 348 }
385 349
386 input_sync(input); 350 input_sync(input);
387 return 1; 351 return 1;
388} 352}
389 353
390static 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)
391{ 355{
356 int error;
357
392 __set_bit(EV_KEY, input->evbit); 358 __set_bit(EV_KEY, input->evbit);
393 359
394 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 360 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
@@ -417,60 +383,66 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
417 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); 383 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
418 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); 384 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
419 __set_bit(BTN_TOOL_QUADTAP, input->keybit); 385 __set_bit(BTN_TOOL_QUADTAP, input->keybit);
386 __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
420 __set_bit(BTN_TOUCH, input->keybit); 387 __set_bit(BTN_TOUCH, input->keybit);
421 __set_bit(INPUT_PROP_POINTER, input->propbit); 388 __set_bit(INPUT_PROP_POINTER, input->propbit);
422 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 389 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
423 } 390 }
424 391
425 if (report_touches) {
426 __set_bit(EV_ABS, input->evbit);
427 392
428 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); 393 __set_bit(EV_ABS, input->evbit);
429 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
430 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
431 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
432 394
433 /* Note: Touch Y position from the device is inverted relative 395 error = input_mt_init_slots(input, 16);
434 * to how pointer motion is reported (and relative to how USB 396 if (error)
435 * HID recommends the coordinates work). This driver keeps 397 return error;
436 * the origin at the same position, and just uses the additive 398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
437 * inverse of the reported Y. 399 4, 0);
438 */ 400 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
439 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 401 4, 0);
440 input_set_abs_params(input, ABS_MT_POSITION_X, 402 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
441 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
442 input_set_abs_params(input, ABS_MT_POSITION_Y,
443 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
444
445 input_abs_set_res(input, ABS_MT_POSITION_X,
446 MOUSE_RES_X);
447 input_abs_set_res(input, ABS_MT_POSITION_Y,
448 MOUSE_RES_Y);
449 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
450 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
451 TRACKPAD_MAX_X, 4, 0);
452 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
453 TRACKPAD_MAX_Y, 4, 0);
454 input_set_abs_params(input, ABS_MT_POSITION_X,
455 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
456 input_set_abs_params(input, ABS_MT_POSITION_Y,
457 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
458
459 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
460 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
461 input_abs_set_res(input, ABS_MT_POSITION_X,
462 TRACKPAD_RES_X);
463 input_abs_set_res(input, ABS_MT_POSITION_Y,
464 TRACKPAD_RES_Y);
465 }
466 403
467 input_set_events_per_packet(input, 60); 404 /* Note: Touch Y position from the device is inverted relative
405 * to how pointer motion is reported (and relative to how USB
406 * HID recommends the coordinates work). This driver keeps
407 * the origin at the same position, and just uses the additive
408 * inverse of the reported Y.
409 */
410 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
411 input_set_abs_params(input, ABS_MT_POSITION_X,
412 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
413 input_set_abs_params(input, ABS_MT_POSITION_Y,
414 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
415
416 input_abs_set_res(input, ABS_MT_POSITION_X,
417 MOUSE_RES_X);
418 input_abs_set_res(input, ABS_MT_POSITION_Y,
419 MOUSE_RES_Y);
420 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
421 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
422 TRACKPAD_MAX_X, 4, 0);
423 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
424 TRACKPAD_MAX_Y, 4, 0);
425 input_set_abs_params(input, ABS_MT_POSITION_X,
426 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
427 input_set_abs_params(input, ABS_MT_POSITION_Y,
428 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
429
430 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
431 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
432 input_abs_set_res(input, ABS_MT_POSITION_X,
433 TRACKPAD_RES_X);
434 input_abs_set_res(input, ABS_MT_POSITION_Y,
435 TRACKPAD_RES_Y);
468 } 436 }
469 437
438 input_set_events_per_packet(input, 60);
439
470 if (report_undeciphered) { 440 if (report_undeciphered) {
471 __set_bit(EV_MSC, input->evbit); 441 __set_bit(EV_MSC, input->evbit);
472 __set_bit(MSC_RAW, input->mscbit); 442 __set_bit(MSC_RAW, input->mscbit);
473 } 443 }
444
445 return 0;
474} 446}
475 447
476static int magicmouse_input_mapping(struct hid_device *hdev, 448static int magicmouse_input_mapping(struct hid_device *hdev,
@@ -509,8 +481,6 @@ static int magicmouse_probe(struct hid_device *hdev,
509 msc->quirks = id->driver_data; 481 msc->quirks = id->driver_data;
510 hid_set_drvdata(hdev, msc); 482 hid_set_drvdata(hdev, msc);
511 483
512 msc->single_touch_id = NO_TOUCHES;
513
514 ret = hid_parse(hdev); 484 ret = hid_parse(hdev);
515 if (ret) { 485 if (ret) {
516 hid_err(hdev, "magicmouse hid parse failed\n"); 486 hid_err(hdev, "magicmouse hid parse failed\n");
@@ -526,8 +496,13 @@ static int magicmouse_probe(struct hid_device *hdev,
526 /* 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
527 * hid-input uses the most natural button and axis IDs. 497 * hid-input uses the most natural button and axis IDs.
528 */ 498 */
529 if (msc->input) 499 if (msc->input) {
530 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 }
531 506
532 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 507 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
533 report = hid_register_report(hdev, HID_INPUT_REPORT, 508 report = hid_register_report(hdev, HID_INPUT_REPORT,