diff options
Diffstat (limited to 'drivers/hid/hid-magicmouse.c')
-rw-r--r-- | drivers/hid/hid-magicmouse.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0ec91c18a421..f0fbd7bd239e 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
@@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie | |||
81 | #define NO_TOUCHES -1 | 81 | #define NO_TOUCHES -1 |
82 | #define SINGLE_TOUCH_UP -2 | 82 | #define SINGLE_TOUCH_UP -2 |
83 | 83 | ||
84 | /* Touch surface information. Dimension is in hundredths of a mm, min and max | ||
85 | * are in units. */ | ||
86 | #define MOUSE_DIMENSION_X (float)9056 | ||
87 | #define MOUSE_MIN_X -1100 | ||
88 | #define MOUSE_MAX_X 1258 | ||
89 | #define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100)) | ||
90 | #define MOUSE_DIMENSION_Y (float)5152 | ||
91 | #define MOUSE_MIN_Y -1589 | ||
92 | #define MOUSE_MAX_Y 2047 | ||
93 | #define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100)) | ||
94 | |||
95 | #define TRACKPAD_DIMENSION_X (float)13000 | ||
96 | #define TRACKPAD_MIN_X -2909 | ||
97 | #define TRACKPAD_MAX_X 3167 | ||
98 | #define TRACKPAD_RES_X \ | ||
99 | ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100)) | ||
100 | #define TRACKPAD_DIMENSION_Y (float)11000 | ||
101 | #define TRACKPAD_MIN_Y -2456 | ||
102 | #define TRACKPAD_MAX_Y 2565 | ||
103 | #define TRACKPAD_RES_Y \ | ||
104 | ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100)) | ||
105 | |||
84 | /** | 106 | /** |
85 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. | 107 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. |
86 | * @input: Input device through which we report events. | 108 | * @input: Input device through which we report events. |
@@ -406,17 +428,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h | |||
406 | * inverse of the reported Y. | 428 | * inverse of the reported Y. |
407 | */ | 429 | */ |
408 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { | 430 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
409 | input_set_abs_params(input, ABS_MT_POSITION_X, -1100, | 431 | input_set_abs_params(input, ABS_MT_POSITION_X, |
410 | 1358, 4, 0); | 432 | MOUSE_MIN_X, MOUSE_MAX_X, 4, 0); |
411 | input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, | 433 | input_set_abs_params(input, ABS_MT_POSITION_Y, |
412 | 2047, 4, 0); | 434 | MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0); |
435 | |||
436 | input_abs_set_res(input, ABS_MT_POSITION_X, | ||
437 | MOUSE_RES_X); | ||
438 | input_abs_set_res(input, ABS_MT_POSITION_Y, | ||
439 | MOUSE_RES_Y); | ||
413 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | 440 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ |
414 | input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); | 441 | input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X, |
415 | input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); | 442 | TRACKPAD_MAX_X, 4, 0); |
416 | input_set_abs_params(input, ABS_MT_POSITION_X, -2909, | 443 | input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y, |
417 | 3167, 4, 0); | 444 | TRACKPAD_MAX_Y, 4, 0); |
418 | input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, | 445 | input_set_abs_params(input, ABS_MT_POSITION_X, |
419 | 2565, 4, 0); | 446 | TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0); |
447 | input_set_abs_params(input, ABS_MT_POSITION_Y, | ||
448 | TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0); | ||
449 | |||
450 | input_abs_set_res(input, ABS_X, TRACKPAD_RES_X); | ||
451 | input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y); | ||
452 | input_abs_set_res(input, ABS_MT_POSITION_X, | ||
453 | TRACKPAD_RES_X); | ||
454 | input_abs_set_res(input, ABS_MT_POSITION_Y, | ||
455 | TRACKPAD_RES_Y); | ||
420 | } | 456 | } |
421 | 457 | ||
422 | input_set_events_per_packet(input, 60); | 458 | input_set_events_per_packet(input, 60); |
@@ -501,9 +537,17 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
501 | } | 537 | } |
502 | report->size = 6; | 538 | report->size = 6; |
503 | 539 | ||
540 | /* | ||
541 | * Some devices repond with 'invalid report id' when feature | ||
542 | * report switching it into multitouch mode is sent to it. | ||
543 | * | ||
544 | * This results in -EIO from the _raw low-level transport callback, | ||
545 | * but there seems to be no other way of switching the mode. | ||
546 | * Thus the super-ugly hacky success check below. | ||
547 | */ | ||
504 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), | 548 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), |
505 | HID_FEATURE_REPORT); | 549 | HID_FEATURE_REPORT); |
506 | if (ret != sizeof(feature)) { | 550 | if (ret != -EIO && ret != sizeof(feature)) { |
507 | hid_err(hdev, "unable to request touch data (%d)\n", ret); | 551 | hid_err(hdev, "unable to request touch data (%d)\n", ret); |
508 | goto err_stop_hw; | 552 | goto err_stop_hw; |
509 | } | 553 | } |