1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Apple "Magic" Wireless Mouse driver 4 * 5 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> 6 * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com> 7 */ 8 9 /* 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/device.h> 15 #include <linux/hid.h> 16 #include <linux/input/mt.h> 17 #include <linux/module.h> 18 #include <linux/slab.h> 19 20 #include "hid-ids.h" 21 22 static bool emulate_3button = true; 23 module_param(emulate_3button, bool, 0644); 24 MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); 25 26 static int middle_button_start = -350; 27 static int middle_button_stop = +350; 28 29 static bool emulate_scroll_wheel = true; 30 module_param(emulate_scroll_wheel, bool, 0644); 31 MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); 32 33 static unsigned int scroll_speed = 32; 34 static int param_set_scroll_speed(const char *val, 35 const struct kernel_param *kp) { 36 unsigned long speed; 37 if (!val || kstrtoul(val, 0, &speed) || speed > 63) 38 return -EINVAL; 39 scroll_speed = speed; 40 return 0; 41 } 42 module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644); 43 MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)"); 44 45 static bool scroll_acceleration = false; 46 module_param(scroll_acceleration, bool, 0644); 47 MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); 48 49 static bool report_undeciphered; 50 module_param(report_undeciphered, bool, 0644); 51 MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 52 53 #define TRACKPAD_REPORT_ID 0x28 54 #define TRACKPAD2_USB_REPORT_ID 0x02 55 #define TRACKPAD2_BT_REPORT_ID 0x31 56 #define MOUSE_REPORT_ID 0x29 57 #define DOUBLE_REPORT_ID 0xf7 58 /* These definitions are not precise, but they're close enough. (Bits 59 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem 60 * to be some kind of bit mask -- 0x20 may be a near-field reading, 61 * and 0x40 is actual contact, and 0x10 may be a start/stop or change 62 * indication.) 63 */ 64 #define TOUCH_STATE_MASK 0xf0 65 #define TOUCH_STATE_NONE 0x00 66 #define TOUCH_STATE_START 0x30 67 #define TOUCH_STATE_DRAG 0x40 68 69 #define SCROLL_ACCEL_DEFAULT 7 70 71 /* Touch surface information. Dimension is in hundredths of a mm, min and max 72 * are in units. */ 73 #define MOUSE_DIMENSION_X (float)9056 74 #define MOUSE_MIN_X -1100 75 #define MOUSE_MAX_X 1258 76 #define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100)) 77 #define MOUSE_DIMENSION_Y (float)5152 78 #define MOUSE_MIN_Y -1589 79 #define MOUSE_MAX_Y 2047 80 #define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100)) 81 82 #define TRACKPAD_DIMENSION_X (float)13000 83 #define TRACKPAD_MIN_X -2909 84 #define TRACKPAD_MAX_X 3167 85 #define TRACKPAD_RES_X \ 86 ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100)) 87 #define TRACKPAD_DIMENSION_Y (float)11000 88 #define TRACKPAD_MIN_Y -2456 89 #define TRACKPAD_MAX_Y 2565 90 #define TRACKPAD_RES_Y \ 91 ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100)) 92 93 #define TRACKPAD2_DIMENSION_X (float)16000 94 #define TRACKPAD2_MIN_X -3678 95 #define TRACKPAD2_MAX_X 3934 96 #define TRACKPAD2_RES_X \ 97 ((TRACKPAD2_MAX_X - TRACKPAD2_MIN_X) / (TRACKPAD2_DIMENSION_X / 100)) 98 #define TRACKPAD2_DIMENSION_Y (float)11490 99 #define TRACKPAD2_MIN_Y -2478 100 #define TRACKPAD2_MAX_Y 2587 101 #define TRACKPAD2_RES_Y \ 102 ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100)) 103 104 /** 105 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 106 * @input: Input device through which we report events. 107 * @quirks: Currently unused. 108 * @ntouches: Number of touches in most recent touch report. 109 * @scroll_accel: Number of consecutive scroll motions. 110 * @scroll_jiffies: Time of last scroll motion. 111 * @touches: Most recent data for a touch, indexed by tracking ID. 112 * @tracking_ids: Mapping of current touch input data to @touches. 113 */ 114 struct magicmouse_sc { 115 struct input_dev *input; 116 unsigned long quirks; 117 118 int ntouches; 119 int scroll_accel; 120 unsigned long scroll_jiffies; 121 122 struct { 123 short x; 124 short y; 125 short scroll_x; 126 short scroll_y; 127 u8 size; 128 } touches[16]; 129 int tracking_ids[16]; 130 }; 131 132 static int magicmouse_firm_touch(struct magicmouse_sc *msc) 133 { 134 int touch = -1; 135 int ii; 136 137 /* If there is only one "firm" touch, set touch to its 138 * tracking ID. 139 */ 140 for (ii = 0; ii < msc->ntouches; ii++) { 141 int idx = msc->tracking_ids[ii]; 142 if (msc->touches[idx].size < 8) { 143 /* Ignore this touch. */ 144 } else if (touch >= 0) { 145 touch = -1; 146 break; 147 } else { 148 touch = idx; 149 } 150 } 151 152 return touch; 153 } 154 155 static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) 156 { 157 int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 | 158 test_bit(BTN_RIGHT, msc->input->key) << 1 | 159 test_bit(BTN_MIDDLE, msc->input->key) << 2; 160 161 if (emulate_3button) { 162 int id; 163 164 /* If some button was pressed before, keep it held 165 * down. Otherwise, if there's exactly one firm 166 * touch, use that to override the mouse's guess. 167 */ 168 if (state == 0) { 169 /* The button was released. */ 170 } else if (last_state != 0) { 171 state = last_state; 172 } else if ((id = magicmouse_firm_touch(msc)) >= 0) { 173 int x = msc->touches[id].x; 174 if (x < middle_button_start) 175 state = 1; 176 else if (x > middle_button_stop) 177 state = 2; 178 else 179 state = 4; 180 } /* else: we keep the mouse's guess */ 181 182 input_report_key(msc->input, BTN_MIDDLE, state & 4); 183 } 184 185 input_report_key(msc->input, BTN_LEFT, state & 1); 186 input_report_key(msc->input, BTN_RIGHT, state & 2); 187 188 if (state != last_state) 189 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 190 } 191 192 static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 193 { 194 struct input_dev *input = msc->input; 195 int id, x, y, size, orientation, touch_major, touch_minor, state, down; 196 int pressure = 0; 197 198 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 199 id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; 200 x = (tdata[1] << 28 | tdata[0] << 20) >> 20; 201 y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); 202 size = tdata[5] & 0x3f; 203 orientation = (tdata[6] >> 2) - 32; 204 touch_major = tdata[3]; 205 touch_minor = tdata[4]; 206 state = tdata[7] & TOUCH_STATE_MASK; 207 down = state != TOUCH_STATE_NONE; 208 } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 209 id = tdata[8] & 0xf; 210 x = (tdata[1] << 27 | tdata[0] << 19) >> 19; 211 y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); 212 size = tdata[6]; 213 orientation = (tdata[8] >> 5) - 4; 214 touch_major = tdata[4]; 215 touch_minor = tdata[5]; 216 pressure = tdata[7]; 217 state = tdata[3] & 0xC0; 218 down = state == 0x80; 219 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 220 id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; 221 x = (tdata[1] << 27 | tdata[0] << 19) >> 19; 222 y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); 223 size = tdata[6] & 0x3f; 224 orientation = (tdata[7] >> 2) - 32; 225 touch_major = tdata[4]; 226 touch_minor = tdata[5]; 227 state = tdata[8] & TOUCH_STATE_MASK; 228 down = state != TOUCH_STATE_NONE; 229 } 230 231 /* Store tracking ID and other fields. */ 232 msc->tracking_ids[raw_id] = id; 233 msc->touches[id].x = x; 234 msc->touches[id].y = y; 235 msc->touches[id].size = size; 236 237 /* If requested, emulate a scroll wheel by detecting small 238 * vertical touch motions. 239 */ 240 if (emulate_scroll_wheel && (input->id.product != 241 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)) { 242 unsigned long now = jiffies; 243 int step_x = msc->touches[id].scroll_x - x; 244 int step_y = msc->touches[id].scroll_y - y; 245 246 /* Calculate and apply the scroll motion. */ 247 switch (state) { 248 case TOUCH_STATE_START: 249 msc->touches[id].scroll_x = x; 250 msc->touches[id].scroll_y = y; 251 252 /* Reset acceleration after half a second. */ 253 if (scroll_acceleration && time_before(now, 254 msc->scroll_jiffies + HZ / 2)) 255 msc->scroll_accel = max_t(int, 256 msc->scroll_accel - 1, 1); 257 else 258 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 259 260 break; 261 case TOUCH_STATE_DRAG: 262 step_x /= (64 - (int)scroll_speed) * msc->scroll_accel; 263 if (step_x != 0) { 264 msc->touches[id].scroll_x -= step_x * 265 (64 - scroll_speed) * msc->scroll_accel; 266 msc->scroll_jiffies = now; 267 input_report_rel(input, REL_HWHEEL, -step_x); 268 } 269 270 step_y /= (64 - (int)scroll_speed) * msc->scroll_accel; 271 if (step_y != 0) { 272 msc->touches[id].scroll_y -= step_y * 273 (64 - scroll_speed) * msc->scroll_accel; 274 msc->scroll_jiffies = now; 275 input_report_rel(input, REL_WHEEL, step_y); 276 } 277 break; 278 } 279 } 280 281 if (down) 282 msc->ntouches++; 283 284 input_mt_slot(input, id); 285 input_mt_report_slot_state(input, MT_TOOL_FINGER, down); 286 287 /* Generate the input events for this touch. */ 288 if (down) { 289 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); 290 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); 291 input_report_abs(input, ABS_MT_ORIENTATION, -orientation); 292 input_report_abs(input, ABS_MT_POSITION_X, x); 293 input_report_abs(input, ABS_MT_POSITION_Y, y); 294 295 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) 296 input_report_abs(input, ABS_MT_PRESSURE, pressure); 297 298 if (report_undeciphered) { 299 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 300 input_event(input, EV_MSC, MSC_RAW, tdata[7]); 301 else if (input->id.product != 302 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) 303 input_event(input, EV_MSC, MSC_RAW, tdata[8]); 304 } 305 } 306 } 307 308 static int magicmouse_raw_event(struct hid_device *hdev, 309 struct hid_report *report, u8 *data, int size) 310 { 311 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 312 struct input_dev *input = msc->input; 313 int x = 0, y = 0, ii, clicks = 0, npoints; 314 315 switch (data[0]) { 316 case TRACKPAD_REPORT_ID: 317 case TRACKPAD2_BT_REPORT_ID: 318 /* Expect four bytes of prefix, and N*9 bytes of touch data. */ 319 if (size < 4 || ((size - 4) % 9) != 0) 320 return 0; 321 npoints = (size - 4) / 9; 322 if (npoints > 15) { 323 hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", 324 size); 325 return 0; 326 } 327 msc->ntouches = 0; 328 for (ii = 0; ii < npoints; ii++) 329 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); 330 331 clicks = data[1]; 332 333 /* The following bits provide a device specific timestamp. They 334 * are unused here. 335 * 336 * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; 337 */ 338 break; 339 case TRACKPAD2_USB_REPORT_ID: 340 /* Expect twelve bytes of prefix and N*9 bytes of touch data. */ 341 if (size < 12 || ((size - 12) % 9) != 0) 342 return 0; 343 npoints = (size - 12) / 9; 344 if (npoints > 15) { 345 hid_warn(hdev, "invalid size value (%d) for TRACKPAD2_USB_REPORT_ID\n", 346 size); 347 return 0; 348 } 349 msc->ntouches = 0; 350 for (ii = 0; ii < npoints; ii++) 351 magicmouse_emit_touch(msc, ii, data + ii * 9 + 12); 352 353 clicks = data[1]; 354 break; 355 case MOUSE_REPORT_ID: 356 /* Expect six bytes of prefix, and N*8 bytes of touch data. */ 357 if (size < 6 || ((size - 6) % 8) != 0) 358 return 0; 359 npoints = (size - 6) / 8; 360 if (npoints > 15) { 361 hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", 362 size); 363 return 0; 364 } 365 msc->ntouches = 0; 366 for (ii = 0; ii < npoints; ii++) 367 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 368 369 /* When emulating three-button mode, it is important 370 * to have the current touch information before 371 * generating a click event. 372 */ 373 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; 374 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; 375 clicks = data[3]; 376 377 /* The following bits provide a device specific timestamp. They 378 * are unused here. 379 * 380 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; 381 */ 382 break; 383 case DOUBLE_REPORT_ID: 384 /* Sometimes the trackpad sends two touch reports in one 385 * packet. 386 */ 387 magicmouse_raw_event(hdev, report, data + 2, data[1]); 388 magicmouse_raw_event(hdev, report, data + 2 + data[1], 389 size - 2 - data[1]); 390 break; 391 default: 392 return 0; 393 } 394 395 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 396 magicmouse_emit_buttons(msc, clicks & 3); 397 input_report_rel(input, REL_X, x); 398 input_report_rel(input, REL_Y, y); 399 } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 400 input_mt_sync_frame(input); 401 input_report_key(input, BTN_MOUSE, clicks & 1); 402 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 403 input_report_key(input, BTN_MOUSE, clicks & 1); 404 input_mt_report_pointer_emulation(input, true); 405 } 406 407 input_sync(input); 408 return 1; 409 } 410 411 static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 412 { 413 int error; 414 int mt_flags = 0; 415 416 __set_bit(EV_KEY, input->evbit); 417 418 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 419 __set_bit(BTN_LEFT, input->keybit); 420 __set_bit(BTN_RIGHT, input->keybit); 421 if (emulate_3button) 422 __set_bit(BTN_MIDDLE, input->keybit); 423 424 __set_bit(EV_REL, input->evbit); 425 __set_bit(REL_X, input->relbit); 426 __set_bit(REL_Y, input->relbit); 427 if (emulate_scroll_wheel) { 428 __set_bit(REL_WHEEL, input->relbit); 429 __set_bit(REL_HWHEEL, input->relbit); 430 } 431 } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 432 /* setting the device name to ensure the same driver settings 433 * get loaded, whether connected through bluetooth or USB 434 */ 435 input->name = "Apple Inc. Magic Trackpad 2"; 436 437 __clear_bit(EV_MSC, input->evbit); 438 __clear_bit(BTN_0, input->keybit); 439 __clear_bit(BTN_RIGHT, input->keybit); 440 __clear_bit(BTN_MIDDLE, input->keybit); 441 __set_bit(BTN_MOUSE, input->keybit); 442 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 443 __set_bit(BTN_TOOL_FINGER, input->keybit); 444 445 mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | 446 INPUT_MT_TRACK; 447 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 448 /* input->keybit is initialized with incorrect button info 449 * for Magic Trackpad. There really is only one physical 450 * button (BTN_LEFT == BTN_MOUSE). Make sure we don't 451 * advertise buttons that don't exist... 452 */ 453 __clear_bit(BTN_RIGHT, input->keybit); 454 __clear_bit(BTN_MIDDLE, input->keybit); 455 __set_bit(BTN_MOUSE, input->keybit); 456 __set_bit(BTN_TOOL_FINGER, input->keybit); 457 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); 458 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); 459 __set_bit(BTN_TOOL_QUADTAP, input->keybit); 460 __set_bit(BTN_TOOL_QUINTTAP, input->keybit); 461 __set_bit(BTN_TOUCH, input->keybit); 462 __set_bit(INPUT_PROP_POINTER, input->propbit); 463 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 464 } 465 466 467 __set_bit(EV_ABS, input->evbit); 468 469 error = input_mt_init_slots(input, 16, mt_flags); 470 if (error) 471 return error; 472 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 473 4, 0); 474 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, 475 4, 0); 476 477 /* Note: Touch Y position from the device is inverted relative 478 * to how pointer motion is reported (and relative to how USB 479 * HID recommends the coordinates work). This driver keeps 480 * the origin at the same position, and just uses the additive 481 * inverse of the reported Y. 482 */ 483 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 484 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); 485 input_set_abs_params(input, ABS_MT_POSITION_X, 486 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0); 487 input_set_abs_params(input, ABS_MT_POSITION_Y, 488 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0); 489 490 input_abs_set_res(input, ABS_MT_POSITION_X, 491 MOUSE_RES_X); 492 input_abs_set_res(input, ABS_MT_POSITION_Y, 493 MOUSE_RES_Y); 494 } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 495 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 253, 0, 0); 496 input_set_abs_params(input, ABS_PRESSURE, 0, 253, 0, 0); 497 input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0); 498 input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X, 499 TRACKPAD2_MAX_X, 0, 0); 500 input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y, 501 TRACKPAD2_MAX_Y, 0, 0); 502 input_set_abs_params(input, ABS_MT_POSITION_X, 503 TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0); 504 input_set_abs_params(input, ABS_MT_POSITION_Y, 505 TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0); 506 507 input_abs_set_res(input, ABS_X, TRACKPAD2_RES_X); 508 input_abs_set_res(input, ABS_Y, TRACKPAD2_RES_Y); 509 input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD2_RES_X); 510 input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD2_RES_Y); 511 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 512 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); 513 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X, 514 TRACKPAD_MAX_X, 4, 0); 515 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y, 516 TRACKPAD_MAX_Y, 4, 0); 517 input_set_abs_params(input, ABS_MT_POSITION_X, 518 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0); 519 input_set_abs_params(input, ABS_MT_POSITION_Y, 520 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0); 521 522 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X); 523 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y); 524 input_abs_set_res(input, ABS_MT_POSITION_X, 525 TRACKPAD_RES_X); 526 input_abs_set_res(input, ABS_MT_POSITION_Y, 527 TRACKPAD_RES_Y); 528 } 529 530 input_set_events_per_packet(input, 60); 531 532 if (report_undeciphered && 533 input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 534 __set_bit(EV_MSC, input->evbit); 535 __set_bit(MSC_RAW, input->mscbit); 536 } 537 538 return 0; 539 } 540 541 static int magicmouse_input_mapping(struct hid_device *hdev, 542 struct hid_input *hi, struct hid_field *field, 543 struct hid_usage *usage, unsigned long **bit, int *max) 544 { 545 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 546 547 if (!msc->input) 548 msc->input = hi->input; 549 550 /* Magic Trackpad does not give relative data after switching to MT */ 551 if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD || 552 hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) && 553 field->flags & HID_MAIN_ITEM_RELATIVE) 554 return -1; 555 556 return 0; 557 } 558 559 static int magicmouse_input_configured(struct hid_device *hdev, 560 struct hid_input *hi) 561 562 { 563 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 564 int ret; 565 566 ret = magicmouse_setup_input(msc->input, hdev); 567 if (ret) { 568 hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); 569 /* clean msc->input to notify probe() of the failure */ 570 msc->input = NULL; 571 return ret; 572 } 573 574 return 0; 575 } 576 577 578 static int magicmouse_probe(struct hid_device *hdev, 579 const struct hid_device_id *id) 580 { 581 const u8 *feature; 582 const u8 feature_mt[] = { 0xD7, 0x01 }; 583 const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 }; 584 const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 }; 585 u8 *buf; 586 struct magicmouse_sc *msc; 587 struct hid_report *report; 588 int ret; 589 int feature_size; 590 591 if (id->vendor == USB_VENDOR_ID_APPLE && 592 id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && 593 hdev->type != HID_TYPE_USBMOUSE) 594 return 0; 595 596 msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); 597 if (msc == NULL) { 598 hid_err(hdev, "can't alloc magicmouse descriptor\n"); 599 return -ENOMEM; 600 } 601 602 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 603 604 msc->quirks = id->driver_data; 605 hid_set_drvdata(hdev, msc); 606 607 ret = hid_parse(hdev); 608 if (ret) { 609 hid_err(hdev, "magicmouse hid parse failed\n"); 610 return ret; 611 } 612 613 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 614 if (ret) { 615 hid_err(hdev, "magicmouse hw start failed\n"); 616 return ret; 617 } 618 619 if (!msc->input) { 620 hid_err(hdev, "magicmouse input not registered\n"); 621 ret = -ENOMEM; 622 goto err_stop_hw; 623 } 624 625 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 626 report = hid_register_report(hdev, HID_INPUT_REPORT, 627 MOUSE_REPORT_ID, 0); 628 else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 629 if (id->vendor == BT_VENDOR_ID_APPLE) 630 report = hid_register_report(hdev, HID_INPUT_REPORT, 631 TRACKPAD2_BT_REPORT_ID, 0); 632 else /* USB_VENDOR_ID_APPLE */ 633 report = hid_register_report(hdev, HID_INPUT_REPORT, 634 TRACKPAD2_USB_REPORT_ID, 0); 635 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 636 report = hid_register_report(hdev, HID_INPUT_REPORT, 637 TRACKPAD_REPORT_ID, 0); 638 report = hid_register_report(hdev, HID_INPUT_REPORT, 639 DOUBLE_REPORT_ID, 0); 640 } 641 642 if (!report) { 643 hid_err(hdev, "unable to register touch report\n"); 644 ret = -ENOMEM; 645 goto err_stop_hw; 646 } 647 report->size = 6; 648 649 if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { 650 if (id->vendor == BT_VENDOR_ID_APPLE) { 651 feature_size = sizeof(feature_mt_trackpad2_bt); 652 feature = feature_mt_trackpad2_bt; 653 } else { /* USB_VENDOR_ID_APPLE */ 654 feature_size = sizeof(feature_mt_trackpad2_usb); 655 feature = feature_mt_trackpad2_usb; 656 } 657 } else { 658 feature_size = sizeof(feature_mt); 659 feature = feature_mt; 660 } 661 662 buf = kmemdup(feature, feature_size, GFP_KERNEL); 663 if (!buf) { 664 ret = -ENOMEM; 665 goto err_stop_hw; 666 } 667 668 /* 669 * Some devices repond with 'invalid report id' when feature 670 * report switching it into multitouch mode is sent to it. 671 * 672 * This results in -EIO from the _raw low-level transport callback, 673 * but there seems to be no other way of switching the mode. 674 * Thus the super-ugly hacky success check below. 675 */ 676 ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size, 677 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 678 kfree(buf); 679 if (ret != -EIO && ret != feature_size) { 680 hid_err(hdev, "unable to request touch data (%d)\n", ret); 681 goto err_stop_hw; 682 } 683 684 return 0; 685 err_stop_hw: 686 hid_hw_stop(hdev); 687 return ret; 688 } 689 690 static const struct hid_device_id magic_mice[] = { 691 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 692 USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, 693 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 694 USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 }, 695 { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, 696 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 }, 697 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 698 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 }, 699 { } 700 }; 701 MODULE_DEVICE_TABLE(hid, magic_mice); 702 703 static struct hid_driver magicmouse_driver = { 704 .name = "magicmouse", 705 .id_table = magic_mice, 706 .probe = magicmouse_probe, 707 .raw_event = magicmouse_raw_event, 708 .input_mapping = magicmouse_input_mapping, 709 .input_configured = magicmouse_input_configured, 710 }; 711 module_hid_driver(magicmouse_driver); 712 713 MODULE_LICENSE("GPL"); 714