Re: [PATCH] HID: ite: Only bind to keyboard USB interface on Acer SW5-012 keyboard dock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 31, 2020 at 2:41 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
>
> Hi,
>
> On 1/31/20 2:10 PM, Benjamin Tissoires wrote:
> > Hi Hans,
> >
> > On Fri, Jan 31, 2020 at 1:46 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
> >>
> >> Commit 8f18eca9ebc5 ("HID: ite: Add USB id match for Acer SW5-012 keyboard
> >> dock") added the USB id for the Acer SW5-012's keyboard dock to the
> >> hid-ite driver to fix the rfkill driver not working.
> >>
> >> Most keyboard docks with an ITE 8595 keyboard/touchpad controller have the
> >> "Wireless Radio Control" bits which need the special hid-ite driver on the
> >> second USB interface (the mouse interface) and their touchpad only supports
> >> mouse emulation, so using generic hid-input handling for anything but
> >> the "Wireless Radio Control" bits is fine. On these devices we simply bind
> >> to all USB interfaces.
> >>
> >> But unlike other ITE8595 using keyboard docks, the Acer Aspire Switch 10
> >> (SW5-012)'s touchpad not only does mouse emulation it also supports
> >> HID-multitouch and all the keys including the "Wireless Radio Control"
> >> bits have been moved to the first USB interface (the keyboard intf).
> >>
> >> So we need hid-ite to handle the first (keyboard) USB interface and have
> >> it NOT bind to the second (mouse) USB interface so that that can be
> >> handled by hid-multitouch.c and we get proper multi-touch support.
> >>
> >> This commit adds a match callback to hid-ite which makes it only
> >> match the first USB interface when running on the Acer SW5-012,
> >> fixing the regression to mouse-emulation mode introduced by adding the
> >> keyboard dock USB id.
> >>
> >> Note the match function only does the special only bind to the first
> >> USB interface on the Acer SW5-012, on other devices the hid-ite driver
> >> actually must bind to the second interface as that is where the
> >> "Wireless Radio Control" bits are.
> >
> > This is not a full review, but a couple of things that popped out
> > while scrolling through the patch.
> >
> >>
> >> Cc: stable@xxxxxxxxxxxxxxx
> >> Fixes: 8f18eca9ebc5 ("HID: ite: Add USB id match for Acer SW5-012 keyboard dock")
> >> Reported-by: Zdeněk Rampas <zdenda.rampas@xxxxxxxxx>
> >> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> >> ---
> >>   drivers/hid/hid-ite.c | 34 ++++++++++++++++++++++++++++++++++
> >>   1 file changed, 34 insertions(+)
> >>
> >> diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c
> >> index c436e12feb23..69a4ddfd033d 100644
> >> --- a/drivers/hid/hid-ite.c
> >> +++ b/drivers/hid/hid-ite.c
> >> @@ -8,9 +8,12 @@
> >>   #include <linux/input.h>
> >>   #include <linux/hid.h>
> >>   #include <linux/module.h>
> >> +#include <linux/usb.h>
> >>
> >>   #include "hid-ids.h"
> >>
> >> +#define ITE8595_KBD_USB_INTF           0
> >> +
> >>   static int ite_event(struct hid_device *hdev, struct hid_field *field,
> >>                       struct hid_usage *usage, __s32 value)
> >>   {
> >> @@ -37,6 +40,36 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field,
> >>          return 0;
> >>   }
> >>
> >> +static bool ite_match(struct hid_device *hdev, bool ignore_special_driver)
> >> +{
> >> +       struct usb_interface *intf;
> >> +
> >> +       if (ignore_special_driver)
> >> +               return false;
> >> +
> >> +       /*
> >> +        * Most keyboard docks with an ITE 8595 keyboard/touchpad controller
> >> +        * have the "Wireless Radio Control" bits which need this special
> >> +        * driver on the second USB interface (the mouse interface). On
> >> +        * these devices we simply bind to all USB interfaces.
> >> +        *
> >> +        * The Acer Aspire Switch 10 (SW5-012) is special, its touchpad
> >> +        * not only does mouse emulation it also supports HID-multitouch
> >> +        * and all the keys including the "Wireless Radio Control" bits
> >> +        * have been moved to the first USB interface (the keyboard intf).
> >> +        *
> >> +        * We want the hid-multitouch driver to bind to the touchpad, so on
> >> +        * the Acer SW5-012 we should only bind to the keyboard USB intf.
> >> +        */
> >> +       if (hdev->bus != BUS_USB || hdev->vendor != USB_VENDOR_ID_SYNAPTICS ||
> >> +                    hdev->product != USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012)
> >
> > Isn't there an existing matching function we can use here, instead of
> > checking each individual field?
>
> There is hid_match_one_id() but that is not exported (can be fixed) and it
> requires a struct hid_device_id, which either requires declaring an extra
> standalone struct hid_device_id for the SW5-012 kbd-dock, or hardcoding an
> index into the existing hid_device_id array for the driver (with the hardcoding
> being error prone, so not a good idea).
>
> Given the problems with using hid_match_one_id() I decided to just go with
> the above.

right. An other solution would be to have a local macro/function that
does that. Because as soon as you start adding a quirk, an other comes
right after.

>
> But see below.
>
> >
> >> +               return true;
> >> +
> >> +       intf = to_usb_interface(hdev->dev.parent);
> >
> > And this is oops-prone. You need:
> > - ensure hid_is_using_ll_driver(hdev, &usb_hid_driver) returns true.
> > - add a dependency on USBHID in the KConfig now that you are checking
> > on the USB transport layer.
> >
> > That being said, I would love instead:
> > - to have a non USB version of this match, where you decide which
> > component needs to be handled based on the report descriptor
>
> Actually your idea to use the desciptors is not bad, but since what
> we really want is to not bind to the interface which is marked for the
> hid-multitouch driver I just realized we can just check that.
>
> So how about:
>
> static bool ite_match(struct hid_device *hdev, bool ignore_special_driver)
> {
>          if (ignore_special_driver)
>                  return false;
>
>          /*
>           * Some keyboard docks with an ITE 8595 keyboard/touchpad controller
>           * support the HID multitouch protocol for the touchpad, in that
>           * case the "Wireless Radio Control" bits which we care about are
>           * on the other interface; and we should not bind to the multitouch
>           * capable interface as that breaks multitouch support.
>           */
>          return hdev->group != HID_GROUP_MULTITOUCH_WIN_8;
> }

Yep, I like that very much :)

>
> ? (note untested)
>
> Zdeněk  I have attached a new version of the patch which uses this
> improved version of the match function, if you have a chance to test it
> this weekend that would be great, otherwise I will test it on my own
> sw5-012 on Monday.
>
> > - have a regression test in
> > https://gitlab.freedesktop.org/libevdev/hid-tools for this particular
> > device, because I never intended the .match callback to be used by
> > anybody else than hid-generic, and opening this can of worms is prone
> > to introduce regressions in the future.
>
> Ugh, I can understand your desire for a test for this, but writing
> tests is not really my thing. Anyways do you have an example test I
> could use as a start ?

So, if I am not wrong:
- keyboard docks with an ITE 8595 keyboard/touchpad controller are
registered in hid-ite.c, but should be really bound to hid-multitouch.
- there are at least 2 HID interfaces (sharing the same VID/PID), one
for the keyboard (hid-ite.c), and one for the touchpad
(hid-multitouch.c)
- what matters in the end, is that the multitouch interface gets
correctly mapped and handled.

So if that is somehow accurate, I think a test would be a matter of:
- duplicating https://gitlab.freedesktop.org/libevdev/hid-tools/blob/master/tests/test_multitouch.py#L1568-1570,
- add the report descriptors of the touchpad interface,
- and check that the unpatched kernel picks up hid-ite.c, which leads
to errors in the multitouch tests
- ideally, we should also add a test for the expected hid-ite.c part,
but I can do that later with the report descriptors.

So initially, it shouldn't be more than a 3 lines patch (hopefully).
Actually 4, because you also need to force the VID/PID with
`info=(0x3, 0xVID, 0xPID)` (see TestZytronic_14c8_0005 for an example,
in the same file)

Cheers,
Benjamin

>
> Regards,
>
> Hans





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux