platform/x86: ideapad-laptop: Disable touchpad_switch for ELAN0634
Newer ideapads (e.g.: Yoga 14s, 720S 14) come with ELAN0634 touchpad do not use EC to switch touchpad. Reading VPCCMD_R_TOUCHPAD will return zero thus touchpad may be blocked unexpectedly. Writing VPCCMD_W_TOUCHPAD may cause a spurious key press. Add has_touchpad_switch to workaround these machines. Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: stable@vger.kernel.org # 5.4+ -- v2: Specify touchpad to ELAN0634 v3: Stupid missing ! in v2 v4: Correct acpi_dev_present usage (Hans) Link: https://lore.kernel.org/r/20210107144438.12605-1-jiaxun.yang@flygoat.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
fc00bc8ac1
commit
d69cd7eea9
@ -92,6 +92,7 @@ struct ideapad_private {
|
|||||||
struct dentry *debug;
|
struct dentry *debug;
|
||||||
unsigned long cfg;
|
unsigned long cfg;
|
||||||
bool has_hw_rfkill_switch;
|
bool has_hw_rfkill_switch;
|
||||||
|
bool has_touchpad_switch;
|
||||||
const char *fnesc_guid;
|
const char *fnesc_guid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -535,7 +536,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
|
|||||||
} else if (attr == &dev_attr_fn_lock.attr) {
|
} else if (attr == &dev_attr_fn_lock.attr) {
|
||||||
supported = acpi_has_method(priv->adev->handle, "HALS") &&
|
supported = acpi_has_method(priv->adev->handle, "HALS") &&
|
||||||
acpi_has_method(priv->adev->handle, "SALS");
|
acpi_has_method(priv->adev->handle, "SALS");
|
||||||
} else
|
} else if (attr == &dev_attr_touchpad.attr)
|
||||||
|
supported = priv->has_touchpad_switch;
|
||||||
|
else
|
||||||
supported = true;
|
supported = true;
|
||||||
|
|
||||||
return supported ? attr->mode : 0;
|
return supported ? attr->mode : 0;
|
||||||
@ -867,6 +870,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv)
|
|||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
|
|
||||||
|
if (!priv->has_touchpad_switch)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Without reading from EC touchpad LED doesn't switch state */
|
/* Without reading from EC touchpad LED doesn't switch state */
|
||||||
if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) {
|
if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) {
|
||||||
/* Some IdeaPads don't really turn off touchpad - they only
|
/* Some IdeaPads don't really turn off touchpad - they only
|
||||||
@ -989,6 +995,9 @@ static int ideapad_acpi_add(struct platform_device *pdev)
|
|||||||
priv->platform_device = pdev;
|
priv->platform_device = pdev;
|
||||||
priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
|
priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
|
||||||
|
|
||||||
|
/* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
|
||||||
|
priv->has_touchpad_switch = !acpi_dev_present("ELAN0634", NULL, -1);
|
||||||
|
|
||||||
ret = ideapad_sysfs_init(priv);
|
ret = ideapad_sysfs_init(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1006,6 +1015,10 @@ static int ideapad_acpi_add(struct platform_device *pdev)
|
|||||||
if (!priv->has_hw_rfkill_switch)
|
if (!priv->has_hw_rfkill_switch)
|
||||||
write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1);
|
write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1);
|
||||||
|
|
||||||
|
/* The same for Touchpad */
|
||||||
|
if (!priv->has_touchpad_switch)
|
||||||
|
write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1);
|
||||||
|
|
||||||
for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
|
for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
|
||||||
if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
|
if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
|
||||||
ideapad_register_rfkill(priv, i);
|
ideapad_register_rfkill(priv, i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user