aboutsummaryrefslogtreecommitdiffstats
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.c79
1 files changed, 61 insertions, 18 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 0ec91c18a42..08f5dc77397 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.
@@ -365,8 +387,10 @@ static int magicmouse_raw_event(struct hid_device *hdev,
365 return 1; 387 return 1;
366} 388}
367 389
368static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 390static int magicmouse_setup_input(struct hid_device *hdev, struct hid_input *hi)
369{ 391{
392 struct input_dev *input = hi->input;
393
370 __set_bit(EV_KEY, input->evbit); 394 __set_bit(EV_KEY, input->evbit);
371 395
372 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 396 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
@@ -406,17 +430,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
406 * inverse of the reported Y. 430 * inverse of the reported Y.
407 */ 431 */
408 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 432 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
409 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 433 input_set_abs_params(input, ABS_MT_POSITION_X,
410 1358, 4, 0); 434 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
411 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 435 input_set_abs_params(input, ABS_MT_POSITION_Y,
412 2047, 4, 0); 436 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
437
438 input_abs_set_res(input, ABS_MT_POSITION_X,
439 MOUSE_RES_X);
440 input_abs_set_res(input, ABS_MT_POSITION_Y,
441 MOUSE_RES_Y);
413 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 442 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
414 input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); 443 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
415 input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); 444 TRACKPAD_MAX_X, 4, 0);
416 input_set_abs_params(input, ABS_MT_POSITION_X, -2909, 445 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
417 3167, 4, 0); 446 TRACKPAD_MAX_Y, 4, 0);
418 input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, 447 input_set_abs_params(input, ABS_MT_POSITION_X,
419 2565, 4, 0); 448 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
449 input_set_abs_params(input, ABS_MT_POSITION_Y,
450 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
451
452 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
453 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
454 input_abs_set_res(input, ABS_MT_POSITION_X,
455 TRACKPAD_RES_X);
456 input_abs_set_res(input, ABS_MT_POSITION_Y,
457 TRACKPAD_RES_Y);
420 } 458 }
421 459
422 input_set_events_per_packet(input, 60); 460 input_set_events_per_packet(input, 60);
@@ -426,6 +464,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
426 __set_bit(EV_MSC, input->evbit); 464 __set_bit(EV_MSC, input->evbit);
427 __set_bit(MSC_RAW, input->mscbit); 465 __set_bit(MSC_RAW, input->mscbit);
428 } 466 }
467
468 return 0;
429} 469}
430 470
431static int magicmouse_input_mapping(struct hid_device *hdev, 471static int magicmouse_input_mapping(struct hid_device *hdev,
@@ -478,12 +518,6 @@ static int magicmouse_probe(struct hid_device *hdev,
478 goto err_free; 518 goto err_free;
479 } 519 }
480 520
481 /* We do this after hid-input is done parsing reports so that
482 * hid-input uses the most natural button and axis IDs.
483 */
484 if (msc->input)
485 magicmouse_setup_input(msc->input, hdev);
486
487 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 521 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
488 report = hid_register_report(hdev, HID_INPUT_REPORT, 522 report = hid_register_report(hdev, HID_INPUT_REPORT,
489 MOUSE_REPORT_ID); 523 MOUSE_REPORT_ID);
@@ -501,9 +535,17 @@ static int magicmouse_probe(struct hid_device *hdev,
501 } 535 }
502 report->size = 6; 536 report->size = 6;
503 537
538 /*
539 * Some devices repond with 'invalid report id' when feature
540 * report switching it into multitouch mode is sent to it.
541 *
542 * This results in -EIO from the _raw low-level transport callback,
543 * but there seems to be no other way of switching the mode.
544 * Thus the super-ugly hacky success check below.
545 */
504 ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), 546 ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
505 HID_FEATURE_REPORT); 547 HID_FEATURE_REPORT);
506 if (ret != sizeof(feature)) { 548 if (ret != -EIO && ret != sizeof(feature)) {
507 hid_err(hdev, "unable to request touch data (%d)\n", ret); 549 hid_err(hdev, "unable to request touch data (%d)\n", ret);
508 goto err_stop_hw; 550 goto err_stop_hw;
509 } 551 }
@@ -540,6 +582,7 @@ static struct hid_driver magicmouse_driver = {
540 .remove = magicmouse_remove, 582 .remove = magicmouse_remove,
541 .raw_event = magicmouse_raw_event, 583 .raw_event = magicmouse_raw_event,
542 .input_mapping = magicmouse_input_mapping, 584 .input_mapping = magicmouse_input_mapping,
585 .input_register = magicmouse_setup_input,
543}; 586};
544 587
545static int __init magicmouse_init(void) 588static int __init magicmouse_init(void)