Skip to content

Commit

Permalink
Wrongly bound Elantech touchpad on Lenovo Yoga Slim 7
Browse files Browse the repository at this point in the history
Hi,

we've got a bug report on openSUSE Bugzilla about the broken touchpad
on Lenovo Yoga Slim 7:
  https://bugzilla.opensuse.org/show_bug.cgi?id=1193064

The touchpad is an Elantech one, connected over i2c, and there are two
drivers supporting it.  Unfortunately, the default one the system
binds, elan-i2c input driver, doesn't seem working properly, while
i2c-hid driver works.

I'm not sure what's the best fix for this, but below a quick
workaround using a deny list with DMI matching.
If this is OK, I can resubmit the patch for merging.

Any comments appreciated.

thanks,

Takashi

-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] Input: elan_i2c: Add deny list for Lenovo Yoga Slim 7

The touchpad on Lenovo Yoga Slim 7 doesn't work well with elan-i2c but
rather better with i2c-hid.  Add a deny list for avoiding to bind with
elan-i2c.

BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1193064
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
tiwai authored and intel-lab-lkp committed Feb 4, 2022
1 parent 87a0b2f commit 9f3fbdd
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions drivers/input/mouse/elan_i2c_core.c
Expand Up @@ -18,6 +18,7 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/init.h>
Expand Down Expand Up @@ -1222,6 +1223,20 @@ static void elan_disable_regulator(void *_data)
regulator_disable(data->vcc);
}

static const struct dmi_system_id elan_i2c_denylist[] __initconst = {
#if IS_ENABLED(CONFIG_I2C_HID_ACPI)
{
/* Lenovo Yoga Slim 7 is better supported by i2c-hid */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "82A3"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Yoga Slim 7 14ITL05"),
},
},
#endif
{ }
};

static int elan_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
Expand All @@ -1233,6 +1248,10 @@ static int elan_probe(struct i2c_client *client,

if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_I2C) &&
i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
if (dmi_check_system(elan_i2c_denylist)) {
dev_info(dev, "Hits deny list, skipping\n");
return -ENODEV;
}
transport_ops = &elan_i2c_ops;
} else if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) &&
i2c_check_functionality(client->adapter,
Expand Down

0 comments on commit 9f3fbdd

Please sign in to comment.