* [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device @ 2010-08-31 18:41 Chase Douglas 2010-08-31 18:41 ` [PATCH 2/6 v2] HID: magicmouse: move features reports to static array Chase Douglas ` (5 more replies) 0 siblings, 6 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel From: Chase Douglas <chase.douglas@ubuntu.com> The driver listens only for raw events from the device. If we allow the hidinput layer to initialize, we can hit NULL pointer dereferences in the hidinput layer because disconnecting only removes the hidinput devices from the hid device while leaving the hid fields configured. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> --- Note that this mimics what the hid-picolcd module does. drivers/hid/hid-magicmouse.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 319b0e5..d38b529 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -404,15 +404,20 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + /* When registering a hid device, one of hidinput, hidraw, or hiddev + * subsystems must claim the device. We are bypassing hidinput due to + * our raw event processing, and hidraw and hiddev may not claim the + * device. We get around this by telling hid_hw_start that input has + * claimed the device already, and then flipping the bit back. + */ + hdev->claimed = HID_CLAIMED_INPUT; + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT); + hdev->claimed &= ~HID_CLAIMED_INPUT; if (ret) { dev_err(&hdev->dev, "magicmouse hw start failed\n"); goto err_free; } - /* we are handling the input ourselves */ - hidinput_disconnect(hdev); - report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); if (!report) { dev_err(&hdev->dev, "unable to register touch report\n"); -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/6 v2] HID: magicmouse: move features reports to static array 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas @ 2010-08-31 18:41 ` Chase Douglas 2010-08-31 18:41 ` [PATCH 3/6 v2] HID: magicmouse: simplify touch data bit manipulation Chase Douglas ` (4 subsequent siblings) 5 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel From: Chase Douglas <chase.douglas@ubuntu.com> By moving the feature reports to an array, we can easily support more products with different initialization reports. This will be useful for enabling the Apple Magic Trackpad. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Michael Poole <mdpoole@troilus.org> --- drivers/hid/hid-magicmouse.c | 35 ++++++++++++++++++++--------------- 1 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index d38b529..3a2147d 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -377,14 +377,23 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h } } +struct feature { + __u8 data[3]; + __u8 length; +}; + +static struct feature mouse_features[] = { + { { 0xd7, 0x01 }, 2 }, + { { 0xf8, 0x01, 0x32 }, 3 } +}; + static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { - __u8 feature_1[] = { 0xd7, 0x01 }; - __u8 feature_2[] = { 0xf8, 0x01, 0x32 }; struct input_dev *input; struct magicmouse_sc *msc; struct hid_report *report; + int i; int ret; msc = kzalloc(sizeof(*msc), GFP_KERNEL); @@ -426,19 +435,15 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; - ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1), - HID_FEATURE_REPORT); - if (ret != sizeof(feature_1)) { - dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", - ret); - goto err_stop_hw; - } - ret = hdev->hid_output_raw_report(hdev, feature_2, - sizeof(feature_2), HID_FEATURE_REPORT); - if (ret != sizeof(feature_2)) { - dev_err(&hdev->dev, "unable to request touch data (2:%d)\n", - ret); - goto err_stop_hw; + for (i = 0; i < ARRAY_SIZE(mouse_features); i++) { + ret = hdev->hid_output_raw_report(hdev, mouse_features[i].data, + mouse_features[i].length, HID_FEATURE_REPORT); + if (ret != mouse_features[i].length) { + dev_err(&hdev->dev, + "unable to request touch data (%d:%d)\n", + i, ret); + goto err_stop_hw; + } } input = input_allocate_device(); -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 3/6 v2] HID: magicmouse: simplify touch data bit manipulation 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas 2010-08-31 18:41 ` [PATCH 2/6 v2] HID: magicmouse: move features reports to static array Chase Douglas @ 2010-08-31 18:41 ` Chase Douglas 2010-08-31 18:41 ` [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering Chase Douglas ` (3 subsequent siblings) 5 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel The new format should be easier to read to determine which bits correspond to which data. It also brings all the manipulation logic to the top of the function. This makes size and orientation reading more clear. Note that the impetus for this change is the forthcoming support for the Magic Trackpad, which has a different touch data protocol. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Michael Poole <mdpoole@troilus.org> --- drivers/hid/hid-magicmouse.c | 25 +++++++++++++------------ 1 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 3a2147d..98bbc53 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -166,18 +166,21 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) { struct input_dev *input = msc->input; - __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; - int misc = tdata[5] | tdata[6] << 8; - int id = (misc >> 6) & 15; - int x = x_y << 12 >> 20; - int y = -(x_y >> 20); - int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; + int id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; + int x = (tdata[1] << 28 | tdata[0] << 20) >> 20; + int y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); + int size = tdata[5] & 0x3f; + int orientation = (tdata[6] >> 2) - 32; + int touch_major = tdata[3]; + int touch_minor = tdata[4]; + int state = tdata[7] & TOUCH_STATE_MASK; + int down = state != TOUCH_STATE_NONE; /* Store tracking ID and other fields. */ msc->tracking_ids[raw_id] = id; msc->touches[id].x = x; msc->touches[id].y = y; - msc->touches[id].size = misc & 63; + msc->touches[id].size = size; /* If requested, emulate a scroll wheel by detecting small * vertical touch motions. @@ -188,7 +191,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda int step_y = msc->touches[id].scroll_y - y; /* Calculate and apply the scroll motion. */ - switch (tdata[7] & TOUCH_STATE_MASK) { + switch (state) { case TOUCH_STATE_START: msc->touches[id].scroll_x = x; msc->touches[id].scroll_y = y; @@ -224,13 +227,11 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda /* Generate the input events for this touch. */ if (report_touches && down) { - int orientation = (misc >> 10) - 32; - msc->touches[id].down = 1; input_report_abs(input, ABS_MT_TRACKING_ID, id); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); - input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); + input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); input_report_abs(input, ABS_MT_ORIENTATION, orientation); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas 2010-08-31 18:41 ` [PATCH 2/6 v2] HID: magicmouse: move features reports to static array Chase Douglas 2010-08-31 18:41 ` [PATCH 3/6 v2] HID: magicmouse: simplify touch data bit manipulation Chase Douglas @ 2010-08-31 18:41 ` Chase Douglas 2010-08-31 20:34 ` Henrik Rydberg 2010-08-31 18:41 ` [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support Chase Douglas ` (2 subsequent siblings) 5 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel The Magic Mouse device is very precise. No driver filtering of input data needs to be performed. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Michael Poole <mdpoole@troilus.org> --- drivers/hid/hid-magicmouse.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 98bbc53..0fe2464 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -357,11 +357,11 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); - input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); + input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, - 4, 0); + 0, 0); /* Note: Touch Y position from the device is inverted relative * to how pointer motion is reported (and relative to how USB * HID recommends the coordinates work). This driver keeps @@ -369,7 +369,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h * inverse of the reported Y. */ input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, - 4, 0); + 0, 0); } if (report_undeciphered) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 18:41 ` [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering Chase Douglas @ 2010-08-31 20:34 ` Henrik Rydberg 2010-08-31 20:58 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 20:34 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 08:41 PM, Chase Douglas wrote: > The Magic Mouse device is very precise. No driver filtering of input > data needs to be performed. > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > Acked-by: Michael Poole <mdpoole@troilus.org> > --- I am still not sure this is a good idea. Bandwidth from MT devices is a big deal. A statement roughly how much data comes out of mtdev (which does the filtering for type A devices) before and after this change would be reassuring. Cheers, Henrik > drivers/hid/hid-magicmouse.c | 10 +++++----- > 1 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > index 98bbc53..0fe2464 100644 > --- a/drivers/hid/hid-magicmouse.c > +++ b/drivers/hid/hid-magicmouse.c > @@ -357,11 +357,11 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > __set_bit(EV_ABS, input->evbit); > > input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); > - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); > - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); > - input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); > + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); > + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); > + input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); > input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, > - 4, 0); > + 0, 0); > /* Note: Touch Y position from the device is inverted relative > * to how pointer motion is reported (and relative to how USB > * HID recommends the coordinates work). This driver keeps > @@ -369,7 +369,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > * inverse of the reported Y. > */ > input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, > - 4, 0); > + 0, 0); > } > > if (report_undeciphered) { ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 20:34 ` Henrik Rydberg @ 2010-08-31 20:58 ` Chase Douglas 2010-08-31 21:06 ` Henrik Rydberg 0 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 20:58 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > On 08/31/2010 08:41 PM, Chase Douglas wrote: > > > The Magic Mouse device is very precise. No driver filtering of input > > data needs to be performed. > > > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > > Acked-by: Michael Poole <mdpoole@troilus.org> > > --- > > > I am still not sure this is a good idea. Bandwidth from MT devices is a big > deal. A statement roughly how much data comes out of mtdev (which does the > filtering for type A devices) before and after this change would be reassuring. As it is right now, hid-magicmouse doesn't support MT slots. I think all the fuzz code ends up comparing in the MT case is between one touch and another touch, not between one touch's current location and its previous location. If I'm correct, then it means a fuzz > 0 is incorrect for non-slotted MT devices. In fact, the code in drivers/input/input.c around line 194 looks like it discards defuzzing in this case, so one could say this patch is making things more correct :). Now a fuzz > 0 for the non-MT ABS axes may be useful, but this device exhibits no jitter, and we're not really worried about bandwidth in the single touch case. -- Chase > > drivers/hid/hid-magicmouse.c | 10 +++++----- > > 1 files changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > > index 98bbc53..0fe2464 100644 > > --- a/drivers/hid/hid-magicmouse.c > > +++ b/drivers/hid/hid-magicmouse.c > > @@ -357,11 +357,11 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > > __set_bit(EV_ABS, input->evbit); > > > > input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); > > - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); > > - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); > > - input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); > > + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); > > + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); > > + input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); > > input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, > > - 4, 0); > > + 0, 0); > > /* Note: Touch Y position from the device is inverted relative > > * to how pointer motion is reported (and relative to how USB > > * HID recommends the coordinates work). This driver keeps > > @@ -369,7 +369,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > > * inverse of the reported Y. > > */ > > input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, > > - 4, 0); > > + 0, 0); > > } > > > > if (report_undeciphered) { ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 20:58 ` Chase Douglas @ 2010-08-31 21:06 ` Henrik Rydberg 2010-08-31 21:16 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 21:06 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 10:58 PM, Chase Douglas wrote: > On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: >> On 08/31/2010 08:41 PM, Chase Douglas wrote: >> >>> The Magic Mouse device is very precise. No driver filtering of input >>> data needs to be performed. >>> >>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> >>> Acked-by: Michael Poole <mdpoole@troilus.org> >>> --- >> >> >> I am still not sure this is a good idea. Bandwidth from MT devices is a big >> deal. A statement roughly how much data comes out of mtdev (which does the >> filtering for type A devices) before and after this change would be reassuring. > > As it is right now, hid-magicmouse doesn't support MT slots. I think all > the fuzz code ends up comparing in the MT case is between one touch and > another touch, not between one touch's current location and its previous > location. If I'm correct, then it means a fuzz > 0 is incorrect for > non-slotted MT devices. > > In fact, the code in drivers/input/input.c around line 194 looks like it > discards defuzzing in this case, so one could say this patch is making > things more correct :). For type A devices, the filtering is performed in userspace, in mtdev, in the same manner as it would have been performed in the kernel in the MT slot case. Therefore, knowing the amount of messages coming out of mtdev is a direct measurement of the effect of filtering. > Now a fuzz > 0 for the non-MT ABS axes may be useful, but this device > exhibits no jitter, and we're not really worried about bandwidth in the > single touch case. The jitter is better measured by the actual amount of events. Henrik ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:06 ` Henrik Rydberg @ 2010-08-31 21:16 ` Chase Douglas 2010-08-31 21:18 ` Henrik Rydberg 0 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 21:16 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: > On 08/31/2010 10:58 PM, Chase Douglas wrote: > > > On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > >> On 08/31/2010 08:41 PM, Chase Douglas wrote: > >> > >>> The Magic Mouse device is very precise. No driver filtering of input > >>> data needs to be performed. > >>> > >>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > >>> Acked-by: Michael Poole <mdpoole@troilus.org> > >>> --- > >> > >> > >> I am still not sure this is a good idea. Bandwidth from MT devices is a big > >> deal. A statement roughly how much data comes out of mtdev (which does the > >> filtering for type A devices) before and after this change would be reassuring. > > > > As it is right now, hid-magicmouse doesn't support MT slots. I think all > > the fuzz code ends up comparing in the MT case is between one touch and > > another touch, not between one touch's current location and its previous > > location. If I'm correct, then it means a fuzz > 0 is incorrect for > > non-slotted MT devices. > > > > In fact, the code in drivers/input/input.c around line 194 looks like it > > discards defuzzing in this case, so one could say this patch is making > > things more correct :). > > > For type A devices, the filtering is performed in userspace, in mtdev, in the > same manner as it would have been performed in the kernel in the MT slot case. > Therefore, knowing the amount of messages coming out of mtdev is a direct > measurement of the effect of filtering. Yes, but we're only interested in the kernel driver when reviewing this patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* axes. On the other axes, such as the touch orientation, it's probably more harmful than good. > > Now a fuzz > 0 for the non-MT ABS axes may be useful, but this device > > exhibits no jitter, and we're not really worried about bandwidth in the > > single touch case. > > > The jitter is better measured by the actual amount of events. I would agree, if there was any jitter to measure. However, I can hold my fingers on the device and not see any extra events due to jitter. Simple inspection via evtest has convinced me. -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:16 ` Chase Douglas @ 2010-08-31 21:18 ` Henrik Rydberg 2010-08-31 21:27 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 21:18 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 11:16 PM, Chase Douglas wrote: > On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: >> On 08/31/2010 10:58 PM, Chase Douglas wrote: >> >>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: >>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: >>>> >>>>> The Magic Mouse device is very precise. No driver filtering of input >>>>> data needs to be performed. >>>>> >>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> >>>>> Acked-by: Michael Poole <mdpoole@troilus.org> >>>>> --- >>>> >>>> >>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big >>>> deal. A statement roughly how much data comes out of mtdev (which does the >>>> filtering for type A devices) before and after this change would be reassuring. >>> >>> As it is right now, hid-magicmouse doesn't support MT slots. I think all >>> the fuzz code ends up comparing in the MT case is between one touch and >>> another touch, not between one touch's current location and its previous >>> location. If I'm correct, then it means a fuzz > 0 is incorrect for >>> non-slotted MT devices. >>> >>> In fact, the code in drivers/input/input.c around line 194 looks like it >>> discards defuzzing in this case, so one could say this patch is making >>> things more correct :). >> >> >> For type A devices, the filtering is performed in userspace, in mtdev, in the >> same manner as it would have been performed in the kernel in the MT slot case. >> Therefore, knowing the amount of messages coming out of mtdev is a direct >> measurement of the effect of filtering. > > Yes, but we're only interested in the kernel driver when reviewing this > patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* > axes. On the other axes, such as the touch orientation, it's probably > more harmful than good. "We" are interested in knowing if this patch makes any sense, given that filtering is in actuality performed in userspace, and thus modifying this code changes the stream rate into userspace applications, thank you. Henrik ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:18 ` Henrik Rydberg @ 2010-08-31 21:27 ` Chase Douglas 2010-08-31 21:39 ` Henrik Rydberg 0 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 21:27 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: > On 08/31/2010 11:16 PM, Chase Douglas wrote: > > > On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: > >> On 08/31/2010 10:58 PM, Chase Douglas wrote: > >> > >>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > >>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: > >>>> > >>>>> The Magic Mouse device is very precise. No driver filtering of input > >>>>> data needs to be performed. > >>>>> > >>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > >>>>> Acked-by: Michael Poole <mdpoole@troilus.org> > >>>>> --- > >>>> > >>>> > >>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big > >>>> deal. A statement roughly how much data comes out of mtdev (which does the > >>>> filtering for type A devices) before and after this change would be reassuring. > >>> > >>> As it is right now, hid-magicmouse doesn't support MT slots. I think all > >>> the fuzz code ends up comparing in the MT case is between one touch and > >>> another touch, not between one touch's current location and its previous > >>> location. If I'm correct, then it means a fuzz > 0 is incorrect for > >>> non-slotted MT devices. > >>> > >>> In fact, the code in drivers/input/input.c around line 194 looks like it > >>> discards defuzzing in this case, so one could say this patch is making > >>> things more correct :). > >> > >> > >> For type A devices, the filtering is performed in userspace, in mtdev, in the > >> same manner as it would have been performed in the kernel in the MT slot case. > >> Therefore, knowing the amount of messages coming out of mtdev is a direct > >> measurement of the effect of filtering. > > > > Yes, but we're only interested in the kernel driver when reviewing this > > patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* > > axes. On the other axes, such as the touch orientation, it's probably > > more harmful than good. > > > "We" are interested in knowing if this patch makes any sense, given that > filtering is in actuality performed in userspace, and thus modifying this code > changes the stream rate into userspace applications, thank you. Because in-kernel defuzzing is turned off for ABS_MT_* axes on non-slotted MT devices, there will be no change in the number of events sent to the userspace due to this patch. Maybe I'm missing something more fundamental. In which case, I'll need more details to get it through my dense skull :). -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:27 ` Chase Douglas @ 2010-08-31 21:39 ` Henrik Rydberg 2010-08-31 21:51 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 21:39 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 11:27 PM, Chase Douglas wrote: > On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: >> On 08/31/2010 11:16 PM, Chase Douglas wrote: >> >>> On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: >>>> On 08/31/2010 10:58 PM, Chase Douglas wrote: >>>> >>>>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: >>>>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: >>>>>> >>>>>>> The Magic Mouse device is very precise. No driver filtering of input >>>>>>> data needs to be performed. >>>>>>> >>>>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> >>>>>>> Acked-by: Michael Poole <mdpoole@troilus.org> >>>>>>> --- >>>>>> >>>>>> >>>>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big >>>>>> deal. A statement roughly how much data comes out of mtdev (which does the >>>>>> filtering for type A devices) before and after this change would be reassuring. >>>>> >>>>> As it is right now, hid-magicmouse doesn't support MT slots. I think all >>>>> the fuzz code ends up comparing in the MT case is between one touch and >>>>> another touch, not between one touch's current location and its previous >>>>> location. If I'm correct, then it means a fuzz > 0 is incorrect for >>>>> non-slotted MT devices. >>>>> >>>>> In fact, the code in drivers/input/input.c around line 194 looks like it >>>>> discards defuzzing in this case, so one could say this patch is making >>>>> things more correct :). >>>> >>>> >>>> For type A devices, the filtering is performed in userspace, in mtdev, in the >>>> same manner as it would have been performed in the kernel in the MT slot case. >>>> Therefore, knowing the amount of messages coming out of mtdev is a direct >>>> measurement of the effect of filtering. >>> >>> Yes, but we're only interested in the kernel driver when reviewing this >>> patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* >>> axes. On the other axes, such as the touch orientation, it's probably >>> more harmful than good. >> >> >> "We" are interested in knowing if this patch makes any sense, given that >> filtering is in actuality performed in userspace, and thus modifying this code >> changes the stream rate into userspace applications, thank you. > > Because in-kernel defuzzing is turned off for ABS_MT_* axes on > non-slotted MT devices, there will be no change in the number of events > sent to the userspace due to this patch. > > Maybe I'm missing something more fundamental. In which case, I'll need > more details to get it through my dense skull :). All events passes through to mtdev, yes, but mtdev filters a considerable amount of events from passing through to X drivers like evdev. Thus, the fuzz values reported in the kernel driver impacts the performance in userspace, even if filtering is not done in the kernel. Henrik ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:39 ` Henrik Rydberg @ 2010-08-31 21:51 ` Chase Douglas 2010-08-31 21:56 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 21:51 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 23:39 +0200, Henrik Rydberg wrote: > On 08/31/2010 11:27 PM, Chase Douglas wrote: > > > On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: > >> On 08/31/2010 11:16 PM, Chase Douglas wrote: > >> > >>> On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: > >>>> On 08/31/2010 10:58 PM, Chase Douglas wrote: > >>>> > >>>>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > >>>>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: > >>>>>> > >>>>>>> The Magic Mouse device is very precise. No driver filtering of input > >>>>>>> data needs to be performed. > >>>>>>> > >>>>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > >>>>>>> Acked-by: Michael Poole <mdpoole@troilus.org> > >>>>>>> --- > >>>>>> > >>>>>> > >>>>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big > >>>>>> deal. A statement roughly how much data comes out of mtdev (which does the > >>>>>> filtering for type A devices) before and after this change would be reassuring. > >>>>> > >>>>> As it is right now, hid-magicmouse doesn't support MT slots. I think all > >>>>> the fuzz code ends up comparing in the MT case is between one touch and > >>>>> another touch, not between one touch's current location and its previous > >>>>> location. If I'm correct, then it means a fuzz > 0 is incorrect for > >>>>> non-slotted MT devices. > >>>>> > >>>>> In fact, the code in drivers/input/input.c around line 194 looks like it > >>>>> discards defuzzing in this case, so one could say this patch is making > >>>>> things more correct :). > >>>> > >>>> > >>>> For type A devices, the filtering is performed in userspace, in mtdev, in the > >>>> same manner as it would have been performed in the kernel in the MT slot case. > >>>> Therefore, knowing the amount of messages coming out of mtdev is a direct > >>>> measurement of the effect of filtering. > >>> > >>> Yes, but we're only interested in the kernel driver when reviewing this > >>> patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* > >>> axes. On the other axes, such as the touch orientation, it's probably > >>> more harmful than good. > >> > >> > >> "We" are interested in knowing if this patch makes any sense, given that > >> filtering is in actuality performed in userspace, and thus modifying this code > >> changes the stream rate into userspace applications, thank you. > > > > Because in-kernel defuzzing is turned off for ABS_MT_* axes on > > non-slotted MT devices, there will be no change in the number of events > > sent to the userspace due to this patch. > > > > Maybe I'm missing something more fundamental. In which case, I'll need > > more details to get it through my dense skull :). > > > All events passes through to mtdev, yes, but mtdev filters a considerable amount > of events from passing through to X drivers like evdev. Thus, the fuzz values > reported in the kernel driver impacts the performance in userspace, even if > filtering is not done in the kernel. My disconnect was that I didn't understand that the fuzz value in the kernel is exported to userspace. I thought the defuzzing in mtdev was independent of the defuzzing in the kernel. Basically, I don't feel I have the time to do the analysis you want right now. If you really want, I can just remove this change. -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:51 ` Chase Douglas @ 2010-08-31 21:56 ` Chase Douglas 2010-08-31 22:05 ` Henrik Rydberg 0 siblings, 1 reply; 22+ messages in thread From: Chase Douglas @ 2010-08-31 21:56 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 17:51 -0400, Chase Douglas wrote: > On Tue, 2010-08-31 at 23:39 +0200, Henrik Rydberg wrote: > > On 08/31/2010 11:27 PM, Chase Douglas wrote: > > > > > On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: > > >> On 08/31/2010 11:16 PM, Chase Douglas wrote: > > >> > > >>> On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: > > >>>> On 08/31/2010 10:58 PM, Chase Douglas wrote: > > >>>> > > >>>>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > > >>>>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: > > >>>>>> > > >>>>>>> The Magic Mouse device is very precise. No driver filtering of input > > >>>>>>> data needs to be performed. > > >>>>>>> > > >>>>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > > >>>>>>> Acked-by: Michael Poole <mdpoole@troilus.org> > > >>>>>>> --- > > >>>>>> > > >>>>>> > > >>>>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big > > >>>>>> deal. A statement roughly how much data comes out of mtdev (which does the > > >>>>>> filtering for type A devices) before and after this change would be reassuring. > > >>>>> > > >>>>> As it is right now, hid-magicmouse doesn't support MT slots. I think all > > >>>>> the fuzz code ends up comparing in the MT case is between one touch and > > >>>>> another touch, not between one touch's current location and its previous > > >>>>> location. If I'm correct, then it means a fuzz > 0 is incorrect for > > >>>>> non-slotted MT devices. > > >>>>> > > >>>>> In fact, the code in drivers/input/input.c around line 194 looks like it > > >>>>> discards defuzzing in this case, so one could say this patch is making > > >>>>> things more correct :). > > >>>> > > >>>> > > >>>> For type A devices, the filtering is performed in userspace, in mtdev, in the > > >>>> same manner as it would have been performed in the kernel in the MT slot case. > > >>>> Therefore, knowing the amount of messages coming out of mtdev is a direct > > >>>> measurement of the effect of filtering. > > >>> > > >>> Yes, but we're only interested in the kernel driver when reviewing this > > >>> patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* > > >>> axes. On the other axes, such as the touch orientation, it's probably > > >>> more harmful than good. > > >> > > >> > > >> "We" are interested in knowing if this patch makes any sense, given that > > >> filtering is in actuality performed in userspace, and thus modifying this code > > >> changes the stream rate into userspace applications, thank you. > > > > > > Because in-kernel defuzzing is turned off for ABS_MT_* axes on > > > non-slotted MT devices, there will be no change in the number of events > > > sent to the userspace due to this patch. > > > > > > Maybe I'm missing something more fundamental. In which case, I'll need > > > more details to get it through my dense skull :). > > > > > > All events passes through to mtdev, yes, but mtdev filters a considerable amount > > of events from passing through to X drivers like evdev. Thus, the fuzz values > > reported in the kernel driver impacts the performance in userspace, even if > > filtering is not done in the kernel. > > My disconnect was that I didn't understand that the fuzz value in the > kernel is exported to userspace. I thought the defuzzing in mtdev was > independent of the defuzzing in the kernel. > > Basically, I don't feel I have the time to do the analysis you want > right now. If you really want, I can just remove this change. On second thought, if there's no jitter from the device, the only reason to filter is to save bandwidth. The magicmouse devices are very verbose strictly because they have a higher resolution than most devices. If that's an issue for userspace, then the filtering should be based on the resolution. In fact, I see that's what you do in mtdev when the in-kernel fuzz is 0. This separates the kernel fuzz into a removal of jitter, and the mtdev fuzz into a dampening of the number of events passed to clients. Since magicmouse devices have no discernable jitter, shouldn't we set the in-kernel fuzz to 0 and let mtdev do its thing as appropriate? -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 21:56 ` Chase Douglas @ 2010-08-31 22:05 ` Henrik Rydberg 2010-08-31 22:29 ` Chase Douglas 0 siblings, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 22:05 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 11:56 PM, Chase Douglas wrote: > On Tue, 2010-08-31 at 17:51 -0400, Chase Douglas wrote: >> On Tue, 2010-08-31 at 23:39 +0200, Henrik Rydberg wrote: >>> On 08/31/2010 11:27 PM, Chase Douglas wrote: >>> >>>> On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: >>>>> On 08/31/2010 11:16 PM, Chase Douglas wrote: >>>>> >>>>>> On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: >>>>>>> On 08/31/2010 10:58 PM, Chase Douglas wrote: >>>>>>> >>>>>>>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: >>>>>>>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: >>>>>>>>> >>>>>>>>>> The Magic Mouse device is very precise. No driver filtering of input >>>>>>>>>> data needs to be performed. >>>>>>>>>> >>>>>>>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> >>>>>>>>>> Acked-by: Michael Poole <mdpoole@troilus.org> >>>>>>>>>> --- >>>>>>>>> >>>>>>>>> >>>>>>>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big >>>>>>>>> deal. A statement roughly how much data comes out of mtdev (which does the >>>>>>>>> filtering for type A devices) before and after this change would be reassuring. >>>>>>>> >>>>>>>> As it is right now, hid-magicmouse doesn't support MT slots. I think all >>>>>>>> the fuzz code ends up comparing in the MT case is between one touch and >>>>>>>> another touch, not between one touch's current location and its previous >>>>>>>> location. If I'm correct, then it means a fuzz > 0 is incorrect for >>>>>>>> non-slotted MT devices. >>>>>>>> >>>>>>>> In fact, the code in drivers/input/input.c around line 194 looks like it >>>>>>>> discards defuzzing in this case, so one could say this patch is making >>>>>>>> things more correct :). >>>>>>> >>>>>>> >>>>>>> For type A devices, the filtering is performed in userspace, in mtdev, in the >>>>>>> same manner as it would have been performed in the kernel in the MT slot case. >>>>>>> Therefore, knowing the amount of messages coming out of mtdev is a direct >>>>>>> measurement of the effect of filtering. >>>>>> >>>>>> Yes, but we're only interested in the kernel driver when reviewing this >>>>>> patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* >>>>>> axes. On the other axes, such as the touch orientation, it's probably >>>>>> more harmful than good. >>>>> >>>>> >>>>> "We" are interested in knowing if this patch makes any sense, given that >>>>> filtering is in actuality performed in userspace, and thus modifying this code >>>>> changes the stream rate into userspace applications, thank you. >>>> >>>> Because in-kernel defuzzing is turned off for ABS_MT_* axes on >>>> non-slotted MT devices, there will be no change in the number of events >>>> sent to the userspace due to this patch. >>>> >>>> Maybe I'm missing something more fundamental. In which case, I'll need >>>> more details to get it through my dense skull :). >>> >>> >>> All events passes through to mtdev, yes, but mtdev filters a considerable amount >>> of events from passing through to X drivers like evdev. Thus, the fuzz values >>> reported in the kernel driver impacts the performance in userspace, even if >>> filtering is not done in the kernel. >> >> My disconnect was that I didn't understand that the fuzz value in the >> kernel is exported to userspace. I thought the defuzzing in mtdev was >> independent of the defuzzing in the kernel. >> >> Basically, I don't feel I have the time to do the analysis you want >> right now. If you really want, I can just remove this change. > > On second thought, if there's no jitter from the device, the only reason > to filter is to save bandwidth. The magicmouse devices are very verbose > strictly because they have a higher resolution than most devices. If > that's an issue for userspace, then the filtering should be based on the > resolution. In fact, I see that's what you do in mtdev when the > in-kernel fuzz is 0. > > This separates the kernel fuzz into a removal of jitter, and the mtdev > fuzz into a dampening of the number of events passed to clients. Since > magicmouse devices have no discernable jitter, shouldn't we set the > in-kernel fuzz to 0 and let mtdev do its thing as appropriate? Per-driver data is more precise than a generic value for all devices. This thread has documented the details of why there is an interest in the fuzz values. Skipping the patch until MT slots are implemented or measurements can be done might be the most sensible thing to do. Thanks, Henrik ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering 2010-08-31 22:05 ` Henrik Rydberg @ 2010-08-31 22:29 ` Chase Douglas 0 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 22:29 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Wed, 2010-09-01 at 00:05 +0200, Henrik Rydberg wrote: > On 08/31/2010 11:56 PM, Chase Douglas wrote: > > > On Tue, 2010-08-31 at 17:51 -0400, Chase Douglas wrote: > >> On Tue, 2010-08-31 at 23:39 +0200, Henrik Rydberg wrote: > >>> On 08/31/2010 11:27 PM, Chase Douglas wrote: > >>> > >>>> On Tue, 2010-08-31 at 23:18 +0200, Henrik Rydberg wrote: > >>>>> On 08/31/2010 11:16 PM, Chase Douglas wrote: > >>>>> > >>>>>> On Tue, 2010-08-31 at 23:06 +0200, Henrik Rydberg wrote: > >>>>>>> On 08/31/2010 10:58 PM, Chase Douglas wrote: > >>>>>>> > >>>>>>>> On Tue, 2010-08-31 at 22:34 +0200, Henrik Rydberg wrote: > >>>>>>>>> On 08/31/2010 08:41 PM, Chase Douglas wrote: > >>>>>>>>> > >>>>>>>>>> The Magic Mouse device is very precise. No driver filtering of input > >>>>>>>>>> data needs to be performed. > >>>>>>>>>> > >>>>>>>>>> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > >>>>>>>>>> Acked-by: Michael Poole <mdpoole@troilus.org> > >>>>>>>>>> --- > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I am still not sure this is a good idea. Bandwidth from MT devices is a big > >>>>>>>>> deal. A statement roughly how much data comes out of mtdev (which does the > >>>>>>>>> filtering for type A devices) before and after this change would be reassuring. > >>>>>>>> > >>>>>>>> As it is right now, hid-magicmouse doesn't support MT slots. I think all > >>>>>>>> the fuzz code ends up comparing in the MT case is between one touch and > >>>>>>>> another touch, not between one touch's current location and its previous > >>>>>>>> location. If I'm correct, then it means a fuzz > 0 is incorrect for > >>>>>>>> non-slotted MT devices. > >>>>>>>> > >>>>>>>> In fact, the code in drivers/input/input.c around line 194 looks like it > >>>>>>>> discards defuzzing in this case, so one could say this patch is making > >>>>>>>> things more correct :). > >>>>>>> > >>>>>>> > >>>>>>> For type A devices, the filtering is performed in userspace, in mtdev, in the > >>>>>>> same manner as it would have been performed in the kernel in the MT slot case. > >>>>>>> Therefore, knowing the amount of messages coming out of mtdev is a direct > >>>>>>> measurement of the effect of filtering. > >>>>>> > >>>>>> Yes, but we're only interested in the kernel driver when reviewing this > >>>>>> patch. Leaving the fuzz in as it is has no effect right now on ABS_MT_* > >>>>>> axes. On the other axes, such as the touch orientation, it's probably > >>>>>> more harmful than good. > >>>>> > >>>>> > >>>>> "We" are interested in knowing if this patch makes any sense, given that > >>>>> filtering is in actuality performed in userspace, and thus modifying this code > >>>>> changes the stream rate into userspace applications, thank you. > >>>> > >>>> Because in-kernel defuzzing is turned off for ABS_MT_* axes on > >>>> non-slotted MT devices, there will be no change in the number of events > >>>> sent to the userspace due to this patch. > >>>> > >>>> Maybe I'm missing something more fundamental. In which case, I'll need > >>>> more details to get it through my dense skull :). > >>> > >>> > >>> All events passes through to mtdev, yes, but mtdev filters a considerable amount > >>> of events from passing through to X drivers like evdev. Thus, the fuzz values > >>> reported in the kernel driver impacts the performance in userspace, even if > >>> filtering is not done in the kernel. > >> > >> My disconnect was that I didn't understand that the fuzz value in the > >> kernel is exported to userspace. I thought the defuzzing in mtdev was > >> independent of the defuzzing in the kernel. > >> > >> Basically, I don't feel I have the time to do the analysis you want > >> right now. If you really want, I can just remove this change. > > > > On second thought, if there's no jitter from the device, the only reason > > to filter is to save bandwidth. The magicmouse devices are very verbose > > strictly because they have a higher resolution than most devices. If > > that's an issue for userspace, then the filtering should be based on the > > resolution. In fact, I see that's what you do in mtdev when the > > in-kernel fuzz is 0. > > > > This separates the kernel fuzz into a removal of jitter, and the mtdev > > fuzz into a dampening of the number of events passed to clients. Since > > magicmouse devices have no discernable jitter, shouldn't we set the > > in-kernel fuzz to 0 and let mtdev do its thing as appropriate? > > > Per-driver data is more precise than a generic value for all devices. This > thread has documented the details of why there is an interest in the fuzz > values. Skipping the patch until MT slots are implemented or measurements can be > done might be the most sensible thing to do. Yes, there's still per-driver fuzz data. If a device is jittery it makes sense to set the in-kernel fuzz factor to a reasonable value. If a device is not jittery, I don't see a need to do any defuzzing of the values in the driver itself. If we think it's necessary to reduce bandwidth, then the kernel should be defuzzing uniformly across devices to compensate. mtdev could do this defuzzing for bandwidth uniformly too. As it is, this driver just has an arbitrary value that is not used in the kernel and likely hasn't ever been used anywhere outside of mtdev. I think it makes sense to reset the fuzz to the baseline of 0 and fix it later if we find it's necessary. Otherwise we're just codifying an arbitrary value. -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas ` (2 preceding siblings ...) 2010-08-31 18:41 ` [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering Chase Douglas @ 2010-08-31 18:41 ` Chase Douglas 2010-08-31 22:00 ` Henrik Rydberg 2010-09-01 0:08 ` Michael Poole 2010-08-31 18:41 ` [PATCH 6/6 v2] HID: magicmouse: Adjust major / minor axes to scale Chase Douglas 2010-08-31 23:45 ` [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Michael Poole 5 siblings, 2 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel The trackpad speaks a similar, but different, protocol from the magic mouse. However, only small code tweaks here and there are needed to make basic multitouch work. Extra logic is required for single-touch emulation of the touchpad. The changes made here take the approach that only one finger may emulate the single pointer when multiple fingers have touched the screen. Once that finger is raised, all touches must be raised before any further single touch events can be sent. Sometimes the magic trackpad sends two distinct touch reports as one big report. Simply splitting the packet in two and resending them through magicmouse_raw_event ensures they are handled properly. I also added myself to the copyright statement. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-magicmouse.c | 229 ++++++++++++++++++++++++++++++++---------- 3 files changed, 176 insertions(+), 55 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 616bddc..5226fd1 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[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, { 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 7b3ca1d..9204cac 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -63,6 +63,7 @@ #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d +#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0fe2464..364556a 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -2,6 +2,7 @@ * Apple "Magic" Wireless Mouse driver * * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> + * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com> */ /* @@ -53,7 +54,9 @@ static bool report_undeciphered; module_param(report_undeciphered, bool, 0644); MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); -#define TOUCH_REPORT_ID 0x29 +#define TRACKPAD_REPORT_ID 0x28 +#define MOUSE_REPORT_ID 0x29 +#define DOUBLE_REPORT_ID 0xf7 /* These definitions are not precise, but they're close enough. (Bits * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem * to be some kind of bit mask -- 0x20 may be a near-field reading, @@ -101,6 +104,7 @@ struct magicmouse_sc { u8 down; } touches[16]; int tracking_ids[16]; + int single_touch_id; }; static int magicmouse_firm_touch(struct magicmouse_sc *msc) @@ -166,15 +170,29 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) { struct input_dev *input = msc->input; - int id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; - int x = (tdata[1] << 28 | tdata[0] << 20) >> 20; - int y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); - int size = tdata[5] & 0x3f; - int orientation = (tdata[6] >> 2) - 32; - int touch_major = tdata[3]; - int touch_minor = tdata[4]; - int state = tdata[7] & TOUCH_STATE_MASK; - int down = state != TOUCH_STATE_NONE; + int id, x, y, size, orientation, touch_major, touch_minor, state, down; + + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { + id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; + x = (tdata[1] << 28 | tdata[0] << 20) >> 20; + y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); + size = tdata[5] & 0x3f; + orientation = (tdata[6] >> 2) - 32; + touch_major = tdata[3]; + touch_minor = tdata[4]; + state = tdata[7] & TOUCH_STATE_MASK; + down = state != TOUCH_STATE_NONE; + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; + x = (tdata[1] << 27 | tdata[0] << 19) >> 19; + y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); + size = tdata[6] & 0x3f; + orientation = (tdata[7] >> 2) - 32; + touch_major = tdata[4]; + touch_minor = tdata[5]; + state = tdata[8] & TOUCH_STATE_MASK; + down = state != TOUCH_STATE_NONE; + } /* Store tracking ID and other fields. */ msc->tracking_ids[raw_id] = id; @@ -225,10 +243,15 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda } } - /* Generate the input events for this touch. */ - if (report_touches && down) { + if (down) { msc->touches[id].down = 1; + if (msc->single_touch_id == -1) + msc->single_touch_id = id; + } else if (msc->single_touch_id == id) + msc->single_touch_id = -2; + /* Generate the input events for this touch. */ + if (report_touches && down) { input_report_abs(input, ABS_MT_TRACKING_ID, id); input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); @@ -236,8 +259,12 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); - if (report_undeciphered) - input_event(input, EV_MSC, MSC_RAW, tdata[7]); + if (report_undeciphered) { + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) + input_event(input, EV_MSC, MSC_RAW, tdata[7]); + else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + input_event(input, EV_MSC, MSC_RAW, tdata[8]); + } input_mt_sync(input); } @@ -248,7 +275,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, { struct magicmouse_sc *msc = hid_get_drvdata(hdev); struct input_dev *input = msc->input; - int x, y, ts, ii, clicks, last_up; + int x = 0, y = 0, ts, ii, clicks = 0, last_up; switch (data[0]) { case 0x10: @@ -258,7 +285,19 @@ static int magicmouse_raw_event(struct hid_device *hdev, y = (__s16)(data[4] | data[5] << 8); clicks = data[1]; break; - case TOUCH_REPORT_ID: + case TRACKPAD_REPORT_ID: + /* Expect four bytes of prefix, and N*9 bytes of touch data. */ + if (size < 4 || ((size - 4) % 9) != 0) + return 0; + ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; + msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; + msc->last_timestamp = ts; + msc->ntouches = (size - 4) / 9; + for (ii = 0; ii < msc->ntouches; ii++) + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); + clicks = data[1]; + break; + case MOUSE_REPORT_ID: /* Expect six bytes of prefix, and N*8 bytes of touch data. */ if (size < 6 || ((size - 6) % 8) != 0) return 0; @@ -269,19 +308,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, for (ii = 0; ii < msc->ntouches; ii++) magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); - if (report_touches) { - last_up = 1; - for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { - if (msc->touches[ii].down) { - last_up = 0; - msc->touches[ii].down = 0; - } - } - if (last_up) { - input_mt_sync(input); - } - } - /* When emulating three-button mode, it is important * to have the current touch information before * generating a click event. @@ -290,6 +316,14 @@ static int magicmouse_raw_event(struct hid_device *hdev, y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; clicks = data[3]; break; + case DOUBLE_REPORT_ID: + /* Sometimes the trackpad sends two touch reports in one + * packet. + */ + magicmouse_raw_event(hdev, report, data + 2, data[1]); + magicmouse_raw_event(hdev, report, data + 2 + data[1], + size - 2 - data[1]); + break; case 0x20: /* Theoretically battery status (0-100), but I have * never seen it -- maybe it is only upon request. */ @@ -301,9 +335,41 @@ static int magicmouse_raw_event(struct hid_device *hdev, return 0; } - magicmouse_emit_buttons(msc, clicks & 3); - input_report_rel(input, REL_X, x); - input_report_rel(input, REL_Y, y); + if ((data[0] == MOUSE_REPORT_ID || data[0] == TRACKPAD_REPORT_ID)) { + last_up = 1; + for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { + if (msc->touches[ii].down) { + last_up = 0; + msc->touches[ii].down = 0; + } + } + if (last_up) { + msc->single_touch_id = -1; + msc->ntouches = 0; + if (report_touches) + input_mt_sync(input); + } + } + + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { + magicmouse_emit_buttons(msc, clicks & 3); + input_report_rel(input, REL_X, x); + input_report_rel(input, REL_Y, y); + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + input_report_key(input, BTN_MOUSE, clicks & 1); + input_report_key(input, BTN_TOUCH, msc->ntouches > 0); + input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); + input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); + input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); + input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); + if (msc->single_touch_id >= 0) { + input_report_abs(input, ABS_X, + msc->touches[msc->single_touch_id].x); + input_report_abs(input, ABS_Y, + msc->touches[msc->single_touch_id].y); + } + } + input_sync(input); return 1; } @@ -339,18 +405,27 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h input->dev.parent = hdev->dev.parent; __set_bit(EV_KEY, input->evbit); - __set_bit(BTN_LEFT, input->keybit); - __set_bit(BTN_RIGHT, input->keybit); - if (emulate_3button) - __set_bit(BTN_MIDDLE, input->keybit); - __set_bit(BTN_TOOL_FINGER, input->keybit); - - __set_bit(EV_REL, input->evbit); - __set_bit(REL_X, input->relbit); - __set_bit(REL_Y, input->relbit); - if (emulate_scroll_wheel) { - __set_bit(REL_WHEEL, input->relbit); - __set_bit(REL_HWHEEL, input->relbit); + + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { + __set_bit(BTN_LEFT, input->keybit); + __set_bit(BTN_RIGHT, input->keybit); + if (emulate_3button) + __set_bit(BTN_MIDDLE, input->keybit); + + __set_bit(EV_REL, input->evbit); + __set_bit(REL_X, input->relbit); + __set_bit(REL_Y, input->relbit); + if (emulate_scroll_wheel) { + __set_bit(REL_WHEEL, input->relbit); + __set_bit(REL_HWHEEL, input->relbit); + } + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + __set_bit(BTN_MOUSE, input->keybit); + __set_bit(BTN_TOOL_FINGER, input->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); + __set_bit(BTN_TOOL_QUADTAP, input->keybit); + __set_bit(BTN_TOUCH, input->keybit); } if (report_touches) { @@ -360,16 +435,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, - 0, 0); + /* Note: Touch Y position from the device is inverted relative * to how pointer motion is reported (and relative to how USB * HID recommends the coordinates work). This driver keeps * the origin at the same position, and just uses the additive * inverse of the reported Y. */ - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, - 0, 0); + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { + input_set_abs_params(input, ABS_MT_POSITION_X, -1100, + 1358, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, + 2047, 0, 0); + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + input_set_abs_params(input, ABS_X, -2909, 3167, 0, 0); + input_set_abs_params(input, ABS_Y, -2456, 2565, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_X, -2909, + 3167, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, + 2565, 0, 0); + } } if (report_undeciphered) { @@ -388,12 +473,29 @@ static struct feature mouse_features[] = { { { 0xf8, 0x01, 0x32 }, 3 } }; +static struct feature trackpad_features[] = { + { { 0xf1, 0xdb }, 2 }, + { { 0xf1, 0xdc }, 2 }, + { { 0xf0, 0x00 }, 2 }, + { { 0xf1, 0xdd }, 2 }, + { { 0xf0, 0x02 }, 2 }, + { { 0xf1, 0xc8 }, 2 }, + { { 0xf0, 0x09 }, 2 }, + { { 0xf1, 0xdc }, 2 }, + { { 0xf0, 0x00 }, 2 }, + { { 0xf1, 0xdd }, 2 }, + { { 0xf0, 0x02 }, 2 }, + { { 0xd7, 0x01 }, 2 }, +}; + static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct input_dev *input; struct magicmouse_sc *msc; struct hid_report *report; + struct feature *features; + int features_size; int i; int ret; @@ -408,6 +510,8 @@ static int magicmouse_probe(struct hid_device *hdev, msc->quirks = id->driver_data; hid_set_drvdata(hdev, msc); + msc->single_touch_id = -1; + ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "magicmouse hid parse failed\n"); @@ -428,7 +532,20 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); + if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { + report = hid_register_report(hdev, HID_INPUT_REPORT, + MOUSE_REPORT_ID); + features = mouse_features; + features_size = ARRAY_SIZE(mouse_features); + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ + report = hid_register_report(hdev, HID_INPUT_REPORT, + TRACKPAD_REPORT_ID); + report = hid_register_report(hdev, HID_INPUT_REPORT, + DOUBLE_REPORT_ID); + features = trackpad_features; + features_size = ARRAY_SIZE(trackpad_features); + } + if (!report) { dev_err(&hdev->dev, "unable to register touch report\n"); ret = -ENOMEM; @@ -436,10 +553,10 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; - for (i = 0; i < ARRAY_SIZE(mouse_features); i++) { - ret = hdev->hid_output_raw_report(hdev, mouse_features[i].data, - mouse_features[i].length, HID_FEATURE_REPORT); - if (ret != mouse_features[i].length) { + for (i = 0; i < features_size; i++) { + ret = hdev->hid_output_raw_report(hdev, features[i].data, + features[i].length, HID_FEATURE_REPORT); + if (ret != features[i].length) { dev_err(&hdev->dev, "unable to request touch data (%d:%d)\n", i, ret); @@ -482,8 +599,10 @@ static void magicmouse_remove(struct hid_device *hdev) } static const struct hid_device_id magic_mice[] = { - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), - .driver_data = 0 }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 }, { } }; MODULE_DEVICE_TABLE(hid, magic_mice); -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support 2010-08-31 18:41 ` [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support Chase Douglas @ 2010-08-31 22:00 ` Henrik Rydberg 2010-09-01 1:26 ` Chase Douglas 2010-09-01 0:08 ` Michael Poole 1 sibling, 1 reply; 22+ messages in thread From: Henrik Rydberg @ 2010-08-31 22:00 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On 08/31/2010 08:41 PM, Chase Douglas wrote: > The trackpad speaks a similar, but different, protocol from the magic > mouse. However, only small code tweaks here and there are needed to make > basic multitouch work. > > Extra logic is required for single-touch emulation of the touchpad. The > changes made here take the approach that only one finger may emulate the > single pointer when multiple fingers have touched the screen. Once that > finger is raised, all touches must be raised before any further single > touch events can be sent. > > Sometimes the magic trackpad sends two distinct touch reports as one big > report. Simply splitting the packet in two and resending them through > magicmouse_raw_event ensures they are handled properly. > > I also added myself to the copyright statement. > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Thanks for this driver. Comments inline. [...] > @@ -166,15 +170,29 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) > static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) > { > struct input_dev *input = msc->input; > - int id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; > - int x = (tdata[1] << 28 | tdata[0] << 20) >> 20; > - int y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); > - int size = tdata[5] & 0x3f; > - int orientation = (tdata[6] >> 2) - 32; > - int touch_major = tdata[3]; > - int touch_minor = tdata[4]; > - int state = tdata[7] & TOUCH_STATE_MASK; > - int down = state != TOUCH_STATE_NONE; > + int id, x, y, size, orientation, touch_major, touch_minor, state, down; > + > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > + id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; > + x = (tdata[1] << 28 | tdata[0] << 20) >> 20; > + y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); > + size = tdata[5] & 0x3f; > + orientation = (tdata[6] >> 2) - 32; > + touch_major = tdata[3]; > + touch_minor = tdata[4]; > + state = tdata[7] & TOUCH_STATE_MASK; > + down = state != TOUCH_STATE_NONE; > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > + id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; > + x = (tdata[1] << 27 | tdata[0] << 19) >> 19; > + y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); > + size = tdata[6] & 0x3f; > + orientation = (tdata[7] >> 2) - 32; > + touch_major = tdata[4]; > + touch_minor = tdata[5]; > + state = tdata[8] & TOUCH_STATE_MASK; > + down = state != TOUCH_STATE_NONE; > + } > > /* Store tracking ID and other fields. */ > msc->tracking_ids[raw_id] = id; > @@ -225,10 +243,15 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda > } > } > > - /* Generate the input events for this touch. */ > - if (report_touches && down) { > + if (down) { > msc->touches[id].down = 1; > + if (msc->single_touch_id == -1) > + msc->single_touch_id = id; > + } else if (msc->single_touch_id == id) > + msc->single_touch_id = -2; The logic using single_touch_id seems complicated. Any chance you could get by with less code here? > + /* Generate the input events for this touch. */ > + if (report_touches && down) { > input_report_abs(input, ABS_MT_TRACKING_ID, id); The tracking id reported by the macpad is not ideal; it works more like a slot that a MT protocol tracking id. Perhaps it is a slot? I would recommend looking at the recent submissions for bamboo touch, 3m-pct and w8001 to see how the tracking id and slots could be handled. > input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); > input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); > @@ -236,8 +259,12 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda > input_report_abs(input, ABS_MT_POSITION_X, x); > input_report_abs(input, ABS_MT_POSITION_Y, y); > > - if (report_undeciphered) > - input_event(input, EV_MSC, MSC_RAW, tdata[7]); > + if (report_undeciphered) { > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) > + input_event(input, EV_MSC, MSC_RAW, tdata[7]); > + else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > + input_event(input, EV_MSC, MSC_RAW, tdata[8]); > + } > > input_mt_sync(input); > } > @@ -248,7 +275,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, > { > struct magicmouse_sc *msc = hid_get_drvdata(hdev); > struct input_dev *input = msc->input; > - int x, y, ts, ii, clicks, last_up; > + int x = 0, y = 0, ts, ii, clicks = 0, last_up; > > switch (data[0]) { > case 0x10: > @@ -258,7 +285,19 @@ static int magicmouse_raw_event(struct hid_device *hdev, > y = (__s16)(data[4] | data[5] << 8); > clicks = data[1]; > break; > - case TOUCH_REPORT_ID: > + case TRACKPAD_REPORT_ID: > + /* Expect four bytes of prefix, and N*9 bytes of touch data. */ > + if (size < 4 || ((size - 4) % 9) != 0) > + return 0; > + ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; > + msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; > + msc->last_timestamp = ts; The delta_time and last_timestamp do not seem to be used anywhere? > + msc->ntouches = (size - 4) / 9; > + for (ii = 0; ii < msc->ntouches; ii++) > + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); > + clicks = data[1]; > + break; > + case MOUSE_REPORT_ID: > /* Expect six bytes of prefix, and N*8 bytes of touch data. */ > if (size < 6 || ((size - 6) % 8) != 0) > return 0; > @@ -269,19 +308,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, > for (ii = 0; ii < msc->ntouches; ii++) > magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); > > - if (report_touches) { > - last_up = 1; > - for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { > - if (msc->touches[ii].down) { > - last_up = 0; > - msc->touches[ii].down = 0; > - } > - } > - if (last_up) { > - input_mt_sync(input); > - } > - } > - > /* When emulating three-button mode, it is important > * to have the current touch information before > * generating a click event. > @@ -290,6 +316,14 @@ static int magicmouse_raw_event(struct hid_device *hdev, > y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; > clicks = data[3]; > break; > + case DOUBLE_REPORT_ID: > + /* Sometimes the trackpad sends two touch reports in one > + * packet. > + */ > + magicmouse_raw_event(hdev, report, data + 2, data[1]); > + magicmouse_raw_event(hdev, report, data + 2 + data[1], > + size - 2 - data[1]); > + break; Nice find. > case 0x20: /* Theoretically battery status (0-100), but I have > * never seen it -- maybe it is only upon request. > */ > @@ -301,9 +335,41 @@ static int magicmouse_raw_event(struct hid_device *hdev, > return 0; > } > > - magicmouse_emit_buttons(msc, clicks & 3); > - input_report_rel(input, REL_X, x); > - input_report_rel(input, REL_Y, y); > + if ((data[0] == MOUSE_REPORT_ID || data[0] == TRACKPAD_REPORT_ID)) { > + last_up = 1; > + for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { > + if (msc->touches[ii].down) { > + last_up = 0; > + msc->touches[ii].down = 0; > + } > + } > + if (last_up) { > + msc->single_touch_id = -1; > + msc->ntouches = 0; > + if (report_touches) > + input_mt_sync(input); > + } If the pointer emulation was handled differently, and the above was replaced with something like if (!msc->ntouches) input_mt_sync(input); it would be short enough not to need to be broken out of the switch... Besides, BTN_TOUCH is emitted for the trackpad case, so the above code is not strictly needed. > + } > + > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > + magicmouse_emit_buttons(msc, clicks & 3); > + input_report_rel(input, REL_X, x); > + input_report_rel(input, REL_Y, y); > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > + input_report_key(input, BTN_MOUSE, clicks & 1); > + input_report_key(input, BTN_TOUCH, msc->ntouches > 0); > + input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); > + input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); > + input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); > + input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); > + if (msc->single_touch_id >= 0) { > + input_report_abs(input, ABS_X, > + msc->touches[msc->single_touch_id].x); > + input_report_abs(input, ABS_Y, > + msc->touches[msc->single_touch_id].y); > + } > + } > + > input_sync(input); > return 1; > } > @@ -339,18 +405,27 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > input->dev.parent = hdev->dev.parent; > > __set_bit(EV_KEY, input->evbit); > - __set_bit(BTN_LEFT, input->keybit); > - __set_bit(BTN_RIGHT, input->keybit); > - if (emulate_3button) > - __set_bit(BTN_MIDDLE, input->keybit); > - __set_bit(BTN_TOOL_FINGER, input->keybit); > - > - __set_bit(EV_REL, input->evbit); > - __set_bit(REL_X, input->relbit); > - __set_bit(REL_Y, input->relbit); > - if (emulate_scroll_wheel) { > - __set_bit(REL_WHEEL, input->relbit); > - __set_bit(REL_HWHEEL, input->relbit); > + > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > + __set_bit(BTN_LEFT, input->keybit); > + __set_bit(BTN_RIGHT, input->keybit); > + if (emulate_3button) > + __set_bit(BTN_MIDDLE, input->keybit); > + > + __set_bit(EV_REL, input->evbit); > + __set_bit(REL_X, input->relbit); > + __set_bit(REL_Y, input->relbit); > + if (emulate_scroll_wheel) { > + __set_bit(REL_WHEEL, input->relbit); > + __set_bit(REL_HWHEEL, input->relbit); > + } > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > + __set_bit(BTN_MOUSE, input->keybit); > + __set_bit(BTN_TOOL_FINGER, input->keybit); > + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); > + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); > + __set_bit(BTN_TOOL_QUADTAP, input->keybit); > + __set_bit(BTN_TOUCH, input->keybit); > } > > if (report_touches) { > @@ -360,16 +435,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); > input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); > input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); > - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, > - 0, 0); > + > /* Note: Touch Y position from the device is inverted relative > * to how pointer motion is reported (and relative to how USB > * HID recommends the coordinates work). This driver keeps > * the origin at the same position, and just uses the additive > * inverse of the reported Y. > */ > - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, > - 0, 0); > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > + input_set_abs_params(input, ABS_MT_POSITION_X, -1100, > + 1358, 0, 0); > + input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, > + 2047, 0, 0); > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > + input_set_abs_params(input, ABS_X, -2909, 3167, 0, 0); > + input_set_abs_params(input, ABS_Y, -2456, 2565, 0, 0); > + input_set_abs_params(input, ABS_MT_POSITION_X, -2909, > + 3167, 0, 0); > + input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, > + 2565, 0, 0); > + } > } > > if (report_undeciphered) { > @@ -388,12 +473,29 @@ static struct feature mouse_features[] = { > { { 0xf8, 0x01, 0x32 }, 3 } > }; > > +static struct feature trackpad_features[] = { > + { { 0xf1, 0xdb }, 2 }, > + { { 0xf1, 0xdc }, 2 }, > + { { 0xf0, 0x00 }, 2 }, > + { { 0xf1, 0xdd }, 2 }, > + { { 0xf0, 0x02 }, 2 }, > + { { 0xf1, 0xc8 }, 2 }, > + { { 0xf0, 0x09 }, 2 }, > + { { 0xf1, 0xdc }, 2 }, > + { { 0xf0, 0x00 }, 2 }, > + { { 0xf1, 0xdd }, 2 }, > + { { 0xf0, 0x02 }, 2 }, > + { { 0xd7, 0x01 }, 2 }, > +}; As noted by Michael, this could likely be simplified. the "0x01" on the last line could be the same coding as wellspring mode for bcm5974. Thanks, Henrik ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support 2010-08-31 22:00 ` Henrik Rydberg @ 2010-09-01 1:26 ` Chase Douglas 0 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-09-01 1:26 UTC (permalink / raw) To: Henrik Rydberg Cc: Jiri Kosina, Michael Poole, Tejun Heo, linux-input, linux-kernel On Wed, 2010-09-01 at 00:00 +0200, Henrik Rydberg wrote: > On 08/31/2010 08:41 PM, Chase Douglas wrote: > > > The trackpad speaks a similar, but different, protocol from the magic > > mouse. However, only small code tweaks here and there are needed to make > > basic multitouch work. > > > > Extra logic is required for single-touch emulation of the touchpad. The > > changes made here take the approach that only one finger may emulate the > > single pointer when multiple fingers have touched the screen. Once that > > finger is raised, all touches must be raised before any further single > > touch events can be sent. > > > > Sometimes the magic trackpad sends two distinct touch reports as one big > > report. Simply splitting the packet in two and resending them through > > magicmouse_raw_event ensures they are handled properly. > > > > I also added myself to the copyright statement. > > > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > > > Thanks for this driver. Comments inline. > > [...] > > > @@ -166,15 +170,29 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) > > static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) > > { > > struct input_dev *input = msc->input; > > - int id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; > > - int x = (tdata[1] << 28 | tdata[0] << 20) >> 20; > > - int y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); > > - int size = tdata[5] & 0x3f; > > - int orientation = (tdata[6] >> 2) - 32; > > - int touch_major = tdata[3]; > > - int touch_minor = tdata[4]; > > - int state = tdata[7] & TOUCH_STATE_MASK; > > - int down = state != TOUCH_STATE_NONE; > > + int id, x, y, size, orientation, touch_major, touch_minor, state, down; > > + > > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > > + id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; > > + x = (tdata[1] << 28 | tdata[0] << 20) >> 20; > > + y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); > > + size = tdata[5] & 0x3f; > > + orientation = (tdata[6] >> 2) - 32; > > + touch_major = tdata[3]; > > + touch_minor = tdata[4]; > > + state = tdata[7] & TOUCH_STATE_MASK; > > + down = state != TOUCH_STATE_NONE; > > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > > + id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; > > + x = (tdata[1] << 27 | tdata[0] << 19) >> 19; > > + y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); > > + size = tdata[6] & 0x3f; > > + orientation = (tdata[7] >> 2) - 32; > > + touch_major = tdata[4]; > > + touch_minor = tdata[5]; > > + state = tdata[8] & TOUCH_STATE_MASK; > > + down = state != TOUCH_STATE_NONE; > > + } > > > > /* Store tracking ID and other fields. */ > > msc->tracking_ids[raw_id] = id; > > @@ -225,10 +243,15 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda > > } > > } > > > > - /* Generate the input events for this touch. */ > > - if (report_touches && down) { > > + if (down) { > > msc->touches[id].down = 1; > > + if (msc->single_touch_id == -1) > > + msc->single_touch_id = id; > > + } else if (msc->single_touch_id == id) > > + msc->single_touch_id = -2; > > > The logic using single_touch_id seems complicated. Any chance you could get by > with less code here? The overall code for single touch handling is ~10 lines spread around the driver. I've tried to condense the code as much as possible. Perhaps someone could come up with something more elegant, but all this code does is keep track of the touch that is tied to single touch emulation. In my next submission I've added macros to make the -1 and -2 values more obvious on inspection. > > + /* Generate the input events for this touch. */ > > + if (report_touches && down) { > > input_report_abs(input, ABS_MT_TRACKING_ID, id); > > > The tracking id reported by the macpad is not ideal; it works more like a slot > that a MT protocol tracking id. Perhaps it is a slot? I would recommend looking > at the recent submissions for bamboo touch, 3m-pct and w8001 to see how the > tracking id and slots could be handled. Yes, I think it could be better handled. However, that handling probably belongs in another patch when slots are implemented in this driver. I just haven't had a chance to get to it yet :). > > input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); > > input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); > > @@ -236,8 +259,12 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda > > input_report_abs(input, ABS_MT_POSITION_X, x); > > input_report_abs(input, ABS_MT_POSITION_Y, y); > > > > - if (report_undeciphered) > > - input_event(input, EV_MSC, MSC_RAW, tdata[7]); > > + if (report_undeciphered) { > > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) > > + input_event(input, EV_MSC, MSC_RAW, tdata[7]); > > + else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > > + input_event(input, EV_MSC, MSC_RAW, tdata[8]); > > + } > > > > input_mt_sync(input); > > } > > @@ -248,7 +275,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > { > > struct magicmouse_sc *msc = hid_get_drvdata(hdev); > > struct input_dev *input = msc->input; > > - int x, y, ts, ii, clicks, last_up; > > + int x = 0, y = 0, ts, ii, clicks = 0, last_up; > > > > switch (data[0]) { > > case 0x10: > > @@ -258,7 +285,19 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > y = (__s16)(data[4] | data[5] << 8); > > clicks = data[1]; > > break; > > - case TOUCH_REPORT_ID: > > + case TRACKPAD_REPORT_ID: > > + /* Expect four bytes of prefix, and N*9 bytes of touch data. */ > > + if (size < 4 || ((size - 4) % 9) != 0) > > + return 0; > > + ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; > > + msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; > > + msc->last_timestamp = ts; > > > The delta_time and last_timestamp do not seem to be used anywhere? Good point. I've removed them in my next submission. > > + msc->ntouches = (size - 4) / 9; > > + for (ii = 0; ii < msc->ntouches; ii++) > > + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); > > + clicks = data[1]; > > + break; > > + case MOUSE_REPORT_ID: > > /* Expect six bytes of prefix, and N*8 bytes of touch data. */ > > if (size < 6 || ((size - 6) % 8) != 0) > > return 0; > > @@ -269,19 +308,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > for (ii = 0; ii < msc->ntouches; ii++) > > magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); > > > > - if (report_touches) { > > - last_up = 1; > > - for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { > > - if (msc->touches[ii].down) { > > - last_up = 0; > > - msc->touches[ii].down = 0; > > - } > > - } > > - if (last_up) { > > - input_mt_sync(input); > > - } > > - } > > - > > /* When emulating three-button mode, it is important > > * to have the current touch information before > > * generating a click event. > > @@ -290,6 +316,14 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; > > clicks = data[3]; > > break; > > + case DOUBLE_REPORT_ID: > > + /* Sometimes the trackpad sends two touch reports in one > > + * packet. > > + */ > > + magicmouse_raw_event(hdev, report, data + 2, data[1]); > > + magicmouse_raw_event(hdev, report, data + 2 + data[1], > > + size - 2 - data[1]); > > + break; > > > Nice find. > > > case 0x20: /* Theoretically battery status (0-100), but I have > > * never seen it -- maybe it is only upon request. > > */ > > @@ -301,9 +335,41 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > return 0; > > } > > > > - magicmouse_emit_buttons(msc, clicks & 3); > > - input_report_rel(input, REL_X, x); > > - input_report_rel(input, REL_Y, y); > > + if ((data[0] == MOUSE_REPORT_ID || data[0] == TRACKPAD_REPORT_ID)) { > > + last_up = 1; > > + for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { > > + if (msc->touches[ii].down) { > > + last_up = 0; > > + msc->touches[ii].down = 0; > > + } > > + } > > + if (last_up) { > > + msc->single_touch_id = -1; > > + msc->ntouches = 0; > > + if (report_touches) > > + input_mt_sync(input); > > + } > > > If the pointer emulation was handled differently, and the above was replaced > with something like > > if (!msc->ntouches) > input_mt_sync(input); > > it would be short enough not to need to be broken out of the switch... Besides, > BTN_TOUCH is emitted for the trackpad case, so the above code is not strictly > needed. I've rewritten the touch down logic, and this does get simple enough to keep inside the switch scope. > > + } > > + > > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > > + magicmouse_emit_buttons(msc, clicks & 3); > > + input_report_rel(input, REL_X, x); > > + input_report_rel(input, REL_Y, y); > > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > > + input_report_key(input, BTN_MOUSE, clicks & 1); > > + input_report_key(input, BTN_TOUCH, msc->ntouches > 0); > > + input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); > > + input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); > > + input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); > > + input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); > > + if (msc->single_touch_id >= 0) { > > + input_report_abs(input, ABS_X, > > + msc->touches[msc->single_touch_id].x); > > + input_report_abs(input, ABS_Y, > > + msc->touches[msc->single_touch_id].y); > > + } > > + } > > + > > input_sync(input); > > return 1; > > } > > @@ -339,18 +405,27 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > > input->dev.parent = hdev->dev.parent; > > > > __set_bit(EV_KEY, input->evbit); > > - __set_bit(BTN_LEFT, input->keybit); > > - __set_bit(BTN_RIGHT, input->keybit); > > - if (emulate_3button) > > - __set_bit(BTN_MIDDLE, input->keybit); > > - __set_bit(BTN_TOOL_FINGER, input->keybit); > > - > > - __set_bit(EV_REL, input->evbit); > > - __set_bit(REL_X, input->relbit); > > - __set_bit(REL_Y, input->relbit); > > - if (emulate_scroll_wheel) { > > - __set_bit(REL_WHEEL, input->relbit); > > - __set_bit(REL_HWHEEL, input->relbit); > > + > > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > > + __set_bit(BTN_LEFT, input->keybit); > > + __set_bit(BTN_RIGHT, input->keybit); > > + if (emulate_3button) > > + __set_bit(BTN_MIDDLE, input->keybit); > > + > > + __set_bit(EV_REL, input->evbit); > > + __set_bit(REL_X, input->relbit); > > + __set_bit(REL_Y, input->relbit); > > + if (emulate_scroll_wheel) { > > + __set_bit(REL_WHEEL, input->relbit); > > + __set_bit(REL_HWHEEL, input->relbit); > > + } > > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > > + __set_bit(BTN_MOUSE, input->keybit); > > + __set_bit(BTN_TOOL_FINGER, input->keybit); > > + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); > > + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); > > + __set_bit(BTN_TOOL_QUADTAP, input->keybit); > > + __set_bit(BTN_TOUCH, input->keybit); > > } > > > > if (report_touches) { > > @@ -360,16 +435,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h > > input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); > > input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); > > input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 0, 0); > > - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, > > - 0, 0); > > + > > /* Note: Touch Y position from the device is inverted relative > > * to how pointer motion is reported (and relative to how USB > > * HID recommends the coordinates work). This driver keeps > > * the origin at the same position, and just uses the additive > > * inverse of the reported Y. > > */ > > - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, > > - 0, 0); > > + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { > > + input_set_abs_params(input, ABS_MT_POSITION_X, -1100, > > + 1358, 0, 0); > > + input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, > > + 2047, 0, 0); > > + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ > > + input_set_abs_params(input, ABS_X, -2909, 3167, 0, 0); > > + input_set_abs_params(input, ABS_Y, -2456, 2565, 0, 0); > > + input_set_abs_params(input, ABS_MT_POSITION_X, -2909, > > + 3167, 0, 0); > > + input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, > > + 2565, 0, 0); > > + } > > } > > > > if (report_undeciphered) { > > @@ -388,12 +473,29 @@ static struct feature mouse_features[] = { > > { { 0xf8, 0x01, 0x32 }, 3 } > > }; > > > > +static struct feature trackpad_features[] = { > > + { { 0xf1, 0xdb }, 2 }, > > + { { 0xf1, 0xdc }, 2 }, > > + { { 0xf0, 0x00 }, 2 }, > > + { { 0xf1, 0xdd }, 2 }, > > + { { 0xf0, 0x02 }, 2 }, > > + { { 0xf1, 0xc8 }, 2 }, > > + { { 0xf0, 0x09 }, 2 }, > > + { { 0xf1, 0xdc }, 2 }, > > + { { 0xf0, 0x00 }, 2 }, > > + { { 0xf1, 0xdd }, 2 }, > > + { { 0xf0, 0x02 }, 2 }, > > + { { 0xd7, 0x01 }, 2 }, > > +}; > > > As noted by Michael, this could likely be simplified. the "0x01" on the last > line could be the same coding as wellspring mode for bcm5974. I've simplified this for the next submission. -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support 2010-08-31 18:41 ` [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support Chase Douglas 2010-08-31 22:00 ` Henrik Rydberg @ 2010-09-01 0:08 ` Michael Poole 2010-09-01 1:55 ` Chase Douglas 1 sibling, 1 reply; 22+ messages in thread From: Michael Poole @ 2010-09-01 0:08 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 14:41 -0400, Chase Douglas wrote: > The trackpad speaks a similar, but different, protocol from the magic > mouse. However, only small code tweaks here and there are needed to make > basic multitouch work. > > Extra logic is required for single-touch emulation of the touchpad. The > changes made here take the approach that only one finger may emulate the > single pointer when multiple fingers have touched the screen. Once that > finger is raised, all touches must be raised before any further single > touch events can be sent. > > Sometimes the magic trackpad sends two distinct touch reports as one big > report. Simply splitting the packet in two and resending them through > magicmouse_raw_event ensures they are handled properly. > > I also added myself to the copyright statement. > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > --- > drivers/hid/hid-core.c | 1 + > drivers/hid/hid-ids.h | 1 + > drivers/hid/hid-magicmouse.c | 229 ++++++++++++++++++++++++++++++++---------- > 3 files changed, 176 insertions(+), 55 deletions(-) Acked-by: Michael Poole <mdpoole@troilus.org> One behavior that slightly surprised me -- which I believe is a quirk due to userspace not expecting touchpads to have button switches -- is that touches on the trackpad that do not close the switch can still be interpreted by X as clicks. Once the discussions about if/how to tweak this code settle down, I'll put together a patch to change the "down" and "last_up" logic as I suggested earlier. Michael Poole ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support 2010-09-01 0:08 ` Michael Poole @ 2010-09-01 1:55 ` Chase Douglas 0 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-09-01 1:55 UTC (permalink / raw) To: Michael Poole Cc: Jiri Kosina, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 20:08 -0400, Michael Poole wrote: > One behavior that slightly surprised me -- which I believe is a quirk > due to userspace not expecting touchpads to have button switches -- is > that touches on the trackpad that do not close the switch can still be > interpreted by X as clicks. This is actually done by the X synaptics input module. It's the defacto X touchpad driver and enables niceties like two finger scrolling and whatnot. You can either use it as is, use xinput/xorg.conf to manipulate its configuration, or switch to the X evdev input module which is more "bare" support. FYI, our gesture support in Maverick is based on a modified version of the X evdev input module. However, because the whole stack of desktop libs and toolkits won't support gestures in Maverick, you lose things like two finger scroll. Thus, we're going to leave the default X input module for the magic trackpad to synaptics in Ubuntu. > Once the discussions about if/how to tweak this code settle down, I'll > put together a patch to change the "down" and "last_up" logic as I > suggested earlier. I actually decided to tackle this to make the patches I'm writing easier. I'll be sending a new batch shortly. Thanks, -- Chase ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 6/6 v2] HID: magicmouse: Adjust major / minor axes to scale 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas ` (3 preceding siblings ...) 2010-08-31 18:41 ` [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support Chase Douglas @ 2010-08-31 18:41 ` Chase Douglas 2010-08-31 23:45 ` [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Michael Poole 5 siblings, 0 replies; 22+ messages in thread From: Chase Douglas @ 2010-08-31 18:41 UTC (permalink / raw) To: Jiri Kosina Cc: Michael Poole, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel From: Henrik Rydberg <rydberg@euromail.se> By visual inspection, the reported touch_major and touch_minor axes are roughly a factor of four too small. The factor is approximate, since the protocol is not known and the HID report encodes touch size with fewer bits than positions. This patch scales the reported values by a factor of four. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Michael Poole <mdpoole@troilus.org> --- drivers/hid/hid-magicmouse.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 364556a..898d0b8 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -253,8 +253,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda /* Generate the input events for this touch. */ if (report_touches && down) { input_report_abs(input, ABS_MT_TRACKING_ID, id); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); - input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); + input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); input_report_abs(input, ABS_MT_ORIENTATION, orientation); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); -- 1.7.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas ` (4 preceding siblings ...) 2010-08-31 18:41 ` [PATCH 6/6 v2] HID: magicmouse: Adjust major / minor axes to scale Chase Douglas @ 2010-08-31 23:45 ` Michael Poole 5 siblings, 0 replies; 22+ messages in thread From: Michael Poole @ 2010-08-31 23:45 UTC (permalink / raw) To: Chase Douglas Cc: Jiri Kosina, Henrik Rydberg, Tejun Heo, linux-input, linux-kernel On Tue, 2010-08-31 at 14:41 -0400, Chase Douglas wrote: > From: Chase Douglas <chase.douglas@ubuntu.com> > > The driver listens only for raw events from the device. If we allow > the hidinput layer to initialize, we can hit NULL pointer dereferences > in the hidinput layer because disconnecting only removes the hidinput > devices from the hid device while leaving the hid fields configured. > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com> > --- > Note that this mimics what the hid-picolcd module does. Thanks, this approach makes sense to me. Acked-by: Michael Poole <mdpoole@troilus.org> > drivers/hid/hid-magicmouse.c | 13 +++++++++---- > 1 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > index 319b0e5..d38b529 100644 > --- a/drivers/hid/hid-magicmouse.c > +++ b/drivers/hid/hid-magicmouse.c > @@ -404,15 +404,20 @@ static int magicmouse_probe(struct hid_device *hdev, > goto err_free; > } > > - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > + /* When registering a hid device, one of hidinput, hidraw, or hiddev > + * subsystems must claim the device. We are bypassing hidinput due to > + * our raw event processing, and hidraw and hiddev may not claim the > + * device. We get around this by telling hid_hw_start that input has > + * claimed the device already, and then flipping the bit back. > + */ > + hdev->claimed = HID_CLAIMED_INPUT; > + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT); > + hdev->claimed &= ~HID_CLAIMED_INPUT; > if (ret) { > dev_err(&hdev->dev, "magicmouse hw start failed\n"); > goto err_free; > } > > - /* we are handling the input ourselves */ > - hidinput_disconnect(hdev); > - > report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); > if (!report) { > dev_err(&hdev->dev, "unable to register touch report\n"); ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2010-09-01 1:55 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-08-31 18:41 [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Chase Douglas 2010-08-31 18:41 ` [PATCH 2/6 v2] HID: magicmouse: move features reports to static array Chase Douglas 2010-08-31 18:41 ` [PATCH 3/6 v2] HID: magicmouse: simplify touch data bit manipulation Chase Douglas 2010-08-31 18:41 ` [PATCH 4/6 v2] HID: magicmouse: remove axis data filtering Chase Douglas 2010-08-31 20:34 ` Henrik Rydberg 2010-08-31 20:58 ` Chase Douglas 2010-08-31 21:06 ` Henrik Rydberg 2010-08-31 21:16 ` Chase Douglas 2010-08-31 21:18 ` Henrik Rydberg 2010-08-31 21:27 ` Chase Douglas 2010-08-31 21:39 ` Henrik Rydberg 2010-08-31 21:51 ` Chase Douglas 2010-08-31 21:56 ` Chase Douglas 2010-08-31 22:05 ` Henrik Rydberg 2010-08-31 22:29 ` Chase Douglas 2010-08-31 18:41 ` [PATCH 5/6 v2] HID: magicmouse: enable Magic Trackpad support Chase Douglas 2010-08-31 22:00 ` Henrik Rydberg 2010-09-01 1:26 ` Chase Douglas 2010-09-01 0:08 ` Michael Poole 2010-09-01 1:55 ` Chase Douglas 2010-08-31 18:41 ` [PATCH 6/6 v2] HID: magicmouse: Adjust major / minor axes to scale Chase Douglas 2010-08-31 23:45 ` [PATCH 1/6 v2] HID: magicmouse: don't allow hidinput to initialize the device Michael Poole
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).