* [PATCH (repost)] Input: MT - use __GFP_NOWARN allocation at input_mt_init_slots()
From: Tetsuo Handa @ 2023-03-28 11:25 UTC (permalink / raw)
To: Henrik Rydberg, Dmitry Torokhov; +Cc: linux-input@vger.kernel.org
syzbot is reporting too large allocation at input_mt_init_slots(), for
num_slots is supplied from userspace using ioctl(UI_DEV_CREATE).
Use __GFP_NOWARN. Also, replace n2 with array_size(), for 32bits variable
n2 will overflow if num_slots >= 65536 and will cause out of bounds
read/write at input_mt_set_matrix()/input_mt_set_slots() on architectures
where PAGE_SIZE > 4096 is available (e.g. PPC64).
Reported-by: syzbot <syzbot+0122fa359a69694395d5@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=0122fa359a69694395d5
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
Dmitry Torokhov proposed limiting max size to accept. But since it seems
that nobody knows appropriate max size to accept, reposting as-is.
https://lkml.kernel.org/r/03e8c3f0-bbbf-af37-6f52-67547cbd4cde@I-love.SAKURA.ne.jp
drivers/input/input-mt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 14b53dac1253..cf74579462ba 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -47,7 +47,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
if (mt)
return mt->num_slots != num_slots ? -EINVAL : 0;
- mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL);
+ mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL | __GFP_NOWARN);
if (!mt)
goto err_mem;
@@ -80,8 +80,8 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
if (flags & INPUT_MT_SEMI_MT)
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
if (flags & INPUT_MT_TRACK) {
- unsigned int n2 = num_slots * num_slots;
- mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL);
+ mt->red = kcalloc(array_size(num_slots, num_slots),
+ sizeof(*mt->red), GFP_KERNEL | __GFP_NOWARN);
if (!mt->red)
goto err_mem;
}
--
2.18.4
^ permalink raw reply related
* Re: [PATCH v2] HID: intel-ish-hid: Fix kernel panic during warm reset
From: Jiri Kosina @ 2023-03-28 12:04 UTC (permalink / raw)
To: Tanu Malhotra
Cc: srinivas.pandruvada, linux-input, linux-kernel, even.xu, stable,
Shaunak Saha
In-Reply-To: <20230327185838.2527560-1-tanu.malhotra@intel.com>
On Mon, 27 Mar 2023, Tanu Malhotra wrote:
> During warm reset device->fw_client is set to NULL. If a bus driver is
> registered after this NULL setting and before new firmware clients are
> enumerated by ISHTP, kernel panic will result in the function
> ishtp_cl_bus_match(). This is because of reference to
> device->fw_client->props.protocol_name.
>
> ISH firmware after getting successfully loaded, sends a warm reset
> notification to remove all clients from the bus and sets
> device->fw_client to NULL. Until kernel v5.15, all enabled ISHTP kernel
> module drivers were loaded right after any of the first ISHTP device was
> registered, regardless of whether it was a matched or an unmatched
> device. This resulted in all drivers getting registered much before the
> warm reset notification from ISH.
>
> Starting kernel v5.16, this issue got exposed after the change was
> introduced to load only bus drivers for the respective matching devices.
> In this scenario, cros_ec_ishtp device and cros_ec_ishtp driver are
> registered after the warm reset device fw_client NULL setting.
> cros_ec_ishtp driver_register() triggers the callback to
> ishtp_cl_bus_match() to match ISHTP driver to the device and causes kernel
> panic in guid_equal() when dereferencing fw_client NULL pointer to get
> protocol_name.
>
> Fixes: f155dfeaa4ee ("platform/x86: isthp_eclite: only load for matching devices")
> Fixes: facfe0a4fdce ("platform/chrome: chros_ec_ishtp: only load for matching devices")
> Fixes: 0d0cccc0fd83 ("HID: intel-ish-hid: hid-client: only load for matching devices")
> Fixes: 44e2a58cb880 ("HID: intel-ish-hid: fw-loader: only load for matching devices")
> Cc: <stable@vger.kernel.org> # 5.16+
> Signed-off-by: Tanu Malhotra <tanu.malhotra@intel.com>
> Tested-by: Shaunak Saha <shaunak.saha@intel.com>
> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Applied, thank you.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] dt-bindings: input: pwm-beeper: convert to dt schema
From: Rob Herring @ 2023-03-28 12:57 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: devicetree, Peng Fan, robh+dt, s.hauer, dmitry.torokhov,
krzysztof.kozlowski+dt, linux-kernel, linux-input
In-Reply-To: <20230328054833.1974942-1-peng.fan@oss.nxp.com>
On Tue, 28 Mar 2023 13:48:33 +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Convert the binding doc to dt schema, and also fixed the
> example from fixed-regulator to regulator-fixed.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> .../devicetree/bindings/input/pwm-beeper.txt | 24 ----------
> .../devicetree/bindings/input/pwm-beeper.yaml | 48 +++++++++++++++++++
> 2 files changed, 48 insertions(+), 24 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/input/pwm-beeper.txt
> create mode 100644 Documentation/devicetree/bindings/input/pwm-beeper.yaml
>
Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.
Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.
Full log is available here: https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230328054833.1974942-1-peng.fan@oss.nxp.com
beeper: beeper-hz:0:0: 4000 is greater than the maximum of 255
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
beeper: pwms:0: [19, 31, 4000] is too long
arch/arm/boot/dts/armada-370-c200-v2.dtb
beeper: pwms:0: [52, 5, 1000000, 0] is too long
arch/arm/boot/dts/aspeed-bmc-vegman-n110.dtb
beeper: pwms:0: [53, 5, 1000000, 0] is too long
arch/arm/boot/dts/aspeed-bmc-vegman-rx20.dtb
arch/arm/boot/dts/aspeed-bmc-vegman-sx20.dtb
beeper: pwms:0: [72, 0, 250000, 0] is too long
arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dtb
beeper: pwms:0: [91, 0, 250000, 0] is too long
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
beeper: pwms:0: [98, 0, 250000, 0] is too long
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
beeper: pwms:0: [98, 0, 500000] is too long
arch/arm/boot/dts/imx6q-kp-tpc.dtb
beeper: Unevaluated properties are not allowed ('beeper-hz', 'pwms' were unexpected)
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
beeper: Unevaluated properties are not allowed ('pwms' was unexpected)
arch/arm/boot/dts/armada-370-c200-v2.dtb
arch/arm/boot/dts/aspeed-bmc-vegman-n110.dtb
arch/arm/boot/dts/aspeed-bmc-vegman-rx20.dtb
arch/arm/boot/dts/aspeed-bmc-vegman-sx20.dtb
arch/arm/boot/dts/imx6q-kp-tpc.dtb
beep: pwms:0: [108, 0, 4000000, 1] is too long
arch/arm/boot/dts/exynos4412-itop-elite.dtb
beep: Unevaluated properties are not allowed ('pwms' was unexpected)
arch/arm/boot/dts/exynos4412-itop-elite.dtb
buzzer: pwms:0: [20, 0, 1000000, 0] is too long
arch/arm/boot/dts/s3c6410-mini6410.dtb
buzzer: pwms:0: [41, 0, 500000] is too long
arch/arm/boot/dts/imx53-kp-ddc.dtb
buzzer: pwms:0: [42, 0, 500000] is too long
arch/arm/boot/dts/imx53-kp-hsc.dtb
buzzer: Unevaluated properties are not allowed ('pwms' was unexpected)
arch/arm/boot/dts/imx53-kp-ddc.dtb
arch/arm/boot/dts/imx53-kp-hsc.dtb
arch/arm/boot/dts/s3c6410-mini6410.dtb
pwm-beeper: pwms:0: [56, 0, 5000] is too long
arch/arm/boot/dts/imx6ul-kontron-bl.dtb
arch/arm/boot/dts/imx6ull-kontron-bl.dtb
pwm-beeper: pwms:0: [60, 0, 5000] is too long
arch/arm/boot/dts/imx6ul-kontron-bl-43.dtb
pwm-beeper: pwms:0: [83, 0, 5000, 0] is too long
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
pwm-beeper: pwms:0: [86, 0, 5000, 0] is too long
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
pwm-beeper: Unevaluated properties are not allowed ('pwms' was unexpected)
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm/boot/dts/imx6ul-kontron-bl-43.dtb
arch/arm/boot/dts/imx6ul-kontron-bl.dtb
arch/arm/boot/dts/imx6ull-kontron-bl.dtb
sound: pwms:0: [44, 1, 1000000, 0] is too long
arch/arm/boot/dts/da850-lego-ev3.dtb
sound: Unevaluated properties are not allowed ('pwms' was unexpected)
arch/arm/boot/dts/da850-lego-ev3.dtb
^ permalink raw reply
* Re: [PATCH] dt-bindings: input: pwm-beeper: convert to dt schema
From: Rob Herring @ 2023-03-28 13:54 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: dmitry.torokhov, krzysztof.kozlowski+dt, s.hauer, linux-input,
devicetree, linux-kernel, Peng Fan
In-Reply-To: <20230328054833.1974942-1-peng.fan@oss.nxp.com>
On Tue, Mar 28, 2023 at 12:43 AM Peng Fan (OSS) <peng.fan@oss.nxp.com> wrote:
>
> From: Peng Fan <peng.fan@nxp.com>
>
> Convert the binding doc to dt schema, and also fixed the
> example from fixed-regulator to regulator-fixed.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> .../devicetree/bindings/input/pwm-beeper.txt | 24 ----------
> .../devicetree/bindings/input/pwm-beeper.yaml | 48 +++++++++++++++++++
> 2 files changed, 48 insertions(+), 24 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/input/pwm-beeper.txt
> create mode 100644 Documentation/devicetree/bindings/input/pwm-beeper.yaml
>
> diff --git a/Documentation/devicetree/bindings/input/pwm-beeper.txt b/Documentation/devicetree/bindings/input/pwm-beeper.txt
> deleted file mode 100644
> index 8fc0e48c20db..000000000000
> --- a/Documentation/devicetree/bindings/input/pwm-beeper.txt
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -* PWM beeper device tree bindings
> -
> -Registers a PWM device as beeper.
> -
> -Required properties:
> -- compatible: should be "pwm-beeper"
> -- pwms: phandle to the physical PWM device
> -
> -Optional properties:
> -- amp-supply: phandle to a regulator that acts as an amplifier for the beeper
> -- beeper-hz: bell frequency in Hz
> -
> -Example:
> -
> -beeper_amp: amplifier {
> - compatible = "fixed-regulator";
> - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
> -};
> -
> -beeper {
> - compatible = "pwm-beeper";
> - pwms = <&pwm0>;
> - amp-supply = <&beeper_amp>;
> -};
> diff --git a/Documentation/devicetree/bindings/input/pwm-beeper.yaml b/Documentation/devicetree/bindings/input/pwm-beeper.yaml
> new file mode 100644
> index 000000000000..1d7cd58d2a8f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/pwm-beeper.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
'or-later' is wrong.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/pwm-beeper.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PWM beeper
> +
> +maintainers:
> + - Sascha Hauer <s.hauer@pengutronix.de>
> +
> +properties:
> + compatible:
> + items:
Drop 'items' as there is only 1.
> + - const: pwm-beeper
> +
> + pwms:
> + description: Phandle to the physical PWM device
> + $ref: /schemas/types.yaml#/definitions/phandle
Standard property which already has a type.
> +
> + amp-supply:
> + description: Phandle to a regulator that acts as an amplifier for the beeper
> +
> + beeper-hz:
> + description: bell frequency in Hz
> + minimum: 1
> + maximum: 255
doubtful a beeper can generate frequencies of 1-255Hz...
> +
> +required:
> + - compatible
> + - pwms
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + beeper_amp: amplifier {
Don't need to show providers in examples for the consumer.
> + compatible = "regulator-fixed";
> + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
> + regulator-name = "beeper_amp";
> + };
> +
> + beeper {
> + compatible = "pwm-beeper";
> + pwms = <&pwm0>;
> + amp-supply = <&beeper_amp>;
Make the example complete and add beeper-hz.
> + };
> --
> 2.37.1
>
^ permalink raw reply
* [PATCH v3] Input: tsc2007 - enable GPIO chips that can sleep
From: Benjamin Bara @ 2023-03-28 15:31 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: richard.leitner, christophe.jaillet, linux-input, linux-kernel,
Benjamin Bara, Richard Leitner
From: Benjamin Bara <benjamin.bara@skidata.com>
This enables the usage of "can_sleep" GPIO chips as "pin up" GPIO.
This might be the case if the GPIO chip is an expander behind i2c.
As the pendown value is read during a hard IRQ, the read process is not
allowed to sleep. Therefore, find out if the read process can sleep and
if so, just return true. During the following soft IRQ, the read process
is allowed to sleep and therefore the actual value can be read.
Signed-off-by: Benjamin Bara <benjamin.bara@skidata.com>
Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
---
This is basically a resend of v2 with extended commit message.
v2: https://lore.kernel.org/lkml/20220715074534.3116678-1-bbara93@gmail.com/
----
v3:
- extend commit message
v2:
- fix style mentioned by Christophe
---
drivers/input/touchscreen/tsc2007.h | 1 +
drivers/input/touchscreen/tsc2007_core.c | 34 +++++++++++++++++++++++++++-----
2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/tsc2007.h b/drivers/input/touchscreen/tsc2007.h
index 69b08dd6c8df..cdd90d727160 100644
--- a/drivers/input/touchscreen/tsc2007.h
+++ b/drivers/input/touchscreen/tsc2007.h
@@ -78,6 +78,7 @@ struct tsc2007 {
bool stopped;
int (*get_pendown_state)(struct device *);
+ int (*get_pendown_state_cansleep)(struct device *dev);
void (*clear_penirq)(void);
struct mutex mlock;
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c
index 3c793fb70a0e..764cec1036e1 100644
--- a/drivers/input/touchscreen/tsc2007_core.c
+++ b/drivers/input/touchscreen/tsc2007_core.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
@@ -108,6 +109,14 @@ bool tsc2007_is_pen_down(struct tsc2007 *ts)
return ts->get_pendown_state(&ts->client->dev);
}
+static bool tsc2007_is_pen_down_cansleep(struct tsc2007 *ts)
+{
+ if (!ts->get_pendown_state_cansleep)
+ return true;
+
+ return ts->get_pendown_state_cansleep(&ts->client->dev);
+}
+
static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
{
struct tsc2007 *ts = handle;
@@ -115,7 +124,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
struct ts_event tc;
u32 rt;
- while (!ts->stopped && tsc2007_is_pen_down(ts)) {
+ while (!ts->stopped && tsc2007_is_pen_down_cansleep(ts)) {
/* pen is down, continue with the measurement */
@@ -125,7 +134,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
rt = tsc2007_calculate_resistance(ts, &tc);
- if (!rt && !ts->get_pendown_state) {
+ if (!rt && !ts->get_pendown_state_cansleep) {
/*
* If pressure reported is 0 and we don't have
* callback to check pendown state, we have to
@@ -229,6 +238,14 @@ static int tsc2007_get_pendown_state_gpio(struct device *dev)
return gpiod_get_value(ts->gpiod);
}
+static int tsc2007_get_pendown_state_gpio_cansleep(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct tsc2007 *ts = i2c_get_clientdata(client);
+
+ return gpiod_get_value_cansleep(ts->gpiod);
+}
+
static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts)
{
u32 val32;
@@ -264,10 +281,17 @@ static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts)
if (IS_ERR(ts->gpiod))
return PTR_ERR(ts->gpiod);
- if (ts->gpiod)
- ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
- else
+ if (ts->gpiod) {
+ ts->get_pendown_state_cansleep = tsc2007_get_pendown_state_gpio_cansleep;
+
+ /* pendown pin is read during hard irq -> gpio chip is not allowed to sleep */
+ if (gpiod_to_chip(ts->gpiod) && !gpiod_to_chip(ts->gpiod)->can_sleep)
+ ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
+ else
+ dev_dbg(dev, "Pen down GPIO chip can sleep\n");
+ } else {
dev_warn(dev, "Pen down GPIO is not specified in properties\n");
+ }
return 0;
}
---
base-commit: 197b6b60ae7bc51dd0814953c562833143b292aa
change-id: 20230328-tsc2007-sleep-f65953ae32d0
Best regards,
--
Benjamin Bara <benjamin.bara@skidata.com>
^ permalink raw reply related
* [PATCH] Series-to: Fred Bloggs <f.blogs@napier.co.nz> Series-cc: Sean O'Brien <seobrien@chromium.org> HID: input: Restore missing cursor for digitizer devices
From: Torsha Banerjee @ 2023-03-28 16:11 UTC (permalink / raw)
To: u-boot
Cc: Jora Jacobi, Torsha Banerjee, Benjamin Tissoires, Jiri Kosina,
linux-input, linux-kernel
From: Jora Jacobi <jora@google.com>
A previously committed patch to remove cursors for HID Digitizer-Pen
devices also removed the cursors for some tablets which have incorrect HID
descriptors. These devices should enumerate with Usage ID "Digitizer"
instead of Usage ID "Pen".
Patch which introduced the issue: commit 8473a93d1ba5
("HID: input: Set INPUT_PROP_-property for HID_UP_DIGITIZERS")
Changes-
Add HID quirk HID_QUIRK_DEVICE_IS_DIGITIZER
Quirk will force INPUT_PROP_POINTER for HID Digitizers
Apply quirk to Huion tablets
Apply quirk to UGEE/XP-Pen tablets based on device ID
Signed-off-by: Torsha Banerjee <torsha@google.com>
---
drivers/hid/hid-input.c | 3 ++-
drivers/hid/hid-quirks.c | 9 +++++++++
include/linux/hid.h | 2 ++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7fc967964dd8..f0c67baddc8d 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -927,7 +927,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
break;
case HID_UP_DIGITIZER:
- if ((field->application & 0xff) == 0x01) /* Digitizer */
+ if (((field->application & 0xff) == 0x01) ||
+ (device->quirks & HID_QUIRK_DEVICE_IS_DIGITIZER)) /* Digitizer */
__set_bit(INPUT_PROP_POINTER, input->propbit);
else if ((field->application & 0xff) == 0x02) /* Pen */
__set_bit(INPUT_PROP_DIRECT, input->propbit);
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 66e64350f138..094fe4c4f3b3 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -102,6 +102,8 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_HS64), HID_QUIRK_DEVICE_IS_DIGITIZER },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET), HID_QUIRK_DEVICE_IS_DIGITIZER },
{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
@@ -1298,6 +1300,13 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev)
quirks = hid_gets_squirk(hdev);
mutex_unlock(&dquirks_lock);
+ /*
+ * UGEE/XP-Pen HID Pen devices which have 0x0-0x9 as the low nibble
+ * of the device ID are actually digitizers, not HID Pen devices
+ */
+ if (hdev->vendor == USB_VENDOR_ID_UGEE && (hdev->product & 0x0F) <= 0x09)
+ quirks |= HID_QUIRK_DEVICE_IS_DIGITIZER;
+
return quirks;
}
EXPORT_SYMBOL_GPL(hid_lookup_quirk);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 1ea8c7a3570b..c9cc81e85a33 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -352,8 +352,10 @@ struct hid_item {
/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
#define HID_QUIRK_ALWAYS_POLL BIT(10)
#define HID_QUIRK_INPUT_PER_APP BIT(11)
+
#define HID_QUIRK_X_INVERT BIT(12)
#define HID_QUIRK_Y_INVERT BIT(13)
+#define HID_QUIRK_DEVICE_IS_DIGITIZER BIT(14)
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
--
2.40.0.348.gf938b09366-goog
^ permalink raw reply related
* Re: [PATCH] Series-to: Fred Bloggs <f.blogs@napier.co.nz> Series-cc: Sean O'Brien <seobrien@chromium.org> HID: input: Restore missing cursor for digitizer devices
From: kernel test robot @ 2023-03-28 22:01 UTC (permalink / raw)
To: Torsha Banerjee, u-boot
Cc: oe-kbuild-all, Jora Jacobi, Torsha Banerjee, Benjamin Tissoires,
Jiri Kosina, linux-input, linux-kernel
In-Reply-To: <20230328161119.1.I40a8881b83b0e440ed5368d98b42a2d9a0c105aa@changeid>
Hi Torsha,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on v6.3-rc4]
[also build test ERROR on linus/master next-20230328]
[cannot apply to hid/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Torsha-Banerjee/Series-to-Fred-Bloggs-f-blogs-napier-co-nz-Series-cc-Sean-O-Brien-seobrien-chromium-org-HID-input-Restore-missing-cursor/20230329-001305
patch link: https://lore.kernel.org/r/20230328161119.1.I40a8881b83b0e440ed5368d98b42a2d9a0c105aa%40changeid
patch subject: [PATCH] Series-to: Fred Bloggs <f.blogs@napier.co.nz> Series-cc: Sean O'Brien <seobrien@chromium.org> HID: input: Restore missing cursor for digitizer devices
config: riscv-allmodconfig (https://download.01.org/0day-ci/archive/20230329/202303290538.GxYGQ37a-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/15e6cca84ddc6ef20ce0e540e439b1e976006f0b
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Torsha-Banerjee/Series-to-Fred-Bloggs-f-blogs-napier-co-nz-Series-cc-Sean-O-Brien-seobrien-chromium-org-HID-input-Restore-missing-cursor/20230329-001305
git checkout 15e6cca84ddc6ef20ce0e540e439b1e976006f0b
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303290538.GxYGQ37a-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/hid/hid-quirks.c:15:
>> drivers/hid/hid-quirks.c:105:47: error: 'USB_DEVICE_ID_HUION_HS64' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_HUION_TABLET'?
105 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_HS64), HID_QUIRK_DEVICE_IS_DIGITIZER },
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/hid.h:716:54: note: in definition of macro 'HID_USB_DEVICE'
716 | .bus = BUS_USB, .vendor = (ven), .product = (prod)
| ^~~~
vim +105 drivers/hid/hid-quirks.c
22
23 /*
24 * Alphabetically sorted by vendor then product.
25 */
26
27 static const struct hid_device_id hid_quirks[] = {
28 { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD), HID_QUIRK_BADPAD },
29 { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR), HID_QUIRK_BADPAD },
30 { HID_USB_DEVICE(USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016), HID_QUIRK_FULLSPEED_INTERVAL },
31 { HID_USB_DEVICE(USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS), HID_QUIRK_NOGET },
32 { HID_USB_DEVICE(USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX), HID_QUIRK_NO_INIT_REPORTS },
33 { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
34 { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
35 { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
36 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
37 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
38 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
39 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U), HID_QUIRK_NOGET },
40 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758), HID_QUIRK_NOGET },
41 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682), HID_QUIRK_NOGET },
42 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692), HID_QUIRK_NOGET },
43 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET },
44 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
45 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
46 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
47 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS), HID_QUIRK_MULTI_INPUT },
48 { HID_USB_DEVICE(USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD), HID_QUIRK_BADPAD },
49 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK), HID_QUIRK_NOGET },
50 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295), HID_QUIRK_NOGET },
51 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK), HID_QUIRK_NOGET },
52 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK), HID_QUIRK_NOGET },
53 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE), HID_QUIRK_NOGET },
54 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
55 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
56 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
57 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
58 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
59 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
60 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
61 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS },
62 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
63 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS },
64 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
65 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
66 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
67 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
68 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
69 { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET },
70 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT },
71 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT },
72 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
73 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT },
74 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT },
75 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT },
76 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT },
77 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT },
78 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
79 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_QUIRK_ALWAYS_POLL },
80 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700), HID_QUIRK_NOGET },
81 { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II), HID_QUIRK_MULTI_INPUT },
82 { HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968), HID_QUIRK_MULTI_INPUT },
83 { HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH), HID_QUIRK_MULTI_INPUT },
84 { HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS },
85 { HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET },
86 { HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS },
87 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT },
88 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT },
89 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186),
90 HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
91 { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI),
92 HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
93 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
94 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
95 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
96 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
97 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
98 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
99 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
100 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
101 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
102 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL },
103 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
104 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL },
> 105 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_HS64), HID_QUIRK_DEVICE_IS_DIGITIZER },
106 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET), HID_QUIRK_DEVICE_IS_DIGITIZER },
107 { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
108 { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
109 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
110 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X), HID_QUIRK_MULTI_INPUT },
111 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
112 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT },
113 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT },
114 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL },
115 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
116 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
117 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
118 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL },
119 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL },
120 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL },
121 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL },
122 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
123 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A), HID_QUIRK_ALWAYS_POLL },
124 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
125 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
126 { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
127 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL },
128 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
129 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
130 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
131 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
132 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
133 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
134 { HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER), HID_QUIRK_MULTI_INPUT },
135 { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL), HID_QUIRK_NO_INIT_REPORTS },
136 { HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD), HID_QUIRK_MULTI_INPUT },
137 { HID_USB_DEVICE(USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD), HID_QUIRK_BADPAD },
138 { HID_USB_DEVICE(USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD), HID_QUIRK_BADPAD },
139 { HID_USB_DEVICE(USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750), HID_QUIRK_NO_INIT_REPORTS },
140 { HID_USB_DEVICE(USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN), HID_QUIRK_MULTI_INPUT},
141 { HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE), HID_QUIRK_NO_INIT_REPORTS },
142 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE), HID_QUIRK_NO_INIT_REPORTS },
143 { HID_USB_DEVICE(USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK), HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
144 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610), HID_QUIRK_NOGET },
145 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640), HID_QUIRK_NOGET },
146 { HID_USB_DEVICE(USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL), HID_QUIRK_HIDINPUT_FORCE },
147 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1), HID_QUIRK_NO_INIT_REPORTS },
148 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2), HID_QUIRK_NO_INIT_REPORTS },
149 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
150 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
151 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
152 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL },
153 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
154 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
155 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
156 { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
157 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
158 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET },
159 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008), HID_QUIRK_NOGET },
160 { HID_USB_DEVICE(USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER), HID_QUIRK_NO_INIT_REPORTS },
161 { HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPAD), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
162 { HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
163 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD), HID_QUIRK_BADPAD },
164 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
165 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
166 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
167 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
168 { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
169 { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
170 { HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
171 { HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD), HID_QUIRK_NO_INIT_REPORTS },
172 { HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780), HID_QUIRK_NOGET },
173 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH), HID_QUIRK_NOGET },
174 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH), HID_QUIRK_NOGET },
175 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH), HID_QUIRK_NOGET },
176 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS_TS), HID_QUIRK_NO_INIT_REPORTS },
177 { HID_USB_DEVICE(USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE), HID_QUIRK_NOGET },
178 { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1), HID_QUIRK_NOGET },
179 { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2), HID_QUIRK_NOGET },
180 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD), HID_QUIRK_NO_INIT_REPORTS },
181 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1), HID_QUIRK_NO_INIT_REPORTS },
182 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2), HID_QUIRK_NO_INIT_REPORTS },
183 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD), HID_QUIRK_NO_INIT_REPORTS },
184 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103), HID_QUIRK_NO_INIT_REPORTS },
185 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A), HID_QUIRK_NO_INIT_REPORTS },
186 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K15A), HID_QUIRK_NO_INIT_REPORTS },
187 { HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD), HID_QUIRK_BADPAD },
188 { HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT },
189 { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET },
190 { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883), HID_QUIRK_NOGET },
191 { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD), HID_QUIRK_NOGET },
192 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT },
193 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT },
194 { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT },
195 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT },
196 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT },
197 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT },
198 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
199 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
200 { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
201 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },
202
203 { 0 }
204 };
205
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
^ permalink raw reply
* Re: [PATCH] Series-to: Fred Bloggs <f.blogs@napier.co.nz> Series-cc: Sean O'Brien <seobrien@chromium.org> HID: input: Restore missing cursor for digitizer devices
From: kernel test robot @ 2023-03-28 22:21 UTC (permalink / raw)
To: Torsha Banerjee, u-boot
Cc: llvm, oe-kbuild-all, Jora Jacobi, Torsha Banerjee,
Benjamin Tissoires, Jiri Kosina, linux-input, linux-kernel
In-Reply-To: <20230328161119.1.I40a8881b83b0e440ed5368d98b42a2d9a0c105aa@changeid>
Hi Torsha,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on v6.3-rc4]
[also build test ERROR on linus/master next-20230328]
[cannot apply to hid/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Torsha-Banerjee/Series-to-Fred-Bloggs-f-blogs-napier-co-nz-Series-cc-Sean-O-Brien-seobrien-chromium-org-HID-input-Restore-missing-cursor/20230329-001305
patch link: https://lore.kernel.org/r/20230328161119.1.I40a8881b83b0e440ed5368d98b42a2d9a0c105aa%40changeid
patch subject: [PATCH] Series-to: Fred Bloggs <f.blogs@napier.co.nz> Series-cc: Sean O'Brien <seobrien@chromium.org> HID: input: Restore missing cursor for digitizer devices
config: i386-randconfig-a012-20230327 (https://download.01.org/0day-ci/archive/20230329/202303290657.v6bveeLJ-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/15e6cca84ddc6ef20ce0e540e439b1e976006f0b
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Torsha-Banerjee/Series-to-Fred-Bloggs-f-blogs-napier-co-nz-Series-cc-Sean-O-Brien-seobrien-chromium-org-HID-input-Restore-missing-cursor/20230329-001305
git checkout 15e6cca84ddc6ef20ce0e540e439b1e976006f0b
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303290657.v6bveeLJ-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/hid/hid-quirks.c:105:40: error: use of undeclared identifier 'USB_DEVICE_ID_HUION_HS64'
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_HS64), HID_QUIRK_DEVICE_IS_DIGITIZER },
^
1 error generated.
vim +/USB_DEVICE_ID_HUION_HS64 +105 drivers/hid/hid-quirks.c
22
23 /*
24 * Alphabetically sorted by vendor then product.
25 */
26
27 static const struct hid_device_id hid_quirks[] = {
28 { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD), HID_QUIRK_BADPAD },
29 { HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR), HID_QUIRK_BADPAD },
30 { HID_USB_DEVICE(USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016), HID_QUIRK_FULLSPEED_INTERVAL },
31 { HID_USB_DEVICE(USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS), HID_QUIRK_NOGET },
32 { HID_USB_DEVICE(USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX), HID_QUIRK_NO_INIT_REPORTS },
33 { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
34 { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
35 { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
36 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
37 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
38 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
39 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U), HID_QUIRK_NOGET },
40 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758), HID_QUIRK_NOGET },
41 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682), HID_QUIRK_NOGET },
42 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692), HID_QUIRK_NOGET },
43 { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET },
44 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
45 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
46 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
47 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS), HID_QUIRK_MULTI_INPUT },
48 { HID_USB_DEVICE(USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD), HID_QUIRK_BADPAD },
49 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK), HID_QUIRK_NOGET },
50 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295), HID_QUIRK_NOGET },
51 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK), HID_QUIRK_NOGET },
52 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK), HID_QUIRK_NOGET },
53 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE), HID_QUIRK_NOGET },
54 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
55 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
56 { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
57 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
58 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
59 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
60 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
61 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS },
62 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
63 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS },
64 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
65 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
66 { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
67 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
68 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
69 { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET },
70 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT },
71 { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT },
72 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
73 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT },
74 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT },
75 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT },
76 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT },
77 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT },
78 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
79 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_QUIRK_ALWAYS_POLL },
80 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700), HID_QUIRK_NOGET },
81 { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II), HID_QUIRK_MULTI_INPUT },
82 { HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968), HID_QUIRK_MULTI_INPUT },
83 { HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH), HID_QUIRK_MULTI_INPUT },
84 { HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS },
85 { HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET },
86 { HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS },
87 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT },
88 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT },
89 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186),
90 HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
91 { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI),
92 HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
93 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
94 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
95 { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
96 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
97 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
98 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
99 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
100 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
101 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
102 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL },
103 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
104 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL },
> 105 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_HS64), HID_QUIRK_DEVICE_IS_DIGITIZER },
106 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET), HID_QUIRK_DEVICE_IS_DIGITIZER },
107 { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
108 { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
109 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
110 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X), HID_QUIRK_MULTI_INPUT },
111 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
112 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT },
113 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT },
114 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL },
115 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
116 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
117 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
118 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL },
119 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL },
120 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL },
121 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL },
122 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
123 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A), HID_QUIRK_ALWAYS_POLL },
124 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
125 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
126 { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
127 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL },
128 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
129 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
130 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
131 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
132 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
133 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
134 { HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER), HID_QUIRK_MULTI_INPUT },
135 { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL), HID_QUIRK_NO_INIT_REPORTS },
136 { HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD), HID_QUIRK_MULTI_INPUT },
137 { HID_USB_DEVICE(USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD), HID_QUIRK_BADPAD },
138 { HID_USB_DEVICE(USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD), HID_QUIRK_BADPAD },
139 { HID_USB_DEVICE(USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750), HID_QUIRK_NO_INIT_REPORTS },
140 { HID_USB_DEVICE(USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN), HID_QUIRK_MULTI_INPUT},
141 { HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE), HID_QUIRK_NO_INIT_REPORTS },
142 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE), HID_QUIRK_NO_INIT_REPORTS },
143 { HID_USB_DEVICE(USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK), HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
144 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610), HID_QUIRK_NOGET },
145 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640), HID_QUIRK_NOGET },
146 { HID_USB_DEVICE(USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL), HID_QUIRK_HIDINPUT_FORCE },
147 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1), HID_QUIRK_NO_INIT_REPORTS },
148 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2), HID_QUIRK_NO_INIT_REPORTS },
149 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
150 { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
151 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
152 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL },
153 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
154 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
155 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
156 { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
157 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
158 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET },
159 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008), HID_QUIRK_NOGET },
160 { HID_USB_DEVICE(USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER), HID_QUIRK_NO_INIT_REPORTS },
161 { HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPAD), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
162 { HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
163 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD), HID_QUIRK_BADPAD },
164 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
165 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
166 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
167 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
168 { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
169 { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
170 { HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
171 { HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD), HID_QUIRK_NO_INIT_REPORTS },
172 { HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780), HID_QUIRK_NOGET },
173 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH), HID_QUIRK_NOGET },
174 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH), HID_QUIRK_NOGET },
175 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH), HID_QUIRK_NOGET },
176 { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS_TS), HID_QUIRK_NO_INIT_REPORTS },
177 { HID_USB_DEVICE(USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE), HID_QUIRK_NOGET },
178 { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1), HID_QUIRK_NOGET },
179 { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2), HID_QUIRK_NOGET },
180 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD), HID_QUIRK_NO_INIT_REPORTS },
181 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1), HID_QUIRK_NO_INIT_REPORTS },
182 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2), HID_QUIRK_NO_INIT_REPORTS },
183 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD), HID_QUIRK_NO_INIT_REPORTS },
184 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103), HID_QUIRK_NO_INIT_REPORTS },
185 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A), HID_QUIRK_NO_INIT_REPORTS },
186 { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K15A), HID_QUIRK_NO_INIT_REPORTS },
187 { HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD), HID_QUIRK_BADPAD },
188 { HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT },
189 { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET },
190 { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883), HID_QUIRK_NOGET },
191 { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD), HID_QUIRK_NOGET },
192 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT },
193 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT },
194 { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT },
195 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT },
196 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT },
197 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT },
198 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
199 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
200 { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
201 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },
202
203 { 0 }
204 };
205
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
^ permalink raw reply
* [PATCH v3 0/2] platform/x86: Add driver for Yoga Tablet mode switch
From: Andrew Kallmeyer @ 2023-03-29 1:45 UTC (permalink / raw)
To: platform-driver-x86
Cc: Andrew Kallmeyer, Gergo Koteles, Ike Panhc, linux-input,
Hans de Goede, Armin Wolf, Barnabás Pőcze
This driver maps the Lenovo Yoga tablet mode switch to a SW_TABLET_MODE input
device. This will make the tablet status available to desktop environments.
This patch series is the result of the discussion at
https://lore.kernel.org/r/CAG4kvq9US=-NjyXFMzJYu2zCJryJWtOc7FGZbrewpgCDjdAkbg@mail.gmail.com/
I decided to follow-up on the patch Gergo wrote and respond to the review
comments to get it merged and available for everyone.
Gergo and I have tested this on the Yoga 7 14ARB7, and the Yoga 7 14AIL7
respectively. Additionally, according to reports at
https://github.com/lukas-w/yoga-usage-mode, which uses the same WMI devices,
this driver should work with:
Yoga C940, Ideapad flex 14API, Yoga 9 14IAP7, Yoga 7 14ARB7, etc.
v1: https://lore.kernel.org/r/20230310041726.217447-1-kallmeyeras@gmail.com/
v2: https://lore.kernel.org/r/20230323025200.5462-1-kallmeyeras@gmail.com/
The diff since v2 is as follows:
--- a/drivers/platform/x86/lenovo-ymc.c
+++ b/drivers/platform/x86/lenovo-ymc.c
@@ -21,8 +21,8 @@
#define LENOVO_YMC_QUERY_METHOD 0x01
static bool ec_trigger __read_mostly;
-module_param(ec_trigger, bool, 0644);
-MODULE_PARM_DESC(ec_trigger, "Enable EC triggering to emit YMC events");
+module_param(ec_trigger, bool, 0444);
+MODULE_PARM_DESC(ec_trigger, "Enable EC triggering work-around to force emitting tablet mode events");
static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
{
@@ -43,8 +43,7 @@ struct lenovo_ymc_private {
static void lenovo_ymc_trigger_ec(struct wmi_device *wdev, struct lenovo_ymc_private *priv)
{
int err;
-
- if (!ec_trigger || !priv || !priv->ec_acpi_dev)
+ if (!priv->ec_acpi_dev)
return;
err = write_ec_cmd(priv->ec_acpi_dev->handle, VPCCMD_W_YMC, 1);
if (err)
@@ -103,11 +102,7 @@ static void lenovo_ymc_notify(struct wmi_device *wdev, union acpi_object *data)
lenovo_ymc_trigger_ec(wdev, priv);
}
-static void lenovo_ymc_remove(struct wmi_device *wdev)
-{
- struct lenovo_ymc_private *priv = dev_get_drvdata(&wdev->dev);
- acpi_dev_put(priv->ec_acpi_dev);
-}
+static void acpi_dev_put_helper(void *p) { acpi_dev_put(p); }
static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
{
@@ -124,10 +119,18 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
if (ec_trigger) {
pr_debug("Lenovo YMC enable EC triggering.\n");
priv->ec_acpi_dev = acpi_dev_get_first_match_dev("VPC2004", NULL, -1);
+
if (!priv->ec_acpi_dev) {
dev_err(&wdev->dev, "Could not find EC ACPI device.\n");
return -ENODEV;
}
+ err = devm_add_action_or_reset(&wdev->dev,
+ acpi_dev_put_helper, priv->ec_acpi_dev);
+ if (err) {
+ dev_err(&wdev->dev,
+ "Could not clean up EC ACPI device: %d\n", err);
+ return err;
+ }
}
input_dev = devm_input_allocate_device(&wdev->dev);
@@ -138,9 +141,6 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
input_dev->phys = LENOVO_YMC_EVENT_GUID "/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &wdev->dev;
-
- input_set_capability(input_dev, EV_SW, SW_TABLET_MODE);
-
err = sparse_keymap_setup(input_dev, lenovo_ymc_keymap, NULL);
if (err) {
dev_err(&wdev->dev,
@@ -177,7 +177,6 @@ static struct wmi_driver lenovo_ymc_driver = {
.id_table = lenovo_ymc_wmi_id_table,
.probe = lenovo_ymc_probe,
.notify = lenovo_ymc_notify,
- .remove = lenovo_ymc_remove,
};
module_wmi_driver(lenovo_ymc_driver);
Andrew Kallmeyer (1):
platform/x86: Move ideapad ACPI helpers to a new header
Gergo Koteles (1):
platform/x86: Add driver for Yoga Tablet Mode switch
drivers/platform/x86/Kconfig | 10 ++
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/ideapad-laptop.c | 135 +------------------
drivers/platform/x86/ideapad-laptop.h | 152 +++++++++++++++++++++
drivers/platform/x86/lenovo-ymc.c | 185 ++++++++++++++++++++++++++
5 files changed, 349 insertions(+), 134 deletions(-)
create mode 100644 drivers/platform/x86/ideapad-laptop.h
create mode 100644 drivers/platform/x86/lenovo-ymc.c
--
2.40.0
^ permalink raw reply
* [PATCH v3 1/2] platform/x86: Move ideapad ACPI helpers to a new header
From: Andrew Kallmeyer @ 2023-03-29 1:45 UTC (permalink / raw)
To: platform-driver-x86
Cc: Andrew Kallmeyer, Gergo Koteles, Ike Panhc, linux-input,
Hans de Goede, Armin Wolf, Barnabás Pőcze
In-Reply-To: <20230329014559.44494-1-kallmeyeras@gmail.com>
These functions will be used by a driver written by Gergo Koteles to
detect the tablet mode switch in Lenovo Yoga laptops. These changes were
discussed in review of that patch.
This is the minimal set of functions needed in that driver, there are
several more small functions left in the ACPI Helpers section in
ideapad-laptop.c. The only change is the functions are now marked inline
as requested in the review comments.
Signed-off-by: Andrew Kallmeyer <kallmeyeras@gmail.com>
Link: https://lore.kernel.org/r/20221004214332.35934-1-soyer@irl.hu/
---
drivers/platform/x86/ideapad-laptop.c | 135 +----------------------
drivers/platform/x86/ideapad-laptop.h | 151 ++++++++++++++++++++++++++
2 files changed, 152 insertions(+), 134 deletions(-)
create mode 100644 drivers/platform/x86/ideapad-laptop.h
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 0eb5bfdd8..55f56697e 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -20,7 +20,6 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
-#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
@@ -31,6 +30,7 @@
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/wmi.h>
+#include "ideapad-laptop.h"
#include <acpi/video.h>
@@ -85,33 +85,6 @@ enum {
SALS_FNLOCK_OFF = 0xf,
};
-enum {
- VPCCMD_R_VPC1 = 0x10,
- VPCCMD_R_BL_MAX,
- VPCCMD_R_BL,
- VPCCMD_W_BL,
- VPCCMD_R_WIFI,
- VPCCMD_W_WIFI,
- VPCCMD_R_BT,
- VPCCMD_W_BT,
- VPCCMD_R_BL_POWER,
- VPCCMD_R_NOVO,
- VPCCMD_R_VPC2,
- VPCCMD_R_TOUCHPAD,
- VPCCMD_W_TOUCHPAD,
- VPCCMD_R_CAMERA,
- VPCCMD_W_CAMERA,
- VPCCMD_R_3G,
- VPCCMD_W_3G,
- VPCCMD_R_ODD, /* 0x21 */
- VPCCMD_W_FAN,
- VPCCMD_R_RF,
- VPCCMD_W_RF,
- VPCCMD_R_FAN = 0x2B,
- VPCCMD_R_SPECIAL_BUTTONS = 0x31,
- VPCCMD_W_BL_POWER = 0x33,
-};
-
struct ideapad_dytc_priv {
enum platform_profile_option current_profile;
struct platform_profile_handler pprof;
@@ -227,7 +200,6 @@ static void ideapad_shared_exit(struct ideapad_private *priv)
/*
* ACPI Helpers
*/
-#define IDEAPAD_EC_TIMEOUT 200 /* in ms */
static int eval_int(acpi_handle handle, const char *name, unsigned long *res)
{
@@ -270,116 +242,11 @@ static int exec_sals(acpi_handle handle, unsigned long arg)
return exec_simple_method(handle, "SALS", arg);
}
-static int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long arg, unsigned long *res)
-{
- struct acpi_object_list params;
- unsigned long long result;
- union acpi_object in_obj;
- acpi_status status;
-
- params.count = 1;
- params.pointer = &in_obj;
- in_obj.type = ACPI_TYPE_INTEGER;
- in_obj.integer.value = arg;
-
- status = acpi_evaluate_integer(handle, (char *)name, ¶ms, &result);
- if (ACPI_FAILURE(status))
- return -EIO;
-
- if (res)
- *res = result;
-
- return 0;
-}
-
static int eval_dytc(acpi_handle handle, unsigned long cmd, unsigned long *res)
{
return eval_int_with_arg(handle, "DYTC", cmd, res);
}
-static int eval_vpcr(acpi_handle handle, unsigned long cmd, unsigned long *res)
-{
- return eval_int_with_arg(handle, "VPCR", cmd, res);
-}
-
-static int eval_vpcw(acpi_handle handle, unsigned long cmd, unsigned long data)
-{
- struct acpi_object_list params;
- union acpi_object in_obj[2];
- acpi_status status;
-
- params.count = 2;
- params.pointer = in_obj;
- in_obj[0].type = ACPI_TYPE_INTEGER;
- in_obj[0].integer.value = cmd;
- in_obj[1].type = ACPI_TYPE_INTEGER;
- in_obj[1].integer.value = data;
-
- status = acpi_evaluate_object(handle, "VPCW", ¶ms, NULL);
- if (ACPI_FAILURE(status))
- return -EIO;
-
- return 0;
-}
-
-static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *data)
-{
- unsigned long end_jiffies, val;
- int err;
-
- err = eval_vpcw(handle, 1, cmd);
- if (err)
- return err;
-
- end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
-
- while (time_before(jiffies, end_jiffies)) {
- schedule();
-
- err = eval_vpcr(handle, 1, &val);
- if (err)
- return err;
-
- if (val == 0)
- return eval_vpcr(handle, 0, data);
- }
-
- acpi_handle_err(handle, "timeout in %s\n", __func__);
-
- return -ETIMEDOUT;
-}
-
-static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long data)
-{
- unsigned long end_jiffies, val;
- int err;
-
- err = eval_vpcw(handle, 0, data);
- if (err)
- return err;
-
- err = eval_vpcw(handle, 1, cmd);
- if (err)
- return err;
-
- end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
-
- while (time_before(jiffies, end_jiffies)) {
- schedule();
-
- err = eval_vpcr(handle, 1, &val);
- if (err)
- return err;
-
- if (val == 0)
- return 0;
- }
-
- acpi_handle_err(handle, "timeout in %s\n", __func__);
-
- return -ETIMEDOUT;
-}
-
/*
* debugfs
*/
diff --git a/drivers/platform/x86/ideapad-laptop.h b/drivers/platform/x86/ideapad-laptop.h
new file mode 100644
index 000000000..7dd8ce027
--- /dev/null
+++ b/drivers/platform/x86/ideapad-laptop.h
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * ideapad-laptop.h - Lenovo IdeaPad ACPI Extras
+ *
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2010 David Woodhouse <dwmw2@infradead.org>
+ */
+
+#ifndef _IDEAPAD_LAPTOP_H_
+#define _IDEAPAD_LAPTOP_H_
+
+#include <linux/acpi.h>
+#include <linux/jiffies.h>
+#include <linux/errno.h>
+
+enum {
+ VPCCMD_R_VPC1 = 0x10,
+ VPCCMD_R_BL_MAX,
+ VPCCMD_R_BL,
+ VPCCMD_W_BL,
+ VPCCMD_R_WIFI,
+ VPCCMD_W_WIFI,
+ VPCCMD_R_BT,
+ VPCCMD_W_BT,
+ VPCCMD_R_BL_POWER,
+ VPCCMD_R_NOVO,
+ VPCCMD_R_VPC2,
+ VPCCMD_R_TOUCHPAD,
+ VPCCMD_W_TOUCHPAD,
+ VPCCMD_R_CAMERA,
+ VPCCMD_W_CAMERA,
+ VPCCMD_R_3G,
+ VPCCMD_W_3G,
+ VPCCMD_R_ODD, /* 0x21 */
+ VPCCMD_W_FAN,
+ VPCCMD_R_RF,
+ VPCCMD_W_RF,
+ VPCCMD_R_FAN = 0x2B,
+ VPCCMD_R_SPECIAL_BUTTONS = 0x31,
+ VPCCMD_W_BL_POWER = 0x33,
+};
+
+static inline int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long arg, unsigned long *res)
+{
+ struct acpi_object_list params;
+ unsigned long long result;
+ union acpi_object in_obj;
+ acpi_status status;
+
+ params.count = 1;
+ params.pointer = &in_obj;
+ in_obj.type = ACPI_TYPE_INTEGER;
+ in_obj.integer.value = arg;
+
+ status = acpi_evaluate_integer(handle, (char *)name, ¶ms, &result);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ if (res)
+ *res = result;
+
+ return 0;
+}
+
+static inline int eval_vpcr(acpi_handle handle, unsigned long cmd, unsigned long *res)
+{
+ return eval_int_with_arg(handle, "VPCR", cmd, res);
+}
+
+static inline int eval_vpcw(acpi_handle handle, unsigned long cmd, unsigned long data)
+{
+ struct acpi_object_list params;
+ union acpi_object in_obj[2];
+ acpi_status status;
+
+ params.count = 2;
+ params.pointer = in_obj;
+ in_obj[0].type = ACPI_TYPE_INTEGER;
+ in_obj[0].integer.value = cmd;
+ in_obj[1].type = ACPI_TYPE_INTEGER;
+ in_obj[1].integer.value = data;
+
+ status = acpi_evaluate_object(handle, "VPCW", ¶ms, NULL);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
+#define IDEAPAD_EC_TIMEOUT 200 /* in ms */
+
+static inline int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *data)
+{
+ unsigned long end_jiffies, val;
+ int err;
+
+ err = eval_vpcw(handle, 1, cmd);
+ if (err)
+ return err;
+
+ end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
+
+ while (time_before(jiffies, end_jiffies)) {
+ schedule();
+
+ err = eval_vpcr(handle, 1, &val);
+ if (err)
+ return err;
+
+ if (val == 0)
+ return eval_vpcr(handle, 0, data);
+ }
+
+ acpi_handle_err(handle, "timeout in %s\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static inline int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long data)
+{
+ unsigned long end_jiffies, val;
+ int err;
+
+ err = eval_vpcw(handle, 0, data);
+ if (err)
+ return err;
+
+ err = eval_vpcw(handle, 1, cmd);
+ if (err)
+ return err;
+
+ end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
+
+ while (time_before(jiffies, end_jiffies)) {
+ schedule();
+
+ err = eval_vpcr(handle, 1, &val);
+ if (err)
+ return err;
+
+ if (val == 0)
+ return 0;
+ }
+
+ acpi_handle_err(handle, "timeout in %s\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+#undef IDEAPAD_EC_TIMEOUT
+#endif /* !_IDEAPAD_LAPTOP_H_ */
--
2.40.0
^ permalink raw reply related
* [PATCH v3 2/2] platform/x86: Add driver for Yoga Tablet Mode switch
From: Andrew Kallmeyer @ 2023-03-29 1:45 UTC (permalink / raw)
To: platform-driver-x86
Cc: Andrew Kallmeyer, Gergo Koteles, Ike Panhc, linux-input,
Hans de Goede, Armin Wolf, Barnabás Pőcze
In-Reply-To: <20230329014559.44494-1-kallmeyeras@gmail.com>
From: Gergo Koteles <soyer@irl.hu>
This WMI driver for the tablet mode control switch for Lenovo Yoga
notebooks was originally written by Gergo Koteles. The mode is mapped to
a SW_TABLET_MODE switch capable input device.
Andrew followed the suggestions that were posted in reply to Gergo's RFC
patch, and on the v1 & v2 versions of this patch to follow-up and get it
merged.
Changes from Gergo's RFC:
- Refactored obtaining a reference to the EC ACPI device needed for the
quirk implementation as suggested by Hans de Goede
- Applied small fixes and switched to always registering handles with
the driver for automatic cleanup as suggested by Barnabás Pőcze.
- Merged the lenovo_ymc_trigger_ec function with the
ideapad_trigger_ymc_next_read function since it was no longer
external.
- Added the word "Tablet" to the driver description to hopefully make
it more clear.
- Fixed the LENOVO_YMC_QUERY_METHOD ID and the name string for the EC
APCI device trigged for the quirk
- Triggered the input event on probe so that the initial tablet mode
state when the driver is loaded is reported to userspace as suggested
by Armin Wolf.
- Restricted the permissions of the ec_trigger parameter as suggested
by Armin Wolf. Also updated the description.
We have tested this on the Yoga 7 14AIL7 for the non-quirk path and on
the Yoga 7 14ARB7 which has the firmware bug that requires triggering
the embedded controller to send the mode change events. This workaround
is also used by the Windows drivers.
According to reports at https://github.com/lukas-w/yoga-usage-mode,
which uses the same WMI devices, the following models should also work:
Yoga C940, Ideapad flex 14API, Yoga 9 14IAP7, Yoga 7 14ARB7, etc.
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Co-developed-by: Andrew Kallmeyer <kallmeyeras@gmail.com>
Signed-off-by: Andrew Kallmeyer <kallmeyeras@gmail.com>
Link: https://lore.kernel.org/r/20221004214332.35934-1-soyer@irl.hu/
Link: https://lore.kernel.org/r/20230310041726.217447-1-kallmeyeras@gmail.com/
Link: https://lore.kernel.org/r/20230323025200.5462-1-kallmeyeras@gmail.com/
---
drivers/platform/x86/Kconfig | 10 ++
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/ideapad-laptop.h | 1 +
drivers/platform/x86/lenovo-ymc.c | 186 ++++++++++++++++++++++++++
4 files changed, 198 insertions(+)
create mode 100644 drivers/platform/x86/lenovo-ymc.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 5692385e2..858be0c65 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -470,6 +470,16 @@ config IDEAPAD_LAPTOP
This is a driver for Lenovo IdeaPad netbooks contains drivers for
rfkill switch, hotkey, fan control and backlight control.
+config LENOVO_YMC
+ tristate "Lenovo Yoga Tablet Mode Control"
+ depends on ACPI_WMI
+ depends on INPUT
+ depends on IDEAPAD_LAPTOP
+ select INPUT_SPARSEKMAP
+ help
+ This driver maps the Tablet Mode Control switch to SW_TABLET_MODE input
+ events for Lenovo Yoga notebooks.
+
config SENSORS_HDAPS
tristate "Thinkpad Hard Drive Active Protection System (hdaps)"
depends on INPUT
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 1d3d1b025..10054cdea 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_UV_SYSFS) += uv_sysfs.o
# IBM Thinkpad and Lenovo
obj-$(CONFIG_IBM_RTL) += ibm_rtl.o
obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o
+obj-$(CONFIG_LENOVO_YMC) += lenovo-ymc.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_THINKPAD_LMI) += think-lmi.o
diff --git a/drivers/platform/x86/ideapad-laptop.h b/drivers/platform/x86/ideapad-laptop.h
index 7dd8ce027..2564cb1cd 100644
--- a/drivers/platform/x86/ideapad-laptop.h
+++ b/drivers/platform/x86/ideapad-laptop.h
@@ -35,6 +35,7 @@ enum {
VPCCMD_W_FAN,
VPCCMD_R_RF,
VPCCMD_W_RF,
+ VPCCMD_W_YMC = 0x2A,
VPCCMD_R_FAN = 0x2B,
VPCCMD_R_SPECIAL_BUTTONS = 0x31,
VPCCMD_W_BL_POWER = 0x33,
diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c
new file mode 100644
index 000000000..5e520a764
--- /dev/null
+++ b/drivers/platform/x86/lenovo-ymc.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * lenovo-ymc.c - Lenovo Yoga Mode Control driver
+ *
+ * Copyright © 2022 Gergo Koteles <soyer@irl.hu>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/wmi.h>
+#include "ideapad-laptop.h"
+
+#define LENOVO_YMC_EVENT_GUID "06129D99-6083-4164-81AD-F092F9D773A6"
+#define LENOVO_YMC_QUERY_GUID "09B0EE6E-C3FD-4243-8DA1-7911FF80BB8C"
+
+#define LENOVO_YMC_QUERY_INSTANCE 0
+#define LENOVO_YMC_QUERY_METHOD 0x01
+
+static bool ec_trigger __read_mostly;
+module_param(ec_trigger, bool, 0444);
+MODULE_PARM_DESC(ec_trigger, "Enable EC triggering work-around to force emitting tablet mode events");
+
+static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
+ {
+ // Lenovo Yoga 7 14ARB7
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82QF"),
+ },
+ },
+ { },
+};
+
+struct lenovo_ymc_private {
+ struct input_dev *input_dev;
+ struct acpi_device *ec_acpi_dev;
+};
+
+static void lenovo_ymc_trigger_ec(struct wmi_device *wdev, struct lenovo_ymc_private *priv)
+{
+ int err;
+ if (!priv->ec_acpi_dev)
+ return;
+ err = write_ec_cmd(priv->ec_acpi_dev->handle, VPCCMD_W_YMC, 1);
+ if (err)
+ dev_warn(&wdev->dev, "Could not write YMC: %d\n", err);
+}
+
+static const struct key_entry lenovo_ymc_keymap[] = {
+ // Laptop
+ { KE_SW, 0x01, { .sw = { SW_TABLET_MODE, 0 } } },
+ // Tablet
+ { KE_SW, 0x02, { .sw = { SW_TABLET_MODE, 1 } } },
+ // Drawing Board
+ { KE_SW, 0x03, { .sw = { SW_TABLET_MODE, 1 } } },
+ // Tent
+ { KE_SW, 0x04, { .sw = { SW_TABLET_MODE, 1 } } },
+ { KE_END },
+};
+
+static void lenovo_ymc_notify(struct wmi_device *wdev, union acpi_object *data)
+{
+ struct lenovo_ymc_private *priv = dev_get_drvdata(&wdev->dev);
+
+ u32 input_val = 0;
+ struct acpi_buffer input = {sizeof(input_val), &input_val};
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_status status;
+ union acpi_object *obj;
+ int code;
+
+ status = wmi_evaluate_method(LENOVO_YMC_QUERY_GUID,
+ LENOVO_YMC_QUERY_INSTANCE,
+ LENOVO_YMC_QUERY_METHOD,
+ &input, &output);
+
+ if (ACPI_FAILURE(status)) {
+ dev_warn(&wdev->dev,
+ "Failed to evaluate query method: %s\n",
+ acpi_format_exception(status));
+ return;
+ }
+
+ obj = output.pointer;
+
+ if (obj->type != ACPI_TYPE_INTEGER) {
+ dev_warn(&wdev->dev,
+ "WMI event data is not an integer\n");
+ goto free_obj;
+ }
+ code = obj->integer.value;
+
+ if (!sparse_keymap_report_event(priv->input_dev, code, 1, true))
+ dev_warn(&wdev->dev, "Unknown key %d pressed\n", code);
+
+free_obj:
+ kfree(obj);
+ lenovo_ymc_trigger_ec(wdev, priv);
+}
+
+static void acpi_dev_put_helper(void *p) { acpi_dev_put(p); }
+
+static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
+{
+ struct input_dev *input_dev;
+ struct lenovo_ymc_private *priv;
+ int err;
+
+ ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table);
+
+ priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (ec_trigger) {
+ pr_debug("Lenovo YMC enable EC triggering.\n");
+ priv->ec_acpi_dev = acpi_dev_get_first_match_dev("VPC2004", NULL, -1);
+
+ if (!priv->ec_acpi_dev) {
+ dev_err(&wdev->dev, "Could not find EC ACPI device.\n");
+ return -ENODEV;
+ }
+ err = devm_add_action_or_reset(&wdev->dev,
+ acpi_dev_put_helper, priv->ec_acpi_dev);
+ if (err) {
+ dev_err(&wdev->dev,
+ "Could not clean up EC ACPI device: %d\n", err);
+ return err;
+ }
+ }
+
+ input_dev = devm_input_allocate_device(&wdev->dev);
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "Lenovo Yoga Tablet Mode Control switch";
+ input_dev->phys = LENOVO_YMC_EVENT_GUID "/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &wdev->dev;
+ err = sparse_keymap_setup(input_dev, lenovo_ymc_keymap, NULL);
+ if (err) {
+ dev_err(&wdev->dev,
+ "Could not set up input device keymap: %d\n", err);
+ return err;
+ }
+
+ err = input_register_device(input_dev);
+ if (err) {
+ dev_err(&wdev->dev,
+ "Could not register input device: %d\n", err);
+ return err;
+ }
+
+ priv->input_dev = input_dev;
+ dev_set_drvdata(&wdev->dev, priv);
+
+ // Report the state for the first time on probe
+ lenovo_ymc_trigger_ec(wdev, priv);
+ lenovo_ymc_notify(wdev, NULL);
+ return 0;
+}
+
+static const struct wmi_device_id lenovo_ymc_wmi_id_table[] = {
+ { .guid_string = LENOVO_YMC_EVENT_GUID },
+ { }
+};
+MODULE_DEVICE_TABLE(wmi, lenovo_ymc_wmi_id_table);
+
+static struct wmi_driver lenovo_ymc_driver = {
+ .driver = {
+ .name = "lenovo-ymc",
+ },
+ .id_table = lenovo_ymc_wmi_id_table,
+ .probe = lenovo_ymc_probe,
+ .notify = lenovo_ymc_notify,
+};
+
+module_wmi_driver(lenovo_ymc_driver);
+
+MODULE_AUTHOR("Gergo Koteles <soyer@irl.hu>");
+MODULE_DESCRIPTION("Lenovo Yoga Mode Control driver");
+MODULE_LICENSE("GPL");
--
2.40.0
^ permalink raw reply related
* Re: [PATCH v2] Input: touchscreen - Add new Novatek NVT-ts driver
From: Jeff LaBundy @ 2023-03-29 1:47 UTC (permalink / raw)
To: Hans de Goede; +Cc: Dmitry Torokhov, linux-input
In-Reply-To: <20230326212308.55730-1-hdegoede@redhat.com>
On Sun, Mar 26, 2023 at 11:23:08PM +0200, Hans de Goede wrote:
> Add a new driver for the Novatek i2c touchscreen controller as found
> on the Acer Iconia One 7 B1-750 tablet. Unfortunately the touchscreen
> controller model-number is unknown. Even with the tablet opened up it
> is impossible to read the model-number.
>
> Android calls this a "NVT-ts" touchscreen, but that may apply to other
> Novatek controller models too.
>
> This appears to be the same controller as the one supported by
> https://github.com/advx9600/android/blob/master/touchscreen/NVTtouch_Android4.0/NVTtouch.c
> but unfortunately that does not give us a model-number either.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Jeff LaBundy <jeff@labundy.com>
> ---
> MAINTAINERS | 6 +
> drivers/input/touchscreen/Kconfig | 10 +
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/novatek-nvt-ts.c | 289 +++++++++++++++++++++
> 4 files changed, 306 insertions(+)
> create mode 100644 drivers/input/touchscreen/novatek-nvt-ts.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 08b7178d645b..30b57a4afe9e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14788,6 +14788,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
> F: tools/include/nolibc/
> F: tools/testing/selftests/nolibc/
>
> +NOVATEK NVT-TS I2C TOUCHSCREEN DRIVER
> +M: Hans de Goede <hdegoede@redhat.com>
> +L: linux-input@vger.kernel.org
> +S: Maintained
> +F: drivers/input/touchscreen/novatek-nvt-ts.c
> +
> NSDEPS
> M: Matthias Maennich <maennich@google.com>
> S: Maintained
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 1a2049b336a6..1feecd7ed3cb 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -654,6 +654,16 @@ config TOUCHSCREEN_MTOUCH
> To compile this driver as a module, choose M here: the
> module will be called mtouch.
>
> +config TOUCHSCREEN_NOVATEK_NVT_TS
> + tristate "Novatek NVT-ts touchscreen support"
> + depends on I2C
> + help
> + Say Y here if you have a Novatek NVT-ts touchscreen.
> + If unsure, say N.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called novatek-nvt-ts.
> +
> config TOUCHSCREEN_IMAGIS
> tristate "Imagis touchscreen support"
> depends on I2C
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index f2fd28cc34a6..159cd5136fdb 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o
> obj-$(CONFIG_TOUCHSCREEN_MSG2638) += msg2638.o
> obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
> obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
> +obj-$(CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS) += novatek-nvt-ts.o
> obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
> obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
> obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o
> diff --git a/drivers/input/touchscreen/novatek-nvt-ts.c b/drivers/input/touchscreen/novatek-nvt-ts.c
> new file mode 100644
> index 000000000000..f959e7b14ad6
> --- /dev/null
> +++ b/drivers/input/touchscreen/novatek-nvt-ts.c
> @@ -0,0 +1,289 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Driver for Novatek i2c touchscreen controller as found on
> + * the Acer Iconia One 7 B1-750 tablet. The Touchscreen controller
> + * model-number is unknown. Android calls this a "NVT-ts" touchscreen,
> + * but that may apply to other Novatek controller models too.
> + *
> + * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/interrupt.h>
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/module.h>
> +
> +#include <asm/unaligned.h>
> +
> +#define NVT_TS_TOUCH_START 0x00
> +#define NVT_TS_TOUCH_SIZE 6
> +
> +#define NVT_TS_PARAMETERS_START 0x78
> +/* These are offsets from NVT_TS_PARAMETERS_START */
> +#define NVT_TS_PARAMS_WIDTH 0x04
> +#define NVT_TS_PARAMS_HEIGHT 0x06
> +#define NVT_TS_PARAMS_MAX_TOUCH 0x09
> +#define NVT_TS_PARAMS_MAX_BUTTONS 0x0a
> +#define NVT_TS_PARAMS_IRQ_TYPE 0x0b
> +#define NVT_TS_PARAMS_WAKE_TYPE 0x0c
> +#define NVT_TS_PARAMS_CHIP_ID 0x0e
> +#define NVT_TS_PARAMS_SIZE 0x0f
> +
> +#define NVT_TS_SUPPORTED_WAKE_TYPE 0x05
> +#define NVT_TS_SUPPORTED_CHIP_ID 0x05
> +
> +#define NVT_TS_MAX_TOUCHES 10
> +#define NVT_TS_MAX_SIZE 4096
> +
> +#define NVT_TS_TOUCH_INVALID 0xff
> +#define NVT_TS_TOUCH_SLOT_SHIFT 3
> +#define NVT_TS_TOUCH_TYPE_MASK GENMASK(2, 0)
> +#define NVT_TS_TOUCH_NEW 1
> +#define NVT_TS_TOUCH_UPDATE 2
> +#define NVT_TS_TOUCH_RELEASE 3
> +
> +static const int nvt_ts_irq_type[4] = {
> + IRQF_TRIGGER_RISING,
> + IRQF_TRIGGER_FALLING,
> + IRQF_TRIGGER_LOW,
> + IRQF_TRIGGER_HIGH
> +};
> +
> +struct nvt_ts_data {
> + struct i2c_client *client;
> + struct input_dev *input;
> + struct gpio_desc *reset_gpio;
> + struct touchscreen_properties prop;
> + int max_touches;
> + u8 buf[NVT_TS_TOUCH_SIZE * NVT_TS_MAX_TOUCHES];
> +};
> +
> +static int nvt_ts_read_data(struct i2c_client *client, u8 reg, u8 *data, int count)
> +{
> + struct i2c_msg msg[2] = {
> + {
> + .addr = client->addr,
> + .len = 1,
> + .buf = ®,
> + },
> + {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .len = count,
> + .buf = data,
> + }
> + };
> + int ret;
> +
> + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
> + if (ret != ARRAY_SIZE(msg)) {
> + dev_err(&client->dev, "Error reading from 0x%02x: %d\n", reg, ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> +
> + return 0;
> +}
> +
> +static irqreturn_t nvt_ts_irq(int irq, void *dev_id)
> +{
> + struct nvt_ts_data *data = dev_id;
> + struct device *dev = &data->client->dev;
> + int i, error, slot, x, y;
> + bool active;
> + u8 *touch;
> +
> + error = nvt_ts_read_data(data->client, NVT_TS_TOUCH_START, data->buf,
> + data->max_touches * NVT_TS_TOUCH_SIZE);
> + if (error)
> + return IRQ_HANDLED;
> +
> + for (i = 0; i < data->max_touches; i++) {
> + touch = &data->buf[i * NVT_TS_TOUCH_SIZE];
> +
> + if (touch[0] == NVT_TS_TOUCH_INVALID)
> + continue;
> +
> + slot = touch[0] >> NVT_TS_TOUCH_SLOT_SHIFT;
> + if (slot < 1 || slot > data->max_touches) {
> + dev_warn(dev, "slot %d out of range, ignoring\n", slot);
> + continue;
> + }
> +
> + switch (touch[0] & NVT_TS_TOUCH_TYPE_MASK) {
> + case NVT_TS_TOUCH_NEW:
> + case NVT_TS_TOUCH_UPDATE:
> + active = true;
> + break;
> + case NVT_TS_TOUCH_RELEASE:
> + active = false;
> + break;
> + default:
> + dev_warn(dev, "slot %d unknown state %d\n", slot, touch[0] & 7);
> + continue;
> + }
> +
> + slot--;
> + x = (touch[1] << 4) | (touch[3] >> 4);
> + y = (touch[2] << 4) | (touch[3] & 0x0f);
> +
> + input_mt_slot(data->input, slot);
> + input_mt_report_slot_state(data->input, MT_TOOL_FINGER, active);
> + touchscreen_report_pos(data->input, &data->prop, x, y, true);
> + }
> +
> + input_mt_sync_frame(data->input);
> + input_sync(data->input);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int nvt_ts_start(struct input_dev *dev)
> +{
> + struct nvt_ts_data *data = input_get_drvdata(dev);
> +
> + enable_irq(data->client->irq);
> + gpiod_set_value_cansleep(data->reset_gpio, 0);
> +
> + return 0;
> +}
> +
> +static void nvt_ts_stop(struct input_dev *dev)
> +{
> + struct nvt_ts_data *data = input_get_drvdata(dev);
> +
> + disable_irq(data->client->irq);
> + gpiod_set_value_cansleep(data->reset_gpio, 1);
> +}
> +
> +static int nvt_ts_suspend(struct device *dev)
> +{
> + struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev));
> +
> + mutex_lock(&data->input->mutex);
> + if (input_device_enabled(data->input))
> + nvt_ts_stop(data->input);
> + mutex_unlock(&data->input->mutex);
> +
> + return 0;
> +}
> +
> +static int nvt_ts_resume(struct device *dev)
> +{
> + struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev));
> +
> + mutex_lock(&data->input->mutex);
> + if (input_device_enabled(data->input))
> + nvt_ts_start(data->input);
> + mutex_unlock(&data->input->mutex);
> +
> + return 0;
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(nvt_ts_pm_ops, nvt_ts_suspend, nvt_ts_resume);
> +
> +static int nvt_ts_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + int error, width, height, irq_type;
> + struct nvt_ts_data *data;
> + struct input_dev *input;
> +
> + if (!client->irq) {
> + dev_err(dev, "Error no irq specified\n");
> + return -EINVAL;
> + }
> +
> + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->client = client;
> + i2c_set_clientdata(client, data);
> +
> + data->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(data->reset_gpio))
> + return dev_err_probe(dev, PTR_ERR(data->reset_gpio), "requesting reset GPIO\n");
> +
> + /* Wait for controller to come out of reset before params read */
> + msleep(100);
> + error = nvt_ts_read_data(data->client, NVT_TS_PARAMETERS_START, data->buf,
> + NVT_TS_PARAMS_SIZE);
> + gpiod_set_value_cansleep(data->reset_gpio, 1); /* Put back in reset */
> + if (error)
> + return error;
> +
> + width = get_unaligned_be16(&data->buf[NVT_TS_PARAMS_WIDTH]);
> + height = get_unaligned_be16(&data->buf[NVT_TS_PARAMS_HEIGHT]);
> + data->max_touches = data->buf[NVT_TS_PARAMS_MAX_TOUCH];
> + irq_type = data->buf[NVT_TS_PARAMS_IRQ_TYPE];
> +
> + if (width > NVT_TS_MAX_SIZE || height >= NVT_TS_MAX_SIZE ||
> + data->max_touches > NVT_TS_MAX_TOUCHES ||
> + irq_type >= ARRAY_SIZE(nvt_ts_irq_type) ||
> + data->buf[NVT_TS_PARAMS_WAKE_TYPE] != NVT_TS_SUPPORTED_WAKE_TYPE ||
> + data->buf[NVT_TS_PARAMS_CHIP_ID] != NVT_TS_SUPPORTED_CHIP_ID) {
> + dev_err(dev, "Unsupported touchscreen parameters: %*ph\n",
> + NVT_TS_PARAMS_SIZE, data->buf);
> + return -EIO;
> + }
> +
> + dev_dbg(dev, "Detected %dx%d touchscreen with %d max touches\n",
> + width, height, data->max_touches);
> +
> + if (data->buf[NVT_TS_PARAMS_MAX_BUTTONS])
> + dev_warn(dev, "Touchscreen buttons are not supported\n");
> +
> + input = devm_input_allocate_device(dev);
> + if (!input)
> + return -ENOMEM;
> +
> + input->name = client->name;
> + input->id.bustype = BUS_I2C;
> + input->open = nvt_ts_start;
> + input->close = nvt_ts_stop;
> +
> + input_set_abs_params(input, ABS_MT_POSITION_X, 0, width - 1, 0, 0);
> + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, height - 1, 0, 0);
> + touchscreen_parse_properties(input, true, &data->prop);
> +
> + error = input_mt_init_slots(input, data->max_touches,
> + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
> + if (error)
> + return error;
> +
> + data->input = input;
> + input_set_drvdata(input, data);
> +
> + error = devm_request_threaded_irq(dev, client->irq, NULL, nvt_ts_irq,
> + IRQF_ONESHOT | IRQF_NO_AUTOEN | nvt_ts_irq_type[irq_type],
> + client->name, data);
> + if (error)
> + return dev_err_probe(dev, error, "requesting irq\n");
> +
> + return input_register_device(input);
> +}
> +
> +static const struct i2c_device_id nvt_ts_i2c_id[] = {
> + { "NVT-ts" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, nvt_ts_i2c_id);
> +
> +static struct i2c_driver nvt_ts_driver = {
> + .driver = {
> + .name = "novatek-nvt-ts",
> + .pm = pm_sleep_ptr(&nvt_ts_pm_ops),
> + },
> + .probe_new = nvt_ts_probe,
> + .id_table = nvt_ts_i2c_id,
> +};
> +
> +module_i2c_driver(nvt_ts_driver);
> +
> +MODULE_DESCRIPTION("Novatek NVT-ts touchscreen driver");
> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.39.1
>
^ permalink raw reply
* Re: [PATCH] Input: iqs62x-keys - Suppress duplicated error message in .remove()
From: Jeff LaBundy @ 2023-03-29 2:00 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Mattijs Korpershoek, Dmitry Torokhov, kernel, linux-input
In-Reply-To: <20230328060829.tqu367vf3ewgiz6j@pengutronix.de>
Hi Uwe,
Thank you for this additional background information.
On Tue, Mar 28, 2023 at 08:08:29AM +0200, Uwe Kleine-König wrote:
> Hello Jeff,
>
> On Mon, Mar 27, 2023 at 06:27:24PM -0500, Jeff LaBundy wrote:
> > On Sat, Mar 18, 2023 at 11:51:10PM +0100, Uwe Kleine-König wrote:
> > > If a platform driver's remove callback returns non-zero the driver core
> > > emits an error message. In such a case however iqs62x_keys_remove()
> > > already issued a (better) message. So return zero to suppress the
> > > generic message.
> > >
> > > This patch has no other side effects as platform_remove() ignores the
> > > return value of .remove() after the warning.
> > >
> > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> >
> > I was traveling all last week, and therefore unable to voice my opposition
> > in time. However, I figured I would still provide my feedback in case this
> > change may be proposed for other cases.
>
> It is.
>
> > > ---
> > > drivers/input/keyboard/iqs62x-keys.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/input/keyboard/iqs62x-keys.c b/drivers/input/keyboard/iqs62x-keys.c
> > > index db793a550c25..02ceebad7bda 100644
> > > --- a/drivers/input/keyboard/iqs62x-keys.c
> > > +++ b/drivers/input/keyboard/iqs62x-keys.c
> > > @@ -320,7 +320,7 @@ static int iqs62x_keys_remove(struct platform_device *pdev)
> > > if (ret)
> > > dev_err(&pdev->dev, "Failed to unregister notifier: %d\n", ret);
> > >
> > > - return ret;
> > > + return 0;
> >
> > In my opinion, we should never silence a function's return value, especially
> > in service of what is ultimately innocuous and cosmetic in nature. While this
> > specific example is harmless today, the caller can change and hence should be
> > the only instance who decides whether the return value is important.
>
> The caller will change. Today the caller (i.e. platform_remove()) looks
> as follows:
>
> ... if (drv->remove) {
> int ret = drv->remove(dev);
>
> if (ret)
> dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n");
> }
>
> (so ret isn't used later any more). And I eventually will do
>
> struct platform_driver {
> ...
> - int (*remove)(struct platform_device *);
> + void (*remove)(struct platform_device *);
> ...
> }
>
> and change platform_remove() to just:
>
> if (drv->remove)
> drv->remove(dev);
>
> The change in question is a preparation for that.
In that case, this change seems perfectly reasonable; although your
ultimate intention would have been useful to include in the commit
message. Of course, I could have also bothered to read the statement
in platform_remove() and it would have been obvious ;)
>
> The reason I tackle that is that .remove() returning an int seduces
> driver authors to exit early in .remove() in the expectation that there
> is error handling in the core (which there isn't).
>
> See
>
> https://lore.kernel.org/linux-spi/20230317084232.142257-3-u.kleine-koenig@pengutronix.de
>
> for such an issue.
Fair enough, I would have also been fine with simply converting this
function to void straight away as part of your impending wider change.
>
> > If having both fine and subsequently coarse print statements is unacceptable,
> > I would have preferred to drop this driver's print statement and continue to
> > return ret. Or at the very least, include a comment as to why we deliberately
> > ignore the return value.
>
> I have a patch series in the queue that will convert all drivers in
> drivers/input to .remove_new(). (See
> https://lore.kernel.org/linux-media/20230326143224.572654-9-u.kleine-koenig@pengutronix.de
> for an example of such a conversion.) If we add such a comment now, I
> will probably miss to adapt it then.
I don't think a comment is necessary anymore given this is not this
driver's final state. I was moreso concerned that someone later would
identify this as a bug and attempt to change it back.
>
> So I'm still convinced the patch I did is the right thing to do.
Based on our discussion, I no longer have any objection.
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |
Kind regards,
Jeff LaBundy
^ permalink raw reply
* [REGRESSION] wrong coord from Thinkpad TrackPoint since 6.2 kernel
From: Takashi Iwai @ 2023-03-29 8:16 UTC (permalink / raw)
To: Pali Rohár, Dmitry Torokhov; +Cc: regressions, linux-input, linux-kernel
Hi,
we've received a bug report about Thinkpad TrackPoint (ALPS DualPoint
Stick) on 6.2 kernel:
https://bugzilla.opensuse.org/show_bug.cgi?id=1209805
The device reports the wrong values as the movements, e.g. sometimes a
value such as 255, 254 or -255 is returned while usually it should be
a smaller value like -1 or 2.
The evtest on 6.2.x kernel shows the wrong values like:
Event: time 1680037542.898747, type 2 (EV_REL), code 0 (REL_X), value 255
Event: time 1680037542.898747, -------------- SYN_REPORT ------------
Event: time 1680037543.145196, type 2 (EV_REL), code 0 (REL_X), value 1
Event: time 1680037543.145196, -------------- SYN_REPORT ------------
Event: time 1680037543.175087, type 2 (EV_REL), code 1 (REL_Y), value -255
Event: time 1680037543.175087, -------------- SYN_REPORT ------------
Event: time 1680037543.185421, type 2 (EV_REL), code 0 (REL_X), value 1
Event: time 1680037543.185421, type 2 (EV_REL), code 1 (REL_Y), value -255
Event: time 1680037543.185421, -------------- SYN_REPORT ------------
while 6.1.x kernel shows the correct values like:
Event: time 1680037386.318058, type 2 (EV_REL), code 0 (REL_X), value -1
Event: time 1680037386.318058, type 2 (EV_REL), code 1 (REL_Y), value -1
Event: time 1680037386.318058, -------------- SYN_REPORT ------------
Event: time 1680037386.328087, type 2 (EV_REL), code 0 (REL_X), value -1
Event: time 1680037386.328087, type 2 (EV_REL), code 1 (REL_Y), value -1
Event: time 1680037386.328087, -------------- SYN_REPORT ------------
Event: time 1680037386.338046, type 2 (EV_REL), code 0 (REL_X), value -1
Event: time 1680037386.338046, type 2 (EV_REL), code 1 (REL_Y), value -2
Event: time 1680037386.338046, -------------- SYN_REPORT ------------
I couldn't see any relevant changes in alps.c between those versions,
so this is likely a breakage in a lower layer.
Could you guys take a look?
Thanks!
Takashi
^ permalink raw reply
* Re: [PATCH 3/6] devicetree: input: cypress,tt21000: fix interrupt type in dts example
From: Linus Walleij @ 2023-03-29 8:43 UTC (permalink / raw)
To: Maximilian Weigand
Cc: Dmitry Torokhov, linux-input, linux-kernel, devicetree,
Alistair Francis
In-Reply-To: <20230323135205.1160879-4-mweigand@mweigand.net>
On Thu, Mar 23, 2023 at 2:52 PM Maximilian Weigand
<mweigand@mweigand.net> wrote:
> Triggering the interrupt of the IRQ_TYPE_LEVEL_LOW type can lead to
> probing issues with the device for the current driver (encountered on
> the Pine64 PineNote). Basically the interrupt would be triggered before
> certain commands were sent to the device, leading to a race between the
> device responding fast enough and the irq handler fetching a data frame
> from it. Actually all devices currently using the driver already use a
> falling edge trigger.
>
> Signed-off-by: Maximilian Weigand <mweigand@mweigand.net>
> Reviewed-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 5/6] devicetree: input: cypress,tt21000: add wakeup-source entry to documentation
From: Linus Walleij @ 2023-03-29 8:43 UTC (permalink / raw)
To: Maximilian Weigand
Cc: Dmitry Torokhov, linux-input, linux-kernel, devicetree,
Alistair Francis
In-Reply-To: <20230323135205.1160879-6-mweigand@mweigand.net>
On Thu, Mar 23, 2023 at 2:52 PM Maximilian Weigand
<mweigand@mweigand.net> wrote:
> The touchscreen can be used to wake up systems from sleep and therefore
> the wakeup-source entry should be included in the documentation.
>
> Signed-off-by: Maximilian Weigand <mweigand@mweigand.net>
> Reviewed-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [REGRESSION] wrong coord from Thinkpad TrackPoint since 6.2 kernel
From: Hans de Goede @ 2023-03-29 9:22 UTC (permalink / raw)
To: Takashi Iwai, Pali Rohár, Dmitry Torokhov
Cc: regressions, linux-input, linux-kernel
In-Reply-To: <87h6u4otuc.wl-tiwai@suse.de>
Hi Takashi,
On 3/29/23 10:16, Takashi Iwai wrote:
> Hi,
>
> we've received a bug report about Thinkpad TrackPoint (ALPS DualPoint
> Stick) on 6.2 kernel:
> https://bugzilla.opensuse.org/show_bug.cgi?id=1209805
>
> The device reports the wrong values as the movements, e.g. sometimes a
> value such as 255, 254 or -255 is returned while usually it should be
> a smaller value like -1 or 2.
>
> The evtest on 6.2.x kernel shows the wrong values like:
>
> Event: time 1680037542.898747, type 2 (EV_REL), code 0 (REL_X), value 255
> Event: time 1680037542.898747, -------------- SYN_REPORT ------------
> Event: time 1680037543.145196, type 2 (EV_REL), code 0 (REL_X), value 1
> Event: time 1680037543.145196, -------------- SYN_REPORT ------------
> Event: time 1680037543.175087, type 2 (EV_REL), code 1 (REL_Y), value -255
> Event: time 1680037543.175087, -------------- SYN_REPORT ------------
> Event: time 1680037543.185421, type 2 (EV_REL), code 0 (REL_X), value 1
> Event: time 1680037543.185421, type 2 (EV_REL), code 1 (REL_Y), value -255
> Event: time 1680037543.185421, -------------- SYN_REPORT ------------
>
> while 6.1.x kernel shows the correct values like:
>
> Event: time 1680037386.318058, type 2 (EV_REL), code 0 (REL_X), value -1
> Event: time 1680037386.318058, type 2 (EV_REL), code 1 (REL_Y), value -1
> Event: time 1680037386.318058, -------------- SYN_REPORT ------------
> Event: time 1680037386.328087, type 2 (EV_REL), code 0 (REL_X), value -1
> Event: time 1680037386.328087, type 2 (EV_REL), code 1 (REL_Y), value -1
> Event: time 1680037386.328087, -------------- SYN_REPORT ------------
> Event: time 1680037386.338046, type 2 (EV_REL), code 0 (REL_X), value -1
> Event: time 1680037386.338046, type 2 (EV_REL), code 1 (REL_Y), value -2
> Event: time 1680037386.338046, -------------- SYN_REPORT ------------
>
> I couldn't see any relevant changes in alps.c between those versions,
> so this is likely a breakage in a lower layer.
>
> Could you guys take a look?
I believe this is caused by the kernel now using -funsigned-char
everywhere and this should be fixed by this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=for-linus&id=754ff5060daf5a1cf4474eff9b4edeb6c17ef7ab
And there is a similar issue in the focaltech touchpad driver:
https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=for-linus&id=8980f190947ba29f23110408e712444884b74251
Dmitry, since this is hitting 6.2 users, perhaps you can send
a pull-req for your current for-linus branch to get the fix
on its way to stable ?
Regards,
Hans
^ permalink raw reply
* [PATCH] Input: Add KUnit tests for some of the input core helper functions
From: Javier Martinez Canillas @ 2023-03-29 9:23 UTC (permalink / raw)
To: linux-kernel
Cc: Brendan Higgins, Maxime Ripard, linux-kselftest,
Enric Balletbo i Serra, David Gow, kunit-dev,
Javier Martinez Canillas, Dmitry Torokhov, linux-input
The input subsystem doesn't currently have any unit tests, let's add a
CONFIG_INPUT_KUNIT_TEST option that builds a test suite to be executed
with the KUnit test infrastructure.
For now, only three tests were added for some of the input core helper
functions that are trivial to test:
* input_test_polling: set/get poll interval and set-up a poll handler.
* input_test_timestamp: set/get input event timestamps.
* input_test_match_device_id: match a device by bus, vendor, product
and events that is capable of handling.
But having the minimal KUnit support allows to add more tests and suites
as follow-up changes. The tests can be run with the following command:
$ ./tools/testing/kunit/kunit.py run \
--kunitconfig=drivers/input/tests/.kunitconfig
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
drivers/input/Kconfig | 12 +++
drivers/input/Makefile | 1 +
drivers/input/tests/Makefile | 3 +
drivers/input/tests/input_test.c | 144 +++++++++++++++++++++++++++++++
4 files changed, 160 insertions(+)
create mode 100644 drivers/input/tests/Makefile
create mode 100644 drivers/input/tests/input_test.c
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index e2752f7364bc..e094e5bbaa0c 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -166,6 +166,18 @@ config INPUT_EVBUG
To compile this driver as a module, choose M here: the
module will be called evbug.
+config INPUT_KUNIT_TEST
+ tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS
+ depends on INPUT && KUNIT=y
+ default KUNIT_ALL_TESTS
+ help
+ Say Y here if you want to build the KUnit tests for the input
+ subsystem. For more information about KUnit and unit tests in
+ general, please refer to the KUnit documentation in
+ Documentation/dev-tools/kunit/.
+
+ If in doubt, say "N".
+
config INPUT_APMPOWER
tristate "Input Power Event -> APM Bridge" if EXPERT
depends on INPUT && APM_EMULATION
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 2266c7d010ef..c78753274921 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
+obj-$(CONFIG_INPUT_KUNIT_TEST) += tests/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
diff --git a/drivers/input/tests/Makefile b/drivers/input/tests/Makefile
new file mode 100644
index 000000000000..90cf954181bc
--- /dev/null
+++ b/drivers/input/tests/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o
diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c
new file mode 100644
index 000000000000..25bbf51b5c87
--- /dev/null
+++ b/drivers/input/tests/input_test.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for the input core.
+ *
+ * Copyright (c) 2023 Red Hat Inc
+ */
+
+#include <linux/delay.h>
+#include <linux/input.h>
+
+#include <kunit/test.h>
+
+#define POLL_INTERVAL 100
+
+static int input_test_init(struct kunit *test)
+{
+ struct input_dev *input_dev;
+ int ret;
+
+ input_dev = input_allocate_device();
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev);
+
+ input_dev->name = "Test input device";
+ input_dev->id.bustype = BUS_VIRTUAL;
+ input_dev->id.vendor = 1;
+ input_dev->id.product = 1;
+ input_dev->id.version = 1;
+ input_set_capability(input_dev, EV_KEY, BTN_LEFT);
+ input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
+
+ ret = input_register_device(input_dev);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ test->priv = input_dev;
+
+ return 0;
+}
+
+static void input_test_exit(struct kunit *test)
+{
+ struct input_dev *input_dev = test->priv;
+
+ input_unregister_device(input_dev);
+}
+
+static void input_test_poll(struct input_dev *input) { }
+
+static void input_test_polling(struct kunit *test)
+{
+ struct input_dev *input_dev = test->priv;
+ int ret;
+
+ ret = input_get_poll_interval(input_dev);
+ KUNIT_ASSERT_EQ(test, ret, -EINVAL);
+
+ ret = input_setup_polling(input_dev, input_test_poll);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ input_set_poll_interval(input_dev, POLL_INTERVAL);
+
+ ret = input_get_poll_interval(input_dev);
+ KUNIT_ASSERT_EQ(test, ret, POLL_INTERVAL);
+}
+
+static void input_test_timestamp(struct kunit *test)
+{
+ const ktime_t invalid_timestamp = ktime_set(0, 0);
+ struct input_dev *input_dev = test->priv;
+ ktime_t *timestamp, time;
+ int ret;
+
+ timestamp = input_get_timestamp(input_dev);
+ time = timestamp[INPUT_CLK_MONO];
+
+ ret = ktime_compare(time, invalid_timestamp);
+ KUNIT_ASSERT_EQ(test, ret, 1);
+
+ time = ktime_get();
+ input_set_timestamp(input_dev, time);
+
+ timestamp = input_get_timestamp(input_dev);
+ KUNIT_ASSERT_EQ(test, ktime_compare(timestamp[INPUT_CLK_MONO],
+ time), 0);
+}
+
+static void input_test_match_device_id(struct kunit *test)
+{
+ struct input_dev *input_dev = test->priv;
+ struct input_device_id id;
+
+ id.flags = INPUT_DEVICE_ID_MATCH_BUS;
+ id.bustype = BUS_VIRTUAL;
+ KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
+
+ id.bustype = BUS_I2C;
+ KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+
+ id.flags = INPUT_DEVICE_ID_MATCH_VENDOR;
+ id.vendor = 1;
+ KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
+
+ id.vendor = 2;
+ KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+
+ id.flags = INPUT_DEVICE_ID_MATCH_PRODUCT;
+ id.product = 1;
+ KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
+
+ id.product = 2;
+ KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+
+ id.flags = INPUT_DEVICE_ID_MATCH_VERSION;
+ id.version = 1;
+ KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
+
+ id.version = 2;
+ KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+
+ id.flags = INPUT_DEVICE_ID_MATCH_EVBIT;
+ __set_bit(EV_KEY, id.evbit);
+ KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
+
+ __set_bit(EV_ABS, id.evbit);
+ KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+}
+
+static struct kunit_case input_tests[] = {
+ KUNIT_CASE(input_test_polling),
+ KUNIT_CASE(input_test_timestamp),
+ KUNIT_CASE(input_test_match_device_id),
+ { /* sentinel */ }
+};
+
+static struct kunit_suite input_test_suite = {
+ .name = "input_core",
+ .init = input_test_init,
+ .exit = input_test_exit,
+ .test_cases = input_tests,
+};
+
+kunit_test_suite(input_test_suite);
+
+MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>");
+MODULE_LICENSE("GPL");
base-commit: 3a93e40326c8f470e71d20b4c42d36767450f38f
--
2.40.0
^ permalink raw reply related
* Re: [REGRESSION] wrong coord from Thinkpad TrackPoint since 6.2 kernel
From: Takashi Iwai @ 2023-03-29 9:28 UTC (permalink / raw)
To: Hans de Goede
Cc: Takashi Iwai, Pali Rohár, Dmitry Torokhov, regressions,
linux-input, linux-kernel
In-Reply-To: <3dec29bf-b772-d82d-fff9-6c8bcca5f464@redhat.com>
On Wed, 29 Mar 2023 11:22:18 +0200,
Hans de Goede wrote:
>
> Hi Takashi,
>
> On 3/29/23 10:16, Takashi Iwai wrote:
> > Hi,
> >
> > we've received a bug report about Thinkpad TrackPoint (ALPS DualPoint
> > Stick) on 6.2 kernel:
> > https://bugzilla.opensuse.org/show_bug.cgi?id=1209805
> >
> > The device reports the wrong values as the movements, e.g. sometimes a
> > value such as 255, 254 or -255 is returned while usually it should be
> > a smaller value like -1 or 2.
> >
> > The evtest on 6.2.x kernel shows the wrong values like:
> >
> > Event: time 1680037542.898747, type 2 (EV_REL), code 0 (REL_X), value 255
> > Event: time 1680037542.898747, -------------- SYN_REPORT ------------
> > Event: time 1680037543.145196, type 2 (EV_REL), code 0 (REL_X), value 1
> > Event: time 1680037543.145196, -------------- SYN_REPORT ------------
> > Event: time 1680037543.175087, type 2 (EV_REL), code 1 (REL_Y), value -255
> > Event: time 1680037543.175087, -------------- SYN_REPORT ------------
> > Event: time 1680037543.185421, type 2 (EV_REL), code 0 (REL_X), value 1
> > Event: time 1680037543.185421, type 2 (EV_REL), code 1 (REL_Y), value -255
> > Event: time 1680037543.185421, -------------- SYN_REPORT ------------
> >
> > while 6.1.x kernel shows the correct values like:
> >
> > Event: time 1680037386.318058, type 2 (EV_REL), code 0 (REL_X), value -1
> > Event: time 1680037386.318058, type 2 (EV_REL), code 1 (REL_Y), value -1
> > Event: time 1680037386.318058, -------------- SYN_REPORT ------------
> > Event: time 1680037386.328087, type 2 (EV_REL), code 0 (REL_X), value -1
> > Event: time 1680037386.328087, type 2 (EV_REL), code 1 (REL_Y), value -1
> > Event: time 1680037386.328087, -------------- SYN_REPORT ------------
> > Event: time 1680037386.338046, type 2 (EV_REL), code 0 (REL_X), value -1
> > Event: time 1680037386.338046, type 2 (EV_REL), code 1 (REL_Y), value -2
> > Event: time 1680037386.338046, -------------- SYN_REPORT ------------
> >
> > I couldn't see any relevant changes in alps.c between those versions,
> > so this is likely a breakage in a lower layer.
> >
> > Could you guys take a look?
>
> I believe this is caused by the kernel now using -funsigned-char
> everywhere and this should be fixed by this commit:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=for-linus&id=754ff5060daf5a1cf4474eff9b4edeb6c17ef7ab
Ah, that makes sense!
I'll build a test kernel with this fix and ask the reporter for
testing.
> And there is a similar issue in the focaltech touchpad driver:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=for-linus&id=8980f190947ba29f23110408e712444884b74251
>
> Dmitry, since this is hitting 6.2 users, perhaps you can send
> a pull-req for your current for-linus branch to get the fix
> on its way to stable ?
That'll be great.
Thanks!
Takashi
^ permalink raw reply
* Re: [PATCH] Input: Add KUnit tests for some of the input core helper functions
From: Enric Balletbo i Serra @ 2023-03-29 21:01 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel, Brendan Higgins, Maxime Ripard, linux-kselftest,
David Gow, kunit-dev, Dmitry Torokhov, linux-input
In-Reply-To: <20230329092332.2143623-1-javierm@redhat.com>
Hi Javier,
Many thanks for the patch and to work on this.
On Wed, Mar 29, 2023 at 11:23 AM Javier Martinez Canillas
<javierm@redhat.com> wrote:
>
> The input subsystem doesn't currently have any unit tests, let's add a
> CONFIG_INPUT_KUNIT_TEST option that builds a test suite to be executed
> with the KUnit test infrastructure.
>
> For now, only three tests were added for some of the input core helper
> functions that are trivial to test:
>
> * input_test_polling: set/get poll interval and set-up a poll handler.
>
> * input_test_timestamp: set/get input event timestamps.
>
> * input_test_match_device_id: match a device by bus, vendor, product
> and events that is capable of handling.
>
> But having the minimal KUnit support allows to add more tests and suites
> as follow-up changes. The tests can be run with the following command:
>
> $ ./tools/testing/kunit/kunit.py run \
> --kunitconfig=drivers/input/tests/.kunitconfig
>
> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
I'll let other more experienced people comment on the kunit tests. In
my opinion it's a starting point and after applying your patch and
giving a try I can confirm that it works as expected, so just wanted
to give my.
Tested-by: Enric Balletbo i Serra <eballetbo@redhat.com>
Thanks,
Enric
> ---
>
> drivers/input/Kconfig | 12 +++
> drivers/input/Makefile | 1 +
> drivers/input/tests/Makefile | 3 +
> drivers/input/tests/input_test.c | 144 +++++++++++++++++++++++++++++++
> 4 files changed, 160 insertions(+)
> create mode 100644 drivers/input/tests/Makefile
> create mode 100644 drivers/input/tests/input_test.c
>
> diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
> index e2752f7364bc..e094e5bbaa0c 100644
> --- a/drivers/input/Kconfig
> +++ b/drivers/input/Kconfig
> @@ -166,6 +166,18 @@ config INPUT_EVBUG
> To compile this driver as a module, choose M here: the
> module will be called evbug.
>
> +config INPUT_KUNIT_TEST
> + tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS
> + depends on INPUT && KUNIT=y
> + default KUNIT_ALL_TESTS
> + help
> + Say Y here if you want to build the KUnit tests for the input
> + subsystem. For more information about KUnit and unit tests in
> + general, please refer to the KUnit documentation in
> + Documentation/dev-tools/kunit/.
> +
> + If in doubt, say "N".
> +
> config INPUT_APMPOWER
> tristate "Input Power Event -> APM Bridge" if EXPERT
> depends on INPUT && APM_EMULATION
> diff --git a/drivers/input/Makefile b/drivers/input/Makefile
> index 2266c7d010ef..c78753274921 100644
> --- a/drivers/input/Makefile
> +++ b/drivers/input/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
> obj-$(CONFIG_INPUT_TABLET) += tablet/
> obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
> obj-$(CONFIG_INPUT_MISC) += misc/
> +obj-$(CONFIG_INPUT_KUNIT_TEST) += tests/
>
> obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
>
> diff --git a/drivers/input/tests/Makefile b/drivers/input/tests/Makefile
> new file mode 100644
> index 000000000000..90cf954181bc
> --- /dev/null
> +++ b/drivers/input/tests/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o
> diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c
> new file mode 100644
> index 000000000000..25bbf51b5c87
> --- /dev/null
> +++ b/drivers/input/tests/input_test.c
> @@ -0,0 +1,144 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit test for the input core.
> + *
> + * Copyright (c) 2023 Red Hat Inc
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/input.h>
> +
> +#include <kunit/test.h>
> +
> +#define POLL_INTERVAL 100
> +
> +static int input_test_init(struct kunit *test)
> +{
> + struct input_dev *input_dev;
> + int ret;
> +
> + input_dev = input_allocate_device();
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev);
> +
> + input_dev->name = "Test input device";
> + input_dev->id.bustype = BUS_VIRTUAL;
> + input_dev->id.vendor = 1;
> + input_dev->id.product = 1;
> + input_dev->id.version = 1;
> + input_set_capability(input_dev, EV_KEY, BTN_LEFT);
> + input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
> +
> + ret = input_register_device(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
> + test->priv = input_dev;
> +
> + return 0;
> +}
> +
> +static void input_test_exit(struct kunit *test)
> +{
> + struct input_dev *input_dev = test->priv;
> +
> + input_unregister_device(input_dev);
> +}
> +
> +static void input_test_poll(struct input_dev *input) { }
> +
> +static void input_test_polling(struct kunit *test)
> +{
> + struct input_dev *input_dev = test->priv;
> + int ret;
> +
> + ret = input_get_poll_interval(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, -EINVAL);
> +
> + ret = input_setup_polling(input_dev, input_test_poll);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
> + input_set_poll_interval(input_dev, POLL_INTERVAL);
> +
> + ret = input_get_poll_interval(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, POLL_INTERVAL);
> +}
> +
> +static void input_test_timestamp(struct kunit *test)
> +{
> + const ktime_t invalid_timestamp = ktime_set(0, 0);
> + struct input_dev *input_dev = test->priv;
> + ktime_t *timestamp, time;
> + int ret;
> +
> + timestamp = input_get_timestamp(input_dev);
> + time = timestamp[INPUT_CLK_MONO];
> +
> + ret = ktime_compare(time, invalid_timestamp);
> + KUNIT_ASSERT_EQ(test, ret, 1);
> +
> + time = ktime_get();
> + input_set_timestamp(input_dev, time);
> +
> + timestamp = input_get_timestamp(input_dev);
> + KUNIT_ASSERT_EQ(test, ktime_compare(timestamp[INPUT_CLK_MONO],
> + time), 0);
> +}
> +
> +static void input_test_match_device_id(struct kunit *test)
> +{
> + struct input_dev *input_dev = test->priv;
> + struct input_device_id id;
> +
> + id.flags = INPUT_DEVICE_ID_MATCH_BUS;
> + id.bustype = BUS_VIRTUAL;
> + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
> +
> + id.bustype = BUS_I2C;
> + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
> +
> + id.flags = INPUT_DEVICE_ID_MATCH_VENDOR;
> + id.vendor = 1;
> + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
> +
> + id.vendor = 2;
> + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
> +
> + id.flags = INPUT_DEVICE_ID_MATCH_PRODUCT;
> + id.product = 1;
> + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
> +
> + id.product = 2;
> + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
> +
> + id.flags = INPUT_DEVICE_ID_MATCH_VERSION;
> + id.version = 1;
> + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
> +
> + id.version = 2;
> + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
> +
> + id.flags = INPUT_DEVICE_ID_MATCH_EVBIT;
> + __set_bit(EV_KEY, id.evbit);
> + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
> +
> + __set_bit(EV_ABS, id.evbit);
> + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
> +}
> +
> +static struct kunit_case input_tests[] = {
> + KUNIT_CASE(input_test_polling),
> + KUNIT_CASE(input_test_timestamp),
> + KUNIT_CASE(input_test_match_device_id),
> + { /* sentinel */ }
> +};
> +
> +static struct kunit_suite input_test_suite = {
> + .name = "input_core",
> + .init = input_test_init,
> + .exit = input_test_exit,
> + .test_cases = input_tests,
> +};
> +
> +kunit_test_suite(input_test_suite);
> +
> +MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>");
> +MODULE_LICENSE("GPL");
>
> base-commit: 3a93e40326c8f470e71d20b4c42d36767450f38f
> --
> 2.40.0
>
^ permalink raw reply
* [PATCH 0/2] Improve GIP support
From: Vicki Pfau @ 2023-03-30 2:47 UTC (permalink / raw)
To: Dmitry Torokhov, Benjamin Tissoires, linux-input
Cc: Vicki Pfau, Pavel Rojtberg
This series contains a new version of the previously submitted "fix PowerA
EnWired Controller guide button" patch to make the failure soft instead of
hard, as well as a further patch to add (and use) constants for the interface
names, based on information gleaned from the xone project.
Vicki Pfau (2):
Input: xpad - Add constants for GIP interface numbers
Input: xpad - fix PowerA EnWired Controller guide button
drivers/input/joystick/xpad.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
--
2.40.0
^ permalink raw reply
* [PATCH 2/2] Input: xpad - fix PowerA EnWired Controller guide button
From: Vicki Pfau @ 2023-03-30 2:47 UTC (permalink / raw)
To: Dmitry Torokhov, Benjamin Tissoires, linux-input
Cc: Vicki Pfau, Pavel Rojtberg
In-Reply-To: <20230330024752.2405603-1-vi@endrift.com>
This commit explicitly disables the audio interface the same way the official
driver does. This is needed for some controllers, such as the PowerA Enhanced
Wired Controller for Series X|S (0x20d6:0x200e) to report the guide button.
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/input/joystick/xpad.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 698224e1948f..c31fc4e9b310 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1396,6 +1396,14 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
unsigned long flags;
int retval;
+ /* Explicitly disable the audio interface. This is needed for some
+ * controllers, such as the PowerA Enhanced Wired Controller
+ * for Series X|S (0x20d6:0x200e) to report the guide button */
+ retval = usb_set_interface(xpad->udev, GIP_WIRED_INTF_AUDIO, 0);
+ if (retval)
+ dev_warn(&xpad->dev->dev,
+ "unable to disable audio interface: %d\n", retval);
+
spin_lock_irqsave(&xpad->odata_lock, flags);
/*
--
2.40.0
^ permalink raw reply related
* [PATCH 1/2] Input: xpad - Add constants for GIP interface numbers
From: Vicki Pfau @ 2023-03-30 2:47 UTC (permalink / raw)
To: Dmitry Torokhov, Benjamin Tissoires, linux-input
Cc: Vicki Pfau, Pavel Rojtberg
In-Reply-To: <20230330024752.2405603-1-vi@endrift.com>
Wired GIP devices present multiple interfaces with the same USB identification
other than the interface number. This adds constants for differentiating two of
them and uses them where appropriate
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/input/joystick/xpad.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 2d86ca0c1ace..698224e1948f 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -561,6 +561,9 @@ struct xboxone_init_packet {
#define GIP_MOTOR_LT BIT(3)
#define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT)
+#define GIP_WIRED_INTF_DATA 0
+#define GIP_WIRED_INTF_AUDIO 1
+
/*
* This packet is required for all Xbox One pads with 2015
* or later firmware installed (or present from the factory).
@@ -2004,7 +2007,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
}
if (xpad->xtype == XTYPE_XBOXONE &&
- intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+ intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) {
/*
* The Xbox One controller lists three interfaces all with the
* same interface class, subclass and protocol. Differentiate by
--
2.40.0
^ permalink raw reply related
* Re: [PATCH] Input: Add KUnit tests for some of the input core helper functions
From: Daniel Latypov @ 2023-03-30 5:28 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel, Brendan Higgins, Maxime Ripard, linux-kselftest,
Enric Balletbo i Serra, David Gow, kunit-dev, Dmitry Torokhov,
linux-input
In-Reply-To: <20230329092332.2143623-1-javierm@redhat.com>
On Wed, Mar 29, 2023 at 2:23 AM Javier Martinez Canillas
<javierm@redhat.com> wrote:
>
> The input subsystem doesn't currently have any unit tests, let's add a
> CONFIG_INPUT_KUNIT_TEST option that builds a test suite to be executed
> with the KUnit test infrastructure.
>
> For now, only three tests were added for some of the input core helper
> functions that are trivial to test:
>
> * input_test_polling: set/get poll interval and set-up a poll handler.
>
> * input_test_timestamp: set/get input event timestamps.
>
> * input_test_match_device_id: match a device by bus, vendor, product
> and events that is capable of handling.
>
> But having the minimal KUnit support allows to add more tests and suites
> as follow-up changes. The tests can be run with the following command:
>
> $ ./tools/testing/kunit/kunit.py run \
> --kunitconfig=drivers/input/tests/.kunitconfig
Nice!
A few small suggestions below as someone who has worked on KUnit.
FYI, to save a few keystrokes, you can omit the "/.kunitconfig" and
just pass the dir, i.e.
--kunitconfig=drivers/input/tests
>
> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
> ---
>
> drivers/input/Kconfig | 12 +++
> drivers/input/Makefile | 1 +
> drivers/input/tests/Makefile | 3 +
> drivers/input/tests/input_test.c | 144 +++++++++++++++++++++++++++++++
I don't see the .kunitconfig in the diff.
Was it accidentally forgotten or does this patch apply to a tree that
already has the file?
(it's easy to forget since git will still ignore it by default, IIRC)
> 4 files changed, 160 insertions(+)
> create mode 100644 drivers/input/tests/Makefile
> create mode 100644 drivers/input/tests/input_test.c
>
> diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
> index e2752f7364bc..e094e5bbaa0c 100644
> --- a/drivers/input/Kconfig
> +++ b/drivers/input/Kconfig
> @@ -166,6 +166,18 @@ config INPUT_EVBUG
> To compile this driver as a module, choose M here: the
> module will be called evbug.
>
> +config INPUT_KUNIT_TEST
> + tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS
> + depends on INPUT && KUNIT=y
> + default KUNIT_ALL_TESTS
> + help
> + Say Y here if you want to build the KUnit tests for the input
> + subsystem. For more information about KUnit and unit tests in
> + general, please refer to the KUnit documentation in
> + Documentation/dev-tools/kunit/.
> +
> + If in doubt, say "N".
FYI, I know this is in the style guide, but I'd personally feel free
to leave out this paragraph.
Having such "advertising" about what KUnit is made more sense when
less people knew about it.
It's not known by everyone in the community yet, but we might be
getting to a point where this turns into repetitive bloat.
> +
> config INPUT_APMPOWER
> tristate "Input Power Event -> APM Bridge" if EXPERT
> depends on INPUT && APM_EMULATION
> diff --git a/drivers/input/Makefile b/drivers/input/Makefile
> index 2266c7d010ef..c78753274921 100644
> --- a/drivers/input/Makefile
> +++ b/drivers/input/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
> obj-$(CONFIG_INPUT_TABLET) += tablet/
> obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
> obj-$(CONFIG_INPUT_MISC) += misc/
> +obj-$(CONFIG_INPUT_KUNIT_TEST) += tests/
>
> obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
>
> diff --git a/drivers/input/tests/Makefile b/drivers/input/tests/Makefile
> new file mode 100644
> index 000000000000..90cf954181bc
> --- /dev/null
> +++ b/drivers/input/tests/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o
> diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c
> new file mode 100644
> index 000000000000..25bbf51b5c87
> --- /dev/null
> +++ b/drivers/input/tests/input_test.c
> @@ -0,0 +1,144 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit test for the input core.
> + *
> + * Copyright (c) 2023 Red Hat Inc
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/input.h>
> +
> +#include <kunit/test.h>
> +
> +#define POLL_INTERVAL 100
> +
> +static int input_test_init(struct kunit *test)
> +{
> + struct input_dev *input_dev;
> + int ret;
> +
> + input_dev = input_allocate_device();
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev);
> +
> + input_dev->name = "Test input device";
> + input_dev->id.bustype = BUS_VIRTUAL;
> + input_dev->id.vendor = 1;
> + input_dev->id.product = 1;
> + input_dev->id.version = 1;
> + input_set_capability(input_dev, EV_KEY, BTN_LEFT);
> + input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
> +
> + ret = input_register_device(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, 0);
(very unlikely that this matters, but...)
Hmm, should we call input_free_device() if this fails?
i.e. something like
ret = ...;
if (ret) {
input_free_device(input_dev);
KUNIT_ASSERT_FAILURE(test, "failed to register device: %d", ret);
}
KUNIT_ASSERT_FAILURE() is like KUNIT_ASSERT_*(), but doesn't do any comparison.
It just unconditionally aborts the test after printing the given message.
We could alternatively do
kunit_err(test, "failed to register device: %d", ret);
return ret;
but this version won't show a file and line number.
> +
> + test->priv = input_dev;
> +
> + return 0;
> +}
> +
> +static void input_test_exit(struct kunit *test)
> +{
> + struct input_dev *input_dev = test->priv;
> +
> + input_unregister_device(input_dev);
> +}
> +
> +static void input_test_poll(struct input_dev *input) { }
> +
> +static void input_test_polling(struct kunit *test)
> +{
> + struct input_dev *input_dev = test->priv;
> + int ret;
> +
> + ret = input_get_poll_interval(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, -EINVAL);
minor suggestion: can we inline these? E.g.
KUNIT_ASSERT_EQ(test, -EINVAL, input_get_poll_interval(input_dev));
This way on failure, KUnit can print the function call instead of just `ret`.
Users could always find out what failed by the line #, but including
it in the output would be a bit nicer.
E.g. w/ KUNIT_EXPECT_EQ(test, 0, ...)
# example_simple_test: EXPECTATION FAILED at
lib/kunit/kunit-example-test.c:29
Expected 0 == input_get_poll_interval(input_dev), but
input_get_poll_interval(input_dev) == 42 (0x2a)
verus
# example_simple_test: EXPECTATION FAILED at
lib/kunit/kunit-example-test.c:28
Expected ret == 0, but
ret == 42 (0x2a)
> +
> + ret = input_setup_polling(input_dev, input_test_poll);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
> + input_set_poll_interval(input_dev, POLL_INTERVAL);
> +
> + ret = input_get_poll_interval(input_dev);
> + KUNIT_ASSERT_EQ(test, ret, POLL_INTERVAL);
> +}
> +
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH] Input: Add KUnit tests for some of the input core helper functions
From: Javier Martinez Canillas @ 2023-03-30 8:09 UTC (permalink / raw)
To: Daniel Latypov
Cc: linux-kernel, Brendan Higgins, Maxime Ripard, linux-kselftest,
Enric Balletbo i Serra, David Gow, kunit-dev, Dmitry Torokhov,
linux-input
In-Reply-To: <CAGS_qxpEzXRWqy2Xd8qJn7GRxv+8HF40Lxt8esD-59CzeePZSw@mail.gmail.com>
Daniel Latypov <dlatypov@google.com> writes:
Hello Daniel,
Thanks a lot for your feedback!
> On Wed, Mar 29, 2023 at 2:23 AM Javier Martinez Canillas
> <javierm@redhat.com> wrote:
[...]
>>
>> $ ./tools/testing/kunit/kunit.py run \
>> --kunitconfig=drivers/input/tests/.kunitconfig
>
> Nice!
> A few small suggestions below as someone who has worked on KUnit.
>
> FYI, to save a few keystrokes, you can omit the "/.kunitconfig" and
> just pass the dir, i.e.
> --kunitconfig=drivers/input/tests
>
Ah, cool. I didn't know that.
[...]
>> drivers/input/tests/input_test.c | 144 +++++++++++++++++++++++++++++++
>
> I don't see the .kunitconfig in the diff.
> Was it accidentally forgotten or does this patch apply to a tree that
> already has the file?
>
> (it's easy to forget since git will still ignore it by default, IIRC)
>
I did indeed forgot because as you mentioned git add complained and I
missed that needed to force to add it.
[...]
>> + Say Y here if you want to build the KUnit tests for the input
>> + subsystem. For more information about KUnit and unit tests in
>> + general, please refer to the KUnit documentation in
>> + Documentation/dev-tools/kunit/.
>> +
>> + If in doubt, say "N".
>
> FYI, I know this is in the style guide, but I'd personally feel free
> to leave out this paragraph.
>
> Having such "advertising" about what KUnit is made more sense when
> less people knew about it.
> It's not known by everyone in the community yet, but we might be
> getting to a point where this turns into repetitive bloat.
>
Ok, I'll drop these.
[...]
>> +
>> + ret = input_register_device(input_dev);
>> + KUNIT_ASSERT_EQ(test, ret, 0);
>
> (very unlikely that this matters, but...)
> Hmm, should we call input_free_device() if this fails?
> i.e. something like
>
> ret = ...;
> if (ret) {
> input_free_device(input_dev);
> KUNIT_ASSERT_FAILURE(test, "failed to register device: %d", ret);
> }
>
Indeed. I'll do this too.
[...]
>> +
>> + ret = input_get_poll_interval(input_dev);
>> + KUNIT_ASSERT_EQ(test, ret, -EINVAL);
>
> minor suggestion: can we inline these? E.g.
> KUNIT_ASSERT_EQ(test, -EINVAL, input_get_poll_interval(input_dev));
> This way on failure, KUnit can print the function call instead of just `ret`.
>
> Users could always find out what failed by the line #, but including
> it in the output would be a bit nicer.
>
> E.g. w/ KUNIT_EXPECT_EQ(test, 0, ...)
>
> # example_simple_test: EXPECTATION FAILED at
> lib/kunit/kunit-example-test.c:29
> Expected 0 == input_get_poll_interval(input_dev), but
> input_get_poll_interval(input_dev) == 42 (0x2a)
>
> verus
>
> # example_simple_test: EXPECTATION FAILED at
> lib/kunit/kunit-example-test.c:28
> Expected ret == 0, but
> ret == 42 (0x2a)
>
Great suggestion. I'll change too, it would also get rid of the ret variable.
--
Best regards,
Javier Martinez Canillas
Core Platforms
Red Hat
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox