diff mbox series

platform/x86: lenovo-ymc: Only bind on machines with a convertible DMI chassis-type

Message ID 20230812144818.383230-1-hdegoede@redhat.com (mailing list archive)
State Accepted, archived
Headers show
Series platform/x86: lenovo-ymc: Only bind on machines with a convertible DMI chassis-type | expand

Commit Message

Hans de Goede Aug. 12, 2023, 2:48 p.m. UTC
The lenovo-ymc driver is causing the keyboard + touchpad to stop working
on some regular laptop models such as the Lenovo ThinkBook 13s G2 ITL 20V9.

The problem is that there are YMC WMI GUID methods in the ACPI tables
of these laptops, despite them not being Yogas and lenovo-ymc loading
causes libinput to see a SW_TABLET_MODE switch with state 1.

This in turn causes libinput to ignore events from the builtin keyboard
and touchpad, since it filters those out for a Yoga in tablet mode.

Similar issues with false-positive SW_TABLET_MODE=1 reporting have
been seen with the intel-hid driver.

Copy the intel-hid driver approach to fix this and only bind to the WMI
device on machines where the DMI chassis-type indicates the machine
is a convertible.

Add a 'force' module parameter to allow overriding the chassis-type check
so that users can easily test if the YMC interface works on models which
report an unexpected chassis-type.

Fixes: e82882cdd241 ("platform/x86: Add driver for Yoga Tablet Mode switch")
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2229373
Cc: Gergo Koteles <soyer@irl.hu>
Cc: Andrew Kallmeyer <kallmeyeras@gmail.com>
Cc: André Apitzsch <git@apitzsch.eu>
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Note: The chassis-type can be checked by doing:
cat /sys/class/dmi/id/chassis_type
if this reports 31 or 32 then this patch should not have any impact
on your machine.
---
 drivers/platform/x86/lenovo-ymc.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Andrew Kallmeyer Aug. 12, 2023, 5:25 p.m. UTC | #1
On Sat, Aug 12, 2023 at 7:48 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> The lenovo-ymc driver is causing the keyboard + touchpad to stop working
> on some regular laptop models such as the Lenovo ThinkBook 13s G2 ITL 20V9.
>
> The problem is that there are YMC WMI GUID methods in the ACPI tables
> of these laptops, despite them not being Yogas and lenovo-ymc loading
> causes libinput to see a SW_TABLET_MODE switch with state 1.
>
> This in turn causes libinput to ignore events from the builtin keyboard
> and touchpad, since it filters those out for a Yoga in tablet mode.
>
> Similar issues with false-positive SW_TABLET_MODE=1 reporting have
> been seen with the intel-hid driver.
>
> Copy the intel-hid driver approach to fix this and only bind to the WMI
> device on machines where the DMI chassis-type indicates the machine
> is a convertible.
>
> Add a 'force' module parameter to allow overriding the chassis-type check
> so that users can easily test if the YMC interface works on models which
> report an unexpected chassis-type.
>
> Fixes: e82882cdd241 ("platform/x86: Add driver for Yoga Tablet Mode switch")
> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2229373
> Cc: Gergo Koteles <soyer@irl.hu>
> Cc: Andrew Kallmeyer <kallmeyeras@gmail.com>
> Cc: André Apitzsch <git@apitzsch.eu>
> Cc: stable@vger.kernel.org
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Too bad that this caused problems for some people. Thank you for
getting it fixed Hans!

While I had trouble applying this patch as is (maybe the code has
changed a bit since my patch), I was able to manually add these lines
and test this fix on my laptop (Yoga 7 14AIL7). The new device was
found and everything worked as expected.

Tested-by: Andrew Kallmeyer <kallmeyeras@gmail.com>

> Note: The chassis-type can be checked by doing:
> cat /sys/class/dmi/id/chassis_type
> if this reports 31 or 32 then this patch should not have any impact
> on your machine.

My laptop (Yoga 7 14AIL7) has chassis_type 31, just to add more info.
Hans de Goede Aug. 12, 2023, 5:54 p.m. UTC | #2
Hi,

