1/* 2 * Apple "Magic" Wireless Mouse driver 3 * 4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> 5 */ 6 7/* 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 */ 13 14#include <linux/device.h> 15#include <linux/hid.h> 16#include <linux/module.h> 17#include <linux/slab.h> 18#include <linux/usb.h> 19 20#include "hid-ids.h" 21 22static bool emulate_3button = true; 23module_param(emulate_3button, bool, 0644); 24MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); 25 26static int middle_button_start = -350; 27static int middle_button_stop = +350; 28 29static bool emulate_scroll_wheel = true; 30module_param(emulate_scroll_wheel, bool, 0644); 31MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); 32 33static unsigned int scroll_speed = 32; 34static int param_set_scroll_speed(const char *val, struct kernel_param *kp) { 35 unsigned long speed; 36 if (!val || strict_strtoul(val, 0, &speed) || speed > 63) 37 return -EINVAL; 38 scroll_speed = speed; 39 return 0; 40} 41module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644); 42MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)"); 43 44static bool scroll_acceleration = false; 45module_param(scroll_acceleration, bool, 0644); 46MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); 47 48static bool report_touches = true; 49module_param(report_touches, bool, 0644); 50MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); 51 52static bool report_undeciphered; 53module_param(report_undeciphered, bool, 0644); 54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 55 56#define TOUCH_REPORT_ID 0x29 57/* These definitions are not precise, but they're close enough. (Bits 58 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem 59 * to be some kind of bit mask -- 0x20 may be a near-field reading, 60 * and 0x40 is actual contact, and 0x10 may be a start/stop or change 61 * indication.) 62 */ 63#define TOUCH_STATE_MASK 0xf0 64#define TOUCH_STATE_NONE 0x00 65#define TOUCH_STATE_START 0x30 66#define TOUCH_STATE_DRAG 0x40 67 68#define SCROLL_ACCEL_DEFAULT 7 69 70/** 71 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 72 * @input: Input device through which we report events. 73 * @quirks: Currently unused. 74 * @last_timestamp: Timestamp from most recent (18-bit) touch report 75 * (units of milliseconds over short windows, but seems to 76 * increase faster when there are no touches). 77 * @delta_time: 18-bit difference between the two most recent touch 78 * reports from the mouse. 79 * @ntouches: Number of touches in most recent touch report. 80 * @scroll_accel: Number of consecutive scroll motions. 81 * @scroll_jiffies: Time of last scroll motion. 82 * @touches: Most recent data for a touch, indexed by tracking ID. 83 * @tracking_ids: Mapping of current touch input data to @touches. 84 */ 85struct magicmouse_sc { 86 struct input_dev *input; 87 unsigned long quirks; 88 89 int last_timestamp; 90 int delta_time; 91 int ntouches; 92 int scroll_accel; 93 unsigned long scroll_jiffies; 94 95 struct { 96 short x; 97 short y; 98 short scroll_x; 99 short scroll_y; 100 u8 size; 101 u8 down; 102 } touches[16]; 103 int tracking_ids[16]; 104}; 105 106static int magicmouse_firm_touch(struct magicmouse_sc *msc) 107{ 108 int touch = -1; 109 int ii; 110 111 /* If there is only one "firm" touch, set touch to its 112 * tracking ID. 113 */ 114 for (ii = 0; ii < msc->ntouches; ii++) { 115 int idx = msc->tracking_ids[ii]; 116 if (msc->touches[idx].size < 8) { 117 /* Ignore this touch. */ 118 } else if (touch >= 0) { 119 touch = -1; 120 break; 121 } else { 122 touch = idx; 123 } 124 } 125 126 return touch; 127} 128 129static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) 130{ 131 int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 | 132 test_bit(BTN_RIGHT, msc->input->key) << 1 | 133 test_bit(BTN_MIDDLE, msc->input->key) << 2; 134 135 if (emulate_3button) { 136 int id; 137 138 /* If some button was pressed before, keep it held 139 * down. Otherwise, if there's exactly one firm 140 * touch, use that to override the mouse's guess. 141 */ 142 if (state == 0) { 143 /* The button was released. */ 144 } else if (last_state != 0) { 145 state = last_state; 146 } else if ((id = magicmouse_firm_touch(msc)) >= 0) { 147 int x = msc->touches[id].x; 148 if (x < middle_button_start) 149 state = 1; 150 else if (x > middle_button_stop) 151 state = 2; 152 else 153 state = 4; 154 } /* else: we keep the mouse's guess */ 155 156 input_report_key(msc->input, BTN_MIDDLE, state & 4); 157 } 158 159 input_report_key(msc->input, BTN_LEFT, state & 1); 160 input_report_key(msc->input, BTN_RIGHT, state & 2); 161 162 if (state != last_state) 163 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 164} 165 166static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 167{ 168 struct input_dev *input = msc->input; 169 __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; 170 int misc = tdata[5] | tdata[6] << 8; 171 int id = (misc >> 6) & 15; 172 int x = x_y << 12 >> 20; 173 int y = -(x_y >> 20); 174 int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; 175 176 /* Store tracking ID and other fields. */ 177 msc->tracking_ids[raw_id] = id; 178 msc->touches[id].x = x; 179 msc->touches[id].y = y; 180 msc->touches[id].size = misc & 63; 181 182 /* If requested, emulate a scroll wheel by detecting small 183 * vertical touch motions. 184 */ 185 if (emulate_scroll_wheel) { 186 unsigned long now = jiffies; 187 int step_x = msc->touches[id].scroll_x - x; 188 int step_y = msc->touches[id].scroll_y - y; 189 190 /* Calculate and apply the scroll motion. */ 191 switch (tdata[7] & TOUCH_STATE_MASK) { 192 case TOUCH_STATE_START: 193 msc->touches[id].scroll_x = x; 194 msc->touches[id].scroll_y = y; 195 196 /* Reset acceleration after half a second. */ 197 if (scroll_acceleration && time_before(now, 198 msc->scroll_jiffies + HZ / 2)) 199 msc->scroll_accel = max_t(int, 200 msc->scroll_accel - 1, 1); 201 else 202 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 203 204 break; 205 case TOUCH_STATE_DRAG: 206 step_x /= (64 - (int)scroll_speed) * msc->scroll_accel; 207 if (step_x != 0) { 208 msc->touches[id].scroll_x -= step_x * 209 (64 - scroll_speed) * msc->scroll_accel; 210 msc->scroll_jiffies = now; 211 input_report_rel(input, REL_HWHEEL, -step_x); 212 } 213 214 step_y /= (64 - (int)scroll_speed) * msc->scroll_accel; 215 if (step_y != 0) { 216 msc->touches[id].scroll_y -= step_y * 217 (64 - scroll_speed) * msc->scroll_accel; 218 msc->scroll_jiffies = now; 219 input_report_rel(input, REL_WHEEL, step_y); 220 } 221 break; 222 } 223 } 224 225 /* Generate the input events for this touch. */ 226 if (report_touches && down) { 227 int orientation = (misc >> 10) - 32; 228 229 msc->touches[id].down = 1; 230 231 input_report_abs(input, ABS_MT_TRACKING_ID, id); 232 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); 233 input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); 234 input_report_abs(input, ABS_MT_ORIENTATION, orientation); 235 input_report_abs(input, ABS_MT_POSITION_X, x); 236 input_report_abs(input, ABS_MT_POSITION_Y, y); 237 238 if (report_undeciphered) 239 input_event(input, EV_MSC, MSC_RAW, tdata[7]); 240 241 input_mt_sync(input); 242 } 243} 244 245static int magicmouse_raw_event(struct hid_device *hdev, 246 struct hid_report *report, u8 *data, int size) 247{ 248 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 249 struct input_dev *input = msc->input; 250 int x, y, ts, ii, clicks, last_up; 251 252 switch (data[0]) { 253 case 0x10: 254 if (size != 6) 255 return 0; 256 x = (__s16)(data[2] | data[3] << 8); 257 y = (__s16)(data[4] | data[5] << 8); 258 clicks = data[1]; 259 break; 260 case TOUCH_REPORT_ID: 261 /* Expect six bytes of prefix, and N*8 bytes of touch data. */ 262 if (size < 6 || ((size - 6) % 8) != 0) 263 return 0; 264 ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; 265 msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; 266 msc->last_timestamp = ts; 267 msc->ntouches = (size - 6) / 8; 268 for (ii = 0; ii < msc->ntouches; ii++) 269 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 270 271 if (report_touches) { 272 last_up = 1; 273 for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { 274 if (msc->touches[ii].down) { 275 last_up = 0; 276 msc->touches[ii].down = 0; 277 } 278 } 279 if (last_up) { 280 input_mt_sync(input); 281 } 282 } 283 284 /* When emulating three-button mode, it is important 285 * to have the current touch information before 286 * generating a click event. 287 */ 288 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; 289 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; 290 clicks = data[3]; 291 break; 292 case 0x20: /* Theoretically battery status (0-100), but I have 293 * never seen it -- maybe it is only upon request. 294 */ 295 case 0x60: /* Unknown, maybe laser on/off. */ 296 case 0x61: /* Laser reflection status change. 297 * data[1]: 0 = spotted, 1 = lost 298 */ 299 default: 300 return 0; 301 } 302 303 magicmouse_emit_buttons(msc, clicks & 3); 304 input_report_rel(input, REL_X, x); 305 input_report_rel(input, REL_Y, y); 306 input_sync(input); 307 return 1; 308} 309 310static int magicmouse_input_open(struct input_dev *dev) 311{ 312 struct hid_device *hid = input_get_drvdata(dev); 313 314 return hid->ll_driver->open(hid); 315} 316 317static void magicmouse_input_close(struct input_dev *dev) 318{ 319 struct hid_device *hid = input_get_drvdata(dev); 320 321 hid->ll_driver->close(hid); 322} 323 324static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 325{ 326 input_set_drvdata(input, hdev); 327 input->event = hdev->ll_driver->hidinput_input_event; 328 input->open = magicmouse_input_open; 329 input->close = magicmouse_input_close; 330 331 input->name = hdev->name; 332 input->phys = hdev->phys; 333 input->uniq = hdev->uniq; 334 input->id.bustype = hdev->bus; 335 input->id.vendor = hdev->vendor; 336 input->id.product = hdev->product; 337 input->id.version = hdev->version; 338 input->dev.parent = hdev->dev.parent; 339 340 __set_bit(EV_KEY, input->evbit); 341 __set_bit(BTN_LEFT, input->keybit); 342 __set_bit(BTN_RIGHT, input->keybit); 343 if (emulate_3button) 344 __set_bit(BTN_MIDDLE, input->keybit); 345 __set_bit(BTN_TOOL_FINGER, input->keybit); 346 347 __set_bit(EV_REL, input->evbit); 348 __set_bit(REL_X, input->relbit); 349 __set_bit(REL_Y, input->relbit); 350 if (emulate_scroll_wheel) { 351 __set_bit(REL_WHEEL, input->relbit); 352 __set_bit(REL_HWHEEL, input->relbit); 353 } 354 355 if (report_touches) { 356 __set_bit(EV_ABS, input->evbit); 357 358 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); 359 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); 360 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); 361 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); 362 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, 363 4, 0); 364 /* Note: Touch Y position from the device is inverted relative 365 * to how pointer motion is reported (and relative to how USB 366 * HID recommends the coordinates work). This driver keeps 367 * the origin at the same position, and just uses the additive 368 * inverse of the reported Y. 369 */ 370 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, 371 4, 0); 372 } 373 374 if (report_undeciphered) { 375 __set_bit(EV_MSC, input->evbit); 376 __set_bit(MSC_RAW, input->mscbit); 377 } 378} 379 380static int magicmouse_probe(struct hid_device *hdev, 381 const struct hid_device_id *id) 382{ 383 __u8 feature_1[] = { 0xd7, 0x01 }; 384 __u8 feature_2[] = { 0xf8, 0x01, 0x32 }; 385 struct input_dev *input; 386 struct magicmouse_sc *msc; 387 struct hid_report *report; 388 int ret; 389 390 msc = kzalloc(sizeof(*msc), GFP_KERNEL); 391 if (msc == NULL) { 392 dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n"); 393 return -ENOMEM; 394 } 395 396 msc->scroll_accel = SCROLL_ACCEL_DEFAULT; 397 398 msc->quirks = id->driver_data; 399 hid_set_drvdata(hdev, msc); 400 401 ret = hid_parse(hdev); 402 if (ret) { 403 dev_err(&hdev->dev, "magicmouse hid parse failed\n"); 404 goto err_free; 405 } 406 407 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 408 if (ret) { 409 dev_err(&hdev->dev, "magicmouse hw start failed\n"); 410 goto err_free; 411 } 412 413 /* we are handling the input ourselves */ 414 hidinput_disconnect(hdev); 415 416 report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); 417 if (!report) { 418 dev_err(&hdev->dev, "unable to register touch report\n"); 419 ret = -ENOMEM; 420 goto err_stop_hw; 421 } 422 report->size = 6; 423 424 ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1), 425 HID_FEATURE_REPORT); 426 if (ret != sizeof(feature_1)) { 427 dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", 428 ret); 429 goto err_stop_hw; 430 } 431 ret = hdev->hid_output_raw_report(hdev, feature_2, 432 sizeof(feature_2), HID_FEATURE_REPORT); 433 if (ret != sizeof(feature_2)) { 434 dev_err(&hdev->dev, "unable to request touch data (2:%d)\n", 435 ret); 436 goto err_stop_hw; 437 } 438 439 input = input_allocate_device(); 440 if (!input) { 441 dev_err(&hdev->dev, "can't alloc input device\n"); 442 ret = -ENOMEM; 443 goto err_stop_hw; 444 } 445 magicmouse_setup_input(input, hdev); 446 447 ret = input_register_device(input); 448 if (ret) { 449 dev_err(&hdev->dev, "input device registration failed\n"); 450 goto err_input; 451 } 452 msc->input = input; 453 454 return 0; 455err_input: 456 input_free_device(input); 457err_stop_hw: 458 hid_hw_stop(hdev); 459err_free: 460 kfree(msc); 461 return ret; 462} 463 464static void magicmouse_remove(struct hid_device *hdev) 465{ 466 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 467 468 hid_hw_stop(hdev); 469 input_unregister_device(msc->input); 470 kfree(msc); 471} 472 473static const struct hid_device_id magic_mice[] = { 474 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), 475 .driver_data = 0 }, 476 { } 477}; 478MODULE_DEVICE_TABLE(hid, magic_mice); 479 480static struct hid_driver magicmouse_driver = { 481 .name = "magicmouse", 482 .id_table = magic_mice, 483 .probe = magicmouse_probe, 484 .remove = magicmouse_remove, 485 .raw_event = magicmouse_raw_event, 486}; 487 488static int __init magicmouse_init(void) 489{ 490 int ret; 491 492 ret = hid_register_driver(&magicmouse_driver); 493 if (ret) 494 printk(KERN_ERR "can't register magicmouse driver\n"); 495 496 return ret; 497} 498 499static void __exit magicmouse_exit(void) 500{ 501 hid_unregister_driver(&magicmouse_driver); 502} 503 504module_init(magicmouse_init); 505module_exit(magicmouse_exit); 506MODULE_LICENSE("GPL"); 507