aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-magicmouse.c192
3 files changed, 155 insertions, 39 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0c52899be964..d2f9c4aa4b52 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1248,6 +1248,7 @@ static const struct hid_device_id hid_blacklist[] = {
1248 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, 1248 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
1250 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, 1250 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
1251 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
1251 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, 1252 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
1252 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, 1253 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
1253 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, 1254 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 85c6d13c9ffa..5ad4ea02157f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -63,6 +63,7 @@
63#define USB_VENDOR_ID_APPLE 0x05ac 63#define USB_VENDOR_ID_APPLE 0x05ac
64#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 64#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
65#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d 65#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
66#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
66#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e 67#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
67#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f 68#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
68#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 69#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 402682e0c2f4..8791a084693e 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -2,6 +2,7 @@
2 * Apple "Magic" Wireless Mouse driver 2 * Apple "Magic" Wireless Mouse driver
3 * 3 *
4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> 4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
5 * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
5 */ 6 */
6 7
7/* 8/*
@@ -53,7 +54,9 @@ static bool report_undeciphered;
53module_param(report_undeciphered, bool, 0644); 54module_param(report_undeciphered, bool, 0644);
54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 55MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
55 56
56#define TOUCH_REPORT_ID 0x29 57#define TRACKPAD_REPORT_ID 0x28
58#define MOUSE_REPORT_ID 0x29
59#define DOUBLE_REPORT_ID 0xf7
57/* These definitions are not precise, but they're close enough. (Bits 60/* 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 61 * 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, 62 * to be some kind of bit mask -- 0x20 may be a near-field reading,
@@ -67,6 +70,15 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
67 70
68#define SCROLL_ACCEL_DEFAULT 7 71#define SCROLL_ACCEL_DEFAULT 7
69 72
73/* Single touch emulation should only begin when no touches are currently down.
74 * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
75 * are down and the touch providing for single touch emulation is lifted,
76 * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
77 * occuring, single_touch_id corresponds with the tracking id of the touch used.
78 */
79#define NO_TOUCHES -1
80#define SINGLE_TOUCH_UP -2
81
70/** 82/**
71 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 83 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
72 * @input: Input device through which we report events. 84 * @input: Input device through which we report events.
@@ -93,6 +105,7 @@ struct magicmouse_sc {
93 u8 size; 105 u8 size;
94 } touches[16]; 106 } touches[16];
95 int tracking_ids[16]; 107 int tracking_ids[16];
108 int single_touch_id;
96}; 109};
97 110
98static int magicmouse_firm_touch(struct magicmouse_sc *msc) 111static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -158,15 +171,29 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
158static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 171static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
159{ 172{
160 struct input_dev *input = msc->input; 173 struct input_dev *input = msc->input;
161 int id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; 174 int id, x, y, size, orientation, touch_major, touch_minor, state, down;
162 int x = (tdata[1] << 28 | tdata[0] << 20) >> 20; 175
163 int y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); 176 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
164 int size = tdata[5] & 0x3f; 177 id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
165 int orientation = (tdata[6] >> 2) - 32; 178 x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
166 int touch_major = tdata[3]; 179 y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
167 int touch_minor = tdata[4]; 180 size = tdata[5] & 0x3f;
168 int state = tdata[7] & TOUCH_STATE_MASK; 181 orientation = (tdata[6] >> 2) - 32;
169 int down = state != TOUCH_STATE_NONE; 182 touch_major = tdata[3];
183 touch_minor = tdata[4];
184 state = tdata[7] & TOUCH_STATE_MASK;
185 down = state != TOUCH_STATE_NONE;
186 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
187 id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
188 x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
189 y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
190 size = tdata[6] & 0x3f;
191 orientation = (tdata[7] >> 2) - 32;
192 touch_major = tdata[4];
193 touch_minor = tdata[5];
194 state = tdata[8] & TOUCH_STATE_MASK;
195 down = state != TOUCH_STATE_NONE;
196 }
170 197
171 /* Store tracking ID and other fields. */ 198 /* Store tracking ID and other fields. */
172 msc->tracking_ids[raw_id] = id; 199 msc->tracking_ids[raw_id] = id;
@@ -217,6 +244,13 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
217 } 244 }
218 } 245 }
219 246
247 if (down) {
248 msc->ntouches++;
249 if (msc->single_touch_id == NO_TOUCHES)
250 msc->single_touch_id = id;
251 } else if (msc->single_touch_id == id)
252 msc->single_touch_id = SINGLE_TOUCH_UP;
253
220 /* Generate the input events for this touch. */ 254 /* Generate the input events for this touch. */
221 if (report_touches && down) { 255 if (report_touches && down) {
222 input_report_abs(input, ABS_MT_TRACKING_ID, id); 256 input_report_abs(input, ABS_MT_TRACKING_ID, id);
@@ -226,14 +260,15 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
226 input_report_abs(input, ABS_MT_POSITION_X, x); 260 input_report_abs(input, ABS_MT_POSITION_X, x);
227 input_report_abs(input, ABS_MT_POSITION_Y, y); 261 input_report_abs(input, ABS_MT_POSITION_Y, y);
228 262
229 if (report_undeciphered) 263 if (report_undeciphered) {
230 input_event(input, EV_MSC, MSC_RAW, tdata[7]); 264 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
265 input_event(input, EV_MSC, MSC_RAW, tdata[7]);
266 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
267 input_event(input, EV_MSC, MSC_RAW, tdata[8]);
268 }
231 269
232 input_mt_sync(input); 270 input_mt_sync(input);
233 } 271 }
234
235 if (down)
236 msc->ntouches++;
237} 272}
238 273
239static int magicmouse_raw_event(struct hid_device *hdev, 274static int magicmouse_raw_event(struct hid_device *hdev,
@@ -241,7 +276,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
241{ 276{
242 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 277 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
243 struct input_dev *input = msc->input; 278 struct input_dev *input = msc->input;
244 int x, y, ii, clicks, npoints; 279 int x = 0, y = 0, ii, clicks = 0, npoints;
245 280
246 switch (data[0]) { 281 switch (data[0]) {
247 case 0x10: 282 case 0x10:
@@ -251,7 +286,30 @@ static int magicmouse_raw_event(struct hid_device *hdev,
251 y = (__s16)(data[4] | data[5] << 8); 286 y = (__s16)(data[4] | data[5] << 8);
252 clicks = data[1]; 287 clicks = data[1];
253 break; 288 break;
254 case TOUCH_REPORT_ID: 289 case TRACKPAD_REPORT_ID:
290 /* Expect four bytes of prefix, and N*9 bytes of touch data. */
291 if (size < 4 || ((size - 4) % 9) != 0)
292 return 0;
293 npoints = (size - 4) / 9;
294 msc->ntouches = 0;
295 for (ii = 0; ii < npoints; ii++)
296 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
297
298 /* We don't need an MT sync here because trackpad emits a
299 * BTN_TOUCH event in a new frame when all touches are released.
300 */
301 if (msc->ntouches == 0)
302 msc->single_touch_id = NO_TOUCHES;
303
304 clicks = data[1];
305
306 /* The following bits provide a device specific timestamp. They
307 * are unused here.
308 *
309 * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
310 */
311 break;
312 case MOUSE_REPORT_ID:
255 /* Expect six bytes of prefix, and N*8 bytes of touch data. */ 313 /* Expect six bytes of prefix, and N*8 bytes of touch data. */
256 if (size < 6 || ((size - 6) % 8) != 0) 314 if (size < 6 || ((size - 6) % 8) != 0)
257 return 0; 315 return 0;
@@ -277,6 +335,14 @@ static int magicmouse_raw_event(struct hid_device *hdev,
277 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; 335 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
278 */ 336 */
279 break; 337 break;
338 case DOUBLE_REPORT_ID:
339 /* Sometimes the trackpad sends two touch reports in one
340 * packet.
341 */
342 magicmouse_raw_event(hdev, report, data + 2, data[1]);
343 magicmouse_raw_event(hdev, report, data + 2 + data[1],
344 size - 2 - data[1]);
345 break;
280 case 0x20: /* Theoretically battery status (0-100), but I have 346 case 0x20: /* Theoretically battery status (0-100), but I have
281 * never seen it -- maybe it is only upon request. 347 * never seen it -- maybe it is only upon request.
282 */ 348 */
@@ -288,9 +354,25 @@ static int magicmouse_raw_event(struct hid_device *hdev,
288 return 0; 354 return 0;
289 } 355 }
290 356
291 magicmouse_emit_buttons(msc, clicks & 3); 357 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
292 input_report_rel(input, REL_X, x); 358 magicmouse_emit_buttons(msc, clicks & 3);
293 input_report_rel(input, REL_Y, y); 359 input_report_rel(input, REL_X, x);
360 input_report_rel(input, REL_Y, y);
361 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
362 input_report_key(input, BTN_MOUSE, clicks & 1);
363 input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
364 input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
365 input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
366 input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
367 input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
368 if (msc->single_touch_id >= 0) {
369 input_report_abs(input, ABS_X,
370 msc->touches[msc->single_touch_id].x);
371 input_report_abs(input, ABS_Y,
372 msc->touches[msc->single_touch_id].y);
373 }
374 }
375
294 input_sync(input); 376 input_sync(input);
295 return 1; 377 return 1;
296} 378}
@@ -326,18 +408,27 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
326 input->dev.parent = hdev->dev.parent; 408 input->dev.parent = hdev->dev.parent;
327 409
328 __set_bit(EV_KEY, input->evbit); 410 __set_bit(EV_KEY, input->evbit);
329 __set_bit(BTN_LEFT, input->keybit); 411
330 __set_bit(BTN_RIGHT, input->keybit); 412 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
331 if (emulate_3button) 413 __set_bit(BTN_LEFT, input->keybit);
332 __set_bit(BTN_MIDDLE, input->keybit); 414 __set_bit(BTN_RIGHT, input->keybit);
333 __set_bit(BTN_TOOL_FINGER, input->keybit); 415 if (emulate_3button)
334 416 __set_bit(BTN_MIDDLE, input->keybit);
335 __set_bit(EV_REL, input->evbit); 417
336 __set_bit(REL_X, input->relbit); 418 __set_bit(EV_REL, input->evbit);
337 __set_bit(REL_Y, input->relbit); 419 __set_bit(REL_X, input->relbit);
338 if (emulate_scroll_wheel) { 420 __set_bit(REL_Y, input->relbit);
339 __set_bit(REL_WHEEL, input->relbit); 421 if (emulate_scroll_wheel) {
340 __set_bit(REL_HWHEEL, input->relbit); 422 __set_bit(REL_WHEEL, input->relbit);
423 __set_bit(REL_HWHEEL, input->relbit);
424 }
425 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
426 __set_bit(BTN_MOUSE, input->keybit);
427 __set_bit(BTN_TOOL_FINGER, input->keybit);
428 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
429 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
430 __set_bit(BTN_TOOL_QUADTAP, input->keybit);
431 __set_bit(BTN_TOUCH, input->keybit);
341 } 432 }
342 433
343 if (report_touches) { 434 if (report_touches) {
@@ -347,16 +438,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
347 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); 438 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
348 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); 439 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
349 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); 440 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
350 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, 441
351 4, 0);
352 /* Note: Touch Y position from the device is inverted relative 442 /* Note: Touch Y position from the device is inverted relative
353 * to how pointer motion is reported (and relative to how USB 443 * to how pointer motion is reported (and relative to how USB
354 * HID recommends the coordinates work). This driver keeps 444 * HID recommends the coordinates work). This driver keeps
355 * the origin at the same position, and just uses the additive 445 * the origin at the same position, and just uses the additive
356 * inverse of the reported Y. 446 * inverse of the reported Y.
357 */ 447 */
358 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, 448 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
359 4, 0); 449 input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
450 1358, 4, 0);
451 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
452 2047, 4, 0);
453 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
454 input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
455 input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
456 input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
457 3167, 4, 0);
458 input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
459 2565, 4, 0);
460 }
360 } 461 }
361 462
362 if (report_undeciphered) { 463 if (report_undeciphered) {
@@ -385,6 +486,8 @@ static int magicmouse_probe(struct hid_device *hdev,
385 msc->quirks = id->driver_data; 486 msc->quirks = id->driver_data;
386 hid_set_drvdata(hdev, msc); 487 hid_set_drvdata(hdev, msc);
387 488
489 msc->single_touch_id = NO_TOUCHES;
490
388 ret = hid_parse(hdev); 491 ret = hid_parse(hdev);
389 if (ret) { 492 if (ret) {
390 dev_err(&hdev->dev, "magicmouse hid parse failed\n"); 493 dev_err(&hdev->dev, "magicmouse hid parse failed\n");
@@ -400,7 +503,16 @@ static int magicmouse_probe(struct hid_device *hdev,
400 /* we are handling the input ourselves */ 503 /* we are handling the input ourselves */
401 hidinput_disconnect(hdev); 504 hidinput_disconnect(hdev);
402 505
403 report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); 506 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
507 report = hid_register_report(hdev, HID_INPUT_REPORT,
508 MOUSE_REPORT_ID);
509 else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
510 report = hid_register_report(hdev, HID_INPUT_REPORT,
511 TRACKPAD_REPORT_ID);
512 report = hid_register_report(hdev, HID_INPUT_REPORT,
513 DOUBLE_REPORT_ID);
514 }
515
404 if (!report) { 516 if (!report) {
405 dev_err(&hdev->dev, "unable to register touch report\n"); 517 dev_err(&hdev->dev, "unable to register touch report\n");
406 ret = -ENOMEM; 518 ret = -ENOMEM;
@@ -451,8 +563,10 @@ static void magicmouse_remove(struct hid_device *hdev)
451} 563}
452 564
453static const struct hid_device_id magic_mice[] = { 565static const struct hid_device_id magic_mice[] = {
454 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), 566 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
455 .driver_data = 0 }, 567 USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
568 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
569 USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
456 { } 570 { }
457}; 571};
458MODULE_DEVICE_TABLE(hid, magic_mice); 572MODULE_DEVICE_TABLE(hid, magic_mice);