On 8/12/23 19:25, Andrew Kallmeyer wrote:
> On Sat, Aug 12, 2023 at 7:48 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> The lenovo-ymc driver is causing the keyboard + touchpad to stop working
>> on some regular laptop models such as the Lenovo ThinkBook 13s G2 ITL 20V9.
>>
>> The problem is that there are YMC WMI GUID methods in the ACPI tables
>> of these laptops, despite them not being Yogas and lenovo-ymc loading
>> causes libinput to see a SW_TABLET_MODE switch with state 1.
>>
>> This in turn causes libinput to ignore events from the builtin keyboard
>> and touchpad, since it filters those out for a Yoga in tablet mode.
>>
>> Similar issues with false-positive SW_TABLET_MODE=1 reporting have
>> been seen with the intel-hid driver.
>>
>> Copy the intel-hid driver approach to fix this and only bind to the WMI
>> device on machines where the DMI chassis-type indicates the machine
>> is a convertible.
>>
>> Add a 'force' module parameter to allow overriding the chassis-type check
>> so that users can easily test if the YMC interface works on models which
>> report an unexpected chassis-type.
>>
>> Fixes: e82882cdd241 ("platform/x86: Add driver for Yoga Tablet Mode switch")
>> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2229373
>> Cc: Gergo Koteles <soyer@irl.hu>
>> Cc: Andrew Kallmeyer <kallmeyeras@gmail.com>
>> Cc: André Apitzsch <git@apitzsch.eu>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> 
> Too bad that this caused problems for some people. Thank you for
> getting it fixed Hans!
> 
> While I had trouble applying this patch as is (maybe the code has
> changed a bit since my patch), I was able to manually add these lines
> and test this fix on my laptop (Yoga 7 14AIL7). The new device was
> found and everything worked as expected.
> 
> Tested-by: Andrew Kallmeyer <kallmeyeras@gmail.com>

Great, thank you for the quick test.

Regards,

Hans
Gergo Koteles Aug. 12, 2023, 8:48 p.m. UTC | #3
Hi,

On Sat, 2023-08-12 at 16:48 +0200, Hans de Goede wrote:
> The lenovo-ymc driver is causing the keyboard + touchpad to stop working
> on some regular laptop models such as the Lenovo ThinkBook 13s G2 ITL 20V9.
> 
> The problem is that there are YMC WMI GUID methods in the ACPI tables
> of these laptops, despite them not being Yogas and lenovo-ymc loading
> causes libinput to see a SW_TABLET_MODE switch with state 1.
> 
> This in turn causes libinput to ignore events from the builtin keyboard
> and touchpad, since it filters those out for a Yoga in tablet mode.
> 
> Similar issues with false-positive SW_TABLET_MODE=1 reporting have
> been seen with the intel-hid driver.
> 
> Copy the intel-hid driver approach to fix this and only bind to the WMI
> device on machines where the DMI chassis-type indicates the machine
> is a convertible.
> 
> Add a 'force' module parameter to allow overriding the chassis-type check
> so that users can easily test if the YMC interface works on models which
> report an unexpected chassis-type.
> 
> Fixes: e82882cdd241 ("platform/x86: Add driver for Yoga Tablet Mode switch")
> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2229373
> Cc: Gergo Koteles <soyer@irl.hu>
> Cc: Andrew Kallmeyer <kallmeyeras@gmail.com>
> Cc: André Apitzsch <git@apitzsch.eu>
> Cc: stable@vger.kernel.org
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Thanks for fixing this!
It works on Yoga 7 14ARB7.

Tested-by: Gergő Köteles <soyer@irl.hu>

Regards,
Gergő

> ---
> Note: The chassis-type can be checked by doing:
> cat /sys/class/dmi/id/chassis_type
> if this reports 31 or 32 then this patch should not have any impact
> on your machine.
> ---
>  drivers/platform/x86/lenovo-ymc.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c
> index 41676188b373..f360370d5002 100644
> --- a/drivers/platform/x86/lenovo-ymc.c
> +++ b/drivers/platform/x86/lenovo-ymc.c
> @@ -24,6 +24,10 @@ 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 bool force;
> +module_param(force, bool, 0444);
> +MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type");
> +
>  static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
>  	{
>  		/* Lenovo Yoga 7 14ARB7 */
> @@ -35,6 +39,20 @@ static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
>  	{ }
>  };
>  
> +static const struct dmi_system_id allowed_chasis_types_dmi_table[] = {
> +	{
> +		.matches = {
> +			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */),
> +		},
> +	},
> +	{
> +		.matches = {
> +			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */),
> +		},
> +	},
> +	{ }
> +};
> +
>  struct lenovo_ymc_private {
>  	struct input_dev *input_dev;
>  	struct acpi_device *ec_acpi_dev;
> @@ -111,6 +129,13 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
>  	struct input_dev *input_dev;
>  	int err;
>  
> +	if (!dmi_check_system(allowed_chasis_types_dmi_table)) {
> +		if (force)
> +			dev_info(&wdev->dev, "Force loading Lenovo YMC support\n");
> +		else
> +			return -ENODEV;
> +	}
> +
>  	ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table);
>  
>  	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
Hans de Goede Aug. 13, 2023, 12:55 p.m. UTC | #4
Hi,

On 8/12/23 22:48, Gergő Köteles wrote:
> Hi,
> 
> On Sat, 2023-08-12 at 16:48 +0200, Hans de Goede wrote:
>> The lenovo-ymc driver is causing the keyboard + touchpad to stop working
>> on some regular laptop models such as the Lenovo ThinkBook 13s G2 ITL 20V9.
>>
>> The problem is that there are YMC WMI GUID methods in the ACPI tables
>> of these laptops, despite them not being Yogas and lenovo-ymc loading
>> causes libinput to see a SW_TABLET_MODE switch with state 1.
>>
>> This in turn causes libinput to ignore events from the builtin keyboard
>> and touchpad, since it filters those out for a Yoga in tablet mode.
>>
>> Similar issues with false-positive SW_TABLET_MODE=1 reporting have
>> been seen with the intel-hid driver.
>>
>> Copy the intel-hid driver approach to fix this and only bind to the WMI
>> device on machines where the DMI chassis-type indicates the machine
>> is a convertible.
>>
>> Add a 'force' module parameter to allow overriding the chassis-type check
>> so that users can easily test if the YMC interface works on models which
>> report an unexpected chassis-type.
>>
>> Fixes: e82882cdd241 ("platform/x86: Add driver for Yoga Tablet Mode switch")
>> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2229373
>> Cc: Gergo Koteles <soyer@irl.hu>
>> Cc: Andrew Kallmeyer <kallmeyeras@gmail.com>
>> Cc: André Apitzsch <git@apitzsch.eu>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> 
> Thanks for fixing this!
> It works on Yoga 7 14ARB7.
> 
> Tested-by: Gergő Köteles <soyer@irl.hu>

On 8/12/23 19:25, Andrew Kallmeyer wrote:

> Too bad that this caused problems for some people. Thank you for
> getting it fixed Hans!
> 
> Tested-by: Andrew Kallmeyer <kallmeyeras@gmail.com>

Thank you both for testing this.

I've added this to the pdx86/fixes branch now, with both
your Tested-by-s added.

Regards,

Hans




>> ---
>> Note: The chassis-type can be checked by doing:
>> cat /sys/class/dmi/id/chassis_type
>> if this reports 31 or 32 then this patch should not have any impact
>> on your machine.
>> ---
>>  drivers/platform/x86/lenovo-ymc.c | 25 +++++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>>
>> diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c
>> index 41676188b373..f360370d5002 100644
>> --- a/drivers/platform/x86/lenovo-ymc.c
>> +++ b/drivers/platform/x86/lenovo-ymc.c
>> @@ -24,6 +24,10 @@ 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 bool force;
>> +module_param(force, bool, 0444);
>> +MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type");
>> +
>>  static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
>>  	{
>>  		/* Lenovo Yoga 7 14ARB7 */
>> @@ -35,6 +39,20 @@ static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
>>  	{ }
>>  };
>>  
>> +static const struct dmi_system_id allowed_chasis_types_dmi_table[] = {
>> +	{
>> +		.matches = {
>> +			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */),
>> +		},
>> +	},
>> +	{
>> +		.matches = {
>> +			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */),
>> +		},
>> +	},
>> +	{ }
>> +};
>> +
>>  struct lenovo_ymc_private {
>>  	struct input_dev *input_dev;
>>  	struct acpi_device *ec_acpi_dev;
>> @@ -111,6 +129,13 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
>>  	struct input_dev *input_dev;
>>  	int err;
>>  
>> +	if (!dmi_check_system(allowed_chasis_types_dmi_table)) {
>> +		if (force)
>> +			dev_info(&wdev->dev, "Force loading Lenovo YMC support\n");
>> +		else
>> +			return -ENODEV;
>> +	}
>> +
>>  	ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table);
>>  
>>  	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
>
diff mbox series

Patch

diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c
index 41676188b373..f360370d5002 100644
--- a/drivers/platform/x86/lenovo-ymc.c
+++ b/drivers/platform/x86/lenovo-ymc.c
@@ -24,6 +24,10 @@  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 bool force;
+module_param(force, bool, 0444);
+MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type");
+
 static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
 	{
 		/* Lenovo Yoga 7 14ARB7 */
@@ -35,6 +39,20 @@  static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = {
 	{ }
 };
 
+static const struct dmi_system_id allowed_chasis_types_dmi_table[] = {
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */),
+		},
+	},
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */),
+		},
+	},
+	{ }
+};
+
 struct lenovo_ymc_private {
 	struct input_dev *input_dev;
 	struct acpi_device *ec_acpi_dev;
@@ -111,6 +129,13 @@  static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx)
 	struct input_dev *input_dev;
 	int err;
 
+	if (!dmi_check_system(allowed_chasis_types_dmi_table)) {
+		if (force)
+			dev_info(&wdev->dev, "Force loading Lenovo YMC support\n");
+		else
+			return -ENODEV;
+	}
+
 	ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table);
 
 	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);