[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CA+rSvc7goy-h-Hu7MruaryngBs39_8oE1AijFAnybuDSiSRHhw@mail.gmail.com>
Date: Tue, 21 Jul 2020 05:24:34 +0900
From: Frank Yang <puilp0502@...il.com>
To: linux-kernel@...r.kernel.org
Cc: Jiri Kosina <jikos@...nel.org>,
Benjamin Tissoires <benjamin.tissoires@...hat.com>,
linux-input@...r.kernel.org
Subject: Re: [PATCH] HID: Support Varmilo Keyboards' media hotkeys
On Tue, 2020-07-21 at 05:10 +0900, Frank Yang <puilp0502@...il.com> wrote:
>
> The Varmilo VA104M Keyboard (04b4:07b1, reported as Varmilo Z104M)
> exposes media control hotkeys as a USB HID consumer control device,
> but these keys do not work in the current (5.8-rc1) kernel due to
> the incorrect HID report descriptor. Fix the problem by modifying
> the internal HID report descriptor.
>
> More specifically, the keyboard report descriptor specifies the
> logical boundary as 572~10754 (0x023c ~ 0x2a02) while the usage
> boundary is specified as 0~10754 (0x00 ~ 0x2a02). This results in an
> incorrect interpretation of input reports, causing inputs to be ignored.
> By setting the Logical Minimum to zero, we align the logical boundary
> with the Usage ID boundary.
>
> Some notes:
>
> * There seem to be multiple variants of the VA104M keyboard. This
> patch specifically targets 04b4:07b1 variant.
>
> * The device works out-of-the-box on Windows platform with the generic
> consumer control device driver (hidserv.inf). This suggests that
> Windows either ignores the Logical Minimum/Logical Maximum or
> interprets the Usage ID assignment differently from the linux
> implementation; Maybe there are other devices out there that only
> works on Windows due to this problem?
>
> Signed-off-by: Frank Yang <puilp0502@...il.com>
> ---
> drivers/hid/Kconfig | 6 ++++
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-ids.h | 2 ++
> drivers/hid/hid-varmilo.c | 58 +++++++++++++++++++++++++++++++++++++++
> 4 files changed, 67 insertions(+)
> create mode 100644 drivers/hid/hid-varmilo.c
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 443c5cbbde04..c9f0c9b79158 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -441,6 +441,12 @@ config HID_WALTOP
> ---help---
> Support for Waltop tablets.
>
> +config HID_VARMILO
> + tristate "Varmilo Keyboards"
> + depends on HID
> + help
> + Support for Varmilo keyboards.
> +
> config HID_VIEWSONIC
> tristate "ViewSonic/Signotec"
> depends on HID
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index d8ea4b8c95af..e90a98090452 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -124,6 +124,7 @@ obj-$(CONFIG_HID_LED) += hid-led.o
> obj-$(CONFIG_HID_XINMO) += hid-xinmo.o
> obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
> obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
> +obj-$(CONFIG_HID_VARMILO) += hid-varmilo.o
> obj-$(CONFIG_HID_VIEWSONIC) += hid-viewsonic.o
>
> wacom-objs := wacom_wac.o wacom_sys.o
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 874fc3791f3b..955be22fc69d 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -1189,6 +1189,8 @@
> #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
> #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19
>
> +#define USB_DEVICE_ID_VARMILO_VA104M_07B1 0X07b1
> +
> #define USB_VENDOR_ID_VELLEMAN 0x10cf
> #define USB_DEVICE_ID_VELLEMAN_K8055_FIRST 0x5500
> #define USB_DEVICE_ID_VELLEMAN_K8055_LAST 0x5503
> diff --git a/drivers/hid/hid-varmilo.c b/drivers/hid/hid-varmilo.c
> new file mode 100644
> index 000000000000..10e50f2dca61
> --- /dev/null
> +++ b/drivers/hid/hid-varmilo.c
> @@ -0,0 +1,58 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * HID report fixup for varmilo keyboards
> + *
> + * Copyright (c) 2020 Frank Yang <puilp0502@...il.com>
> + *
> + */
> +
> +#include <linux/hid.h>
> +#include <linux/module.h>
> +
> +#include "hid-ids.h"
> +
> +/*
> + * Varmilo VA104M with device ID of 07B1 incorrectly reports Logical Minimum as
> + * 572 (0x02 0x3c). We fix this by setting Logical Minimum to zero.
> + */
> +static __u8 *varmilo_07b1_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> + unsigned int *rsize)
> +{
> + if (*rsize == 25 &&
> + rdesc[0] == 0x05 && rdesc[1] == 0x0c &&
> + rdesc[2] == 0x09 && rdesc[3] == 0x01 &&
> + rdesc[6] == 0x19 && rdesc[7] == 0x00 &&
> + rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) {
> + hid_info(hdev,
> + "fixing up varmilo VA104M consumer control report descriptor\n");
> + rdesc[12] = 0x00;
> + rdesc[13] = 0x00;
> + }
> + return rdesc;
> +}
> +
> +static __u8 *varmilo_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> + unsigned int *rsize)
> +{
> + if (hdev->product == USB_DEVICE_ID_VARMILO_VA104M_07B1 &&
> + hdev->vendor == USB_VENDOR_ID_CYPRESS)
> + rdesc = varmilo_07b1_report_fixup(hdev, rdesc, rsize);
> + return rdesc;
> +}
> +
> +static const struct hid_device_id varmilo_devices[] = {
> + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_VARMILO_VA104M_07B1) },
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(hid, varmilo_devices);
> +
> +static struct hid_driver varmilo_driver = {
> + .name = "varmilo",
> + .id_table = varmilo_devices,
> + .report_fixup = varmilo_report_fixup,
> +};
> +
> +module_hid_driver(varmilo_driver);
> +
> +MODULE_LICENSE("GPL");
> --
> 2.17.1
>
CCing linux-input mailing list.
Cc: linux-input@...r.kernel.org
Powered by blists - more mailing lists