Advertisement
Guest User

linux 2.6.35 magic trackpad patch

a guest
Sep 2nd, 2010
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 18.88 KB | None | 0 0
  1. --- a/drivers/hid/hid-core.c    2010-08-01 18:11:14.000000000 -0400
  2. +++ b/drivers/hid/hid-core.c    2010-09-02 16:13:18.723462269 -0400
  3. @@ -1239,10 +1241,14 @@
  4.     { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
  5.     { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
  6.     { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
  7. +#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
  8. +   { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
  9. +#endif
  10.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
  11.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
  12.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
  13.     { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
  14. +   { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
  15.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
  16.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
  17.     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
  18.  
  19. --- a/drivers/hid/hid-ids.h 2010-08-01 18:11:14.000000000 -0400
  20. +++ b/drivers/hid/hid-ids.h 2010-09-02 16:13:18.853443470 -0400
  21. @@ -61,6 +63,7 @@
  22.  #define USB_VENDOR_ID_APPLE        0x05ac
  23.  #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE    0x0304
  24.  #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
  25. +#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD  0x030e
  26.  #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI  0x020e
  27.  #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO   0x020f
  28.  #define USB_DEVICE_ID_APPLE_GEYSER_ANSI    0x0214
  29.  
  30. --- a/drivers/hid/hid-magicmouse.c  2010-08-01 18:11:14.000000000 -0400
  31. +++ b/drivers/hid/hid-magicmouse.c  2010-09-02 16:13:19.103407323 -0400
  32. @@ -2,6 +2,7 @@
  33.   *   Apple "Magic" Wireless Mouse driver
  34.   *
  35.   *   Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
  36. + *   Copyright (c) 2010 Chase Douglas <chase.douglas@xxxxxxxxxxxxx>
  37.   */
  38.  
  39.  /*
  40. @@ -30,6 +31,21 @@
  41.  module_param(emulate_scroll_wheel, bool, 0644);
  42.  MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
  43.  
  44. +static unsigned int scroll_speed = 32;
  45. +static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
  46. +   unsigned long speed;
  47. +   if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
  48. +       return -EINVAL;
  49. +   scroll_speed = speed;
  50. +   return 0;
  51. +}
  52. +module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
  53. +MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
  54. +
  55. +static bool scroll_acceleration = false;
  56. +module_param(scroll_acceleration, bool, 0644);
  57. +MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
  58. +
  59.  static bool report_touches = true;
  60.  module_param(report_touches, bool, 0644);
  61.  MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
  62. @@ -38,7 +54,9 @@
  63.  module_param(report_undeciphered, bool, 0644);
  64.  MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
  65.  
  66. -#define TOUCH_REPORT_ID   0x29
  67. +#define TRACKPAD_REPORT_ID 0x28
  68. +#define MOUSE_REPORT_ID    0x29
  69. +#define DOUBLE_REPORT_ID   0xf7
  70.  /* These definitions are not precise, but they're close enough.  (Bits
  71.   * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
  72.   * to be some kind of bit mask -- 0x20 may be a near-field reading,
  73. @@ -50,15 +68,21 @@
  74.  #define TOUCH_STATE_START 0x30
  75.  #define TOUCH_STATE_DRAG  0x40
  76.  
  77. +#define SCROLL_ACCEL_DEFAULT 7
  78. +
  79. +/* Single touch emulation should only begin when no touches are currently down.
  80. + * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
  81. + * are down and the touch providing for single touch emulation is lifted,
  82. + * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
  83. + * occuring, single_touch_id corresponds with the tracking id of the touch used.
  84. + */
  85. +#define NO_TOUCHES -1
  86. +#define SINGLE_TOUCH_UP -2
  87. +
  88.  /**
  89.   * struct magicmouse_sc - Tracks Magic Mouse-specific data.
  90.   * @input: Input device through which we report events.
  91.   * @quirks: Currently unused.
  92. - * @last_timestamp: Timestamp from most recent (18-bit) touch report
  93. - *     (units of milliseconds over short windows, but seems to
  94. - *     increase faster when there are no touches).
  95. - * @delta_time: 18-bit difference between the two most recent touch
  96. - *     reports from the mouse.
  97.   * @ntouches: Number of touches in most recent touch report.
  98.   * @scroll_accel: Number of consecutive scroll motions.
  99.   * @scroll_jiffies: Time of last scroll motion.
  100. @@ -69,8 +93,6 @@
  101.     struct input_dev *input;
  102.     unsigned long quirks;
  103.  
  104. -   int last_timestamp;
  105. -   int delta_time;
  106.     int ntouches;
  107.     int scroll_accel;
  108.     unsigned long scroll_jiffies;
  109. @@ -78,10 +100,12 @@
  110.     struct {
  111.         short x;
  112.         short y;
  113. +       short scroll_x;
  114.         short scroll_y;
  115.         u8 size;
  116.     } touches[16];
  117.     int tracking_ids[16];
  118. +   int single_touch_id;
  119.  };
  120.  
  121.  static int magicmouse_firm_touch(struct magicmouse_sc *msc)
  122. @@ -141,70 +165,107 @@
  123.     input_report_key(msc->input, BTN_RIGHT, state & 2);
  124.  
  125.     if (state != last_state)
  126. -       msc->scroll_accel = 0;
  127. +       msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
  128.  }
  129.  
  130.  static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
  131.  {
  132.     struct input_dev *input = msc->input;
  133. -   __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24;
  134. -   int misc = tdata[5] | tdata[6] << 8;
  135. -   int id = (misc >> 6) & 15;
  136. -   int x = x_y << 12 >> 20;
  137. -   int y = -(x_y >> 20);
  138. +   int id, x, y, size, orientation, touch_major, touch_minor, state, down;
  139. +
  140. +   if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  141. +       id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
  142. +       x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
  143. +       y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
  144. +       size = tdata[5] & 0x3f;
  145. +       orientation = (tdata[6] >> 2) - 32;
  146. +       touch_major = tdata[3];
  147. +       touch_minor = tdata[4];
  148. +       state = tdata[7] & TOUCH_STATE_MASK;
  149. +       down = state != TOUCH_STATE_NONE;
  150. +   } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  151. +       id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
  152. +       x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
  153. +       y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
  154. +       size = tdata[6] & 0x3f;
  155. +       orientation = (tdata[7] >> 2) - 32;
  156. +       touch_major = tdata[4];
  157. +       touch_minor = tdata[5];
  158. +       state = tdata[8] & TOUCH_STATE_MASK;
  159. +       down = state != TOUCH_STATE_NONE;
  160. +   }
  161.  
  162.     /* Store tracking ID and other fields. */
  163.     msc->tracking_ids[raw_id] = id;
  164.     msc->touches[id].x = x;
  165.     msc->touches[id].y = y;
  166. -   msc->touches[id].size = misc & 63;
  167. +   msc->touches[id].size = size;
  168.  
  169.     /* If requested, emulate a scroll wheel by detecting small
  170. -    * vertical touch motions along the middle of the mouse.
  171. +    * vertical touch motions.
  172.      */
  173. -   if (emulate_scroll_wheel &&
  174. -       middle_button_start < x && x < middle_button_stop) {
  175. -       static const int accel_profile[] = {
  176. -           256, 228, 192, 160, 128, 96, 64, 32,
  177. -       };
  178. +   if (emulate_scroll_wheel) {
  179.         unsigned long now = jiffies;
  180. -       int step = msc->touches[id].scroll_y - y;
  181. -
  182. -       /* Reset acceleration after half a second. */
  183. -       if (time_after(now, msc->scroll_jiffies + HZ / 2))
  184. -           msc->scroll_accel = 0;
  185. +       int step_x = msc->touches[id].scroll_x - x;
  186. +       int step_y = msc->touches[id].scroll_y - y;
  187.  
  188.         /* Calculate and apply the scroll motion. */
  189. -       switch (tdata[7] & TOUCH_STATE_MASK) {
  190. +       switch (state) {
  191.         case TOUCH_STATE_START:
  192. +           msc->touches[id].scroll_x = x;
  193.             msc->touches[id].scroll_y = y;
  194. -           msc->scroll_accel = min_t(int, msc->scroll_accel + 1,
  195. -                       ARRAY_SIZE(accel_profile) - 1);
  196. +
  197. +           /* Reset acceleration after half a second. */
  198. +           if (scroll_acceleration && time_before(now,
  199. +                       msc->scroll_jiffies + HZ / 2))
  200. +               msc->scroll_accel = max_t(int,
  201. +                       msc->scroll_accel - 1, 1);
  202. +           else
  203. +               msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
  204. +
  205.             break;
  206.         case TOUCH_STATE_DRAG:
  207. -           step = step / accel_profile[msc->scroll_accel];
  208. -           if (step != 0) {
  209. -               msc->touches[id].scroll_y = y;
  210. +           step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
  211. +           if (step_x != 0) {
  212. +               msc->touches[id].scroll_x -= step_x *
  213. +                   (64 - scroll_speed) * msc->scroll_accel;
  214.                 msc->scroll_jiffies = now;
  215. -               input_report_rel(input, REL_WHEEL, step);
  216. +               input_report_rel(input, REL_HWHEEL, -step_x);
  217. +           }
  218. +
  219. +           step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
  220. +           if (step_y != 0) {
  221. +               msc->touches[id].scroll_y -= step_y *
  222. +                   (64 - scroll_speed) * msc->scroll_accel;
  223. +               msc->scroll_jiffies = now;
  224. +               input_report_rel(input, REL_WHEEL, step_y);
  225.             }
  226.             break;
  227.         }
  228.     }
  229.  
  230. -   /* Generate the input events for this touch. */
  231. -   if (report_touches) {
  232. -       int orientation = (misc >> 10) - 32;
  233. +   if (down) {
  234. +       msc->ntouches++;
  235. +       if (msc->single_touch_id == NO_TOUCHES)
  236. +           msc->single_touch_id = id;
  237. +   } else if (msc->single_touch_id == id)
  238. +       msc->single_touch_id = SINGLE_TOUCH_UP;
  239.  
  240. +   /* Generate the input events for this touch. */
  241. +   if (report_touches && down) {
  242.         input_report_abs(input, ABS_MT_TRACKING_ID, id);
  243. -       input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
  244. -       input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
  245. +       input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
  246. +       input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
  247.         input_report_abs(input, ABS_MT_ORIENTATION, orientation);
  248.         input_report_abs(input, ABS_MT_POSITION_X, x);
  249.         input_report_abs(input, ABS_MT_POSITION_Y, y);
  250.  
  251. -       if (report_undeciphered)
  252. -           input_event(input, EV_MSC, MSC_RAW, tdata[7]);
  253. +       if (report_undeciphered) {
  254. +           if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
  255. +               input_event(input, EV_MSC, MSC_RAW, tdata[7]);
  256. +           else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  257. +               input_event(input, EV_MSC, MSC_RAW, tdata[8]);
  258. +       }
  259.  
  260.         input_mt_sync(input);
  261.     }
  262. @@ -215,7 +276,7 @@
  263.  {
  264.     struct magicmouse_sc *msc = hid_get_drvdata(hdev);
  265.     struct input_dev *input = msc->input;
  266. -   int x, y, ts, ii, clicks;
  267. +   int x = 0, y = 0, ii, clicks = 0, npoints;
  268.  
  269.     switch (data[0]) {
  270.     case 0x10:
  271. @@ -225,23 +286,62 @@
  272.         y = (__s16)(data[4] | data[5] << 8);
  273.         clicks = data[1];
  274.         break;
  275. -   case TOUCH_REPORT_ID:
  276. +   case TRACKPAD_REPORT_ID:
  277. +       /* Expect four bytes of prefix, and N*9 bytes of touch data. */
  278. +       if (size < 4 || ((size - 4) % 9) != 0)
  279. +           return 0;
  280. +       npoints = (size - 4) / 9;
  281. +       msc->ntouches = 0;
  282. +       for (ii = 0; ii < npoints; ii++)
  283. +           magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
  284. +
  285. +       /* We don't need an MT sync here because trackpad emits a
  286. +        * BTN_TOUCH event in a new frame when all touches are released.
  287. +        */
  288. +       if (msc->ntouches == 0)
  289. +           msc->single_touch_id = NO_TOUCHES;
  290. +
  291. +       clicks = data[1];
  292. +
  293. +       /* The following bits provide a device specific timestamp. They
  294. +        * are unused here.
  295. +        *
  296. +        * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
  297. +        */
  298. +       break;
  299. +   case MOUSE_REPORT_ID:
  300.         /* Expect six bytes of prefix, and N*8 bytes of touch data. */
  301.         if (size < 6 || ((size - 6) % 8) != 0)
  302.             return 0;
  303. -       ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
  304. -       msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff;
  305. -       msc->last_timestamp = ts;
  306. -       msc->ntouches = (size - 6) / 8;
  307. -       for (ii = 0; ii < msc->ntouches; ii++)
  308. +       npoints = (size - 6) / 8;
  309. +       msc->ntouches = 0;
  310. +       for (ii = 0; ii < npoints; ii++)
  311.             magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
  312. +
  313. +       if (report_touches && msc->ntouches == 0)
  314. +           input_mt_sync(input);
  315. +
  316.         /* When emulating three-button mode, it is important
  317.          * to have the current touch information before
  318.          * generating a click event.
  319.          */
  320. -       x = (signed char)data[1];
  321. -       y = (signed char)data[2];
  322. +       x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
  323. +       y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
  324.         clicks = data[3];
  325. +
  326. +       /* The following bits provide a device specific timestamp. They
  327. +        * are unused here.
  328. +        *
  329. +        * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
  330. +        */
  331. +       break;
  332. +   case DOUBLE_REPORT_ID:
  333. +       /* Sometimes the trackpad sends two touch reports in one
  334. +        * packet.
  335. +        */
  336. +       magicmouse_raw_event(hdev, report, data + 2, data[1]);
  337. +       magicmouse_raw_event(hdev, report, data + 2 + data[1],
  338. +           size - 2 - data[1]);
  339.         break;
  340.     case 0x20: /* Theoretically battery status (0-100), but I have
  341.             * never seen it -- maybe it is only upon request.
  342. @@ -254,9 +354,25 @@
  343.         return 0;
  344.     }
  345.  
  346. -   magicmouse_emit_buttons(msc, clicks & 3);
  347. -   input_report_rel(input, REL_X, x);
  348. -   input_report_rel(input, REL_Y, y);
  349. +   if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  350. +       magicmouse_emit_buttons(msc, clicks & 3);
  351. +       input_report_rel(input, REL_X, x);
  352. +       input_report_rel(input, REL_Y, y);
  353. +   } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  354. +       input_report_key(input, BTN_MOUSE, clicks & 1);
  355. +       input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
  356. +       input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
  357. +       input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
  358. +       input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
  359. +       input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
  360. +       if (msc->single_touch_id >= 0) {
  361. +           input_report_abs(input, ABS_X,
  362. +               msc->touches[msc->single_touch_id].x);
  363. +           input_report_abs(input, ABS_Y,
  364. +               msc->touches[msc->single_touch_id].y);
  365. +       }
  366. +   }
  367. +
  368.     input_sync(input);
  369.     return 1;
  370.  }
  371. @@ -292,17 +408,28 @@
  372.     input->dev.parent = hdev->dev.parent;
  373.  
  374.     __set_bit(EV_KEY, input->evbit);
  375. -   __set_bit(BTN_LEFT, input->keybit);
  376. -   __set_bit(BTN_RIGHT, input->keybit);
  377. -   if (emulate_3button)
  378. -       __set_bit(BTN_MIDDLE, input->keybit);
  379. -   __set_bit(BTN_TOOL_FINGER, input->keybit);
  380. -
  381. -   __set_bit(EV_REL, input->evbit);
  382. -   __set_bit(REL_X, input->relbit);
  383. -   __set_bit(REL_Y, input->relbit);
  384. -   if (emulate_scroll_wheel)
  385. -       __set_bit(REL_WHEEL, input->relbit);
  386. +
  387. +   if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  388. +       __set_bit(BTN_LEFT, input->keybit);
  389. +       __set_bit(BTN_RIGHT, input->keybit);
  390. +       if (emulate_3button)
  391. +           __set_bit(BTN_MIDDLE, input->keybit);
  392. +
  393. +       __set_bit(EV_REL, input->evbit);
  394. +       __set_bit(REL_X, input->relbit);
  395. +       __set_bit(REL_Y, input->relbit);
  396. +       if (emulate_scroll_wheel) {
  397. +           __set_bit(REL_WHEEL, input->relbit);
  398. +           __set_bit(REL_HWHEEL, input->relbit);
  399. +       }
  400. +   } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  401. +       __set_bit(BTN_MOUSE, input->keybit);
  402. +       __set_bit(BTN_TOOL_FINGER, input->keybit);
  403. +       __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
  404. +       __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
  405. +       __set_bit(BTN_TOOL_QUADTAP, input->keybit);
  406. +       __set_bit(BTN_TOUCH, input->keybit);
  407. +   }
  408.  
  409.     if (report_touches) {
  410.         __set_bit(EV_ABS, input->evbit);
  411. @@ -311,16 +438,26 @@
  412.         input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
  413.         input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
  414.         input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
  415. -       input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358,
  416. -               4, 0);
  417. +
  418.         /* Note: Touch Y position from the device is inverted relative
  419.          * to how pointer motion is reported (and relative to how USB
  420.          * HID recommends the coordinates work).  This driver keeps
  421.          * the origin at the same position, and just uses the additive
  422.          * inverse of the reported Y.
  423.          */
  424. -       input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047,
  425. -               4, 0);
  426. +       if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  427. +           input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
  428. +               1358, 4, 0);
  429. +           input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
  430. +               2047, 4, 0);
  431. +       } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  432. +           input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
  433. +           input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
  434. +           input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
  435. +               3167, 4, 0);
  436. +           input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
  437. +               2565, 4, 0);
  438. +       }
  439.     }
  440.  
  441.     if (report_undeciphered) {
  442. @@ -332,8 +469,7 @@
  443.  static int magicmouse_probe(struct hid_device *hdev,
  444.     const struct hid_device_id *id)
  445.  {
  446. -   __u8 feature_1[] = { 0xd7, 0x01 };
  447. -   __u8 feature_2[] = { 0xf8, 0x01, 0x32 };
  448. +   __u8 feature[] = { 0xd7, 0x01 };
  449.     struct input_dev *input;
  450.     struct magicmouse_sc *msc;
  451.     struct hid_report *report;
  452. @@ -345,25 +481,43 @@
  453.         return -ENOMEM;
  454.     }
  455.  
  456. +   msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
  457. +
  458.     msc->quirks = id->driver_data;
  459.     hid_set_drvdata(hdev, msc);
  460.  
  461. +   msc->single_touch_id = NO_TOUCHES;
  462. +
  463.     ret = hid_parse(hdev);
  464.     if (ret) {
  465.         dev_err(&hdev->dev, "magicmouse hid parse failed\n");
  466.         goto err_free;
  467.     }
  468.  
  469. -   ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
  470. +   /* When registering a hid device, one of hidinput, hidraw, or hiddev
  471. +    * subsystems must claim the device. We are bypassing hidinput due to
  472. +    * our raw event processing, and hidraw and hiddev may not claim the
  473. +    * device. We get around this by telling hid_hw_start that input has
  474. +    * claimed the device already, and then flipping the bit back.
  475. +    */
  476. +   hdev->claimed = HID_CLAIMED_INPUT;
  477. +   ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT);
  478. +   hdev->claimed &= ~HID_CLAIMED_INPUT;
  479.     if (ret) {
  480.         dev_err(&hdev->dev, "magicmouse hw start failed\n");
  481.         goto err_free;
  482.     }
  483.  
  484. -   /* we are handling the input ourselves */
  485. -   hidinput_disconnect(hdev);
  486. +   if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
  487. +       report = hid_register_report(hdev, HID_INPUT_REPORT,
  488. +           MOUSE_REPORT_ID);
  489. +   else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  490. +       report = hid_register_report(hdev, HID_INPUT_REPORT,
  491. +           TRACKPAD_REPORT_ID);
  492. +       report = hid_register_report(hdev, HID_INPUT_REPORT,
  493. +           DOUBLE_REPORT_ID);
  494. +   }
  495.  
  496. -   report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID);
  497.     if (!report) {
  498.         dev_err(&hdev->dev, "unable to register touch report\n");
  499.         ret = -ENOMEM;
  500. @@ -371,17 +525,10 @@
  501.     }
  502.     report->size = 6;
  503.  
  504. -   ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1),
  505. +   ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
  506.             HID_FEATURE_REPORT);
  507. -   if (ret != sizeof(feature_1)) {
  508. -       dev_err(&hdev->dev, "unable to request touch data (1:%d)\n",
  509. -               ret);
  510. -       goto err_stop_hw;
  511. -   }
  512. -   ret = hdev->hid_output_raw_report(hdev, feature_2,
  513. -           sizeof(feature_2), HID_FEATURE_REPORT);
  514. -   if (ret != sizeof(feature_2)) {
  515. -       dev_err(&hdev->dev, "unable to request touch data (2:%d)\n",
  516. +   if (ret != sizeof(feature)) {
  517. +       dev_err(&hdev->dev, "unable to request touch data (%d)\n",
  518.                 ret);
  519.         goto err_stop_hw;
  520.     }
  521. @@ -421,8 +568,10 @@
  522.  }
  523.  
  524.  static const struct hid_device_id magic_mice[] = {
  525. -   { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE),
  526. -       .driver_data = 0 },
  527. +   { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
  528. +       USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
  529. +   { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
  530. +       USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
  531.     { }
  532.  };
  533.  MODULE_DEVICE_TABLE(hid, magic_mice);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement