platform/x86: ideapad-laptop: Send KEY_TOUCHPAD_TOGGLE on some models
On recent Ideapad models the EC does not control the touchpad at all, so instead of sending KEY_TOUCHPAD_ON/ _OFF on touchpad toggle hotkey events, ideapad-laptop should send KEY_TOUCHPAD_TOGGLE and let userspace handle the toggling. Check for this by checking if the value read from VPCCMD_R_TOUCHPAD actually changes when receiving a touchpad-toggle hotkey event; and if it does not change send KEY_TOUCHPAD_TOGGLE to userspace to let userspace enable/disable the touchpad in software. Note this also drops the priv->features.touchpad_ctrl_via_ec check from ideapad_sync_touchpad_state() so that KEY_TOUCHPAD_TOGGLE will be send on laptops where this is not set too. This can be safely dropped now because the i8042_command(I8042_CMD_AUX_ENABLE/_DISABLE) call is now guarded by its own feature flag. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Tested-by: Maxim Mikityanskiy <maxtram95@gmail.com> Link: https://lore.kernel.org/r/20221117110244.67811-5-hdegoede@redhat.com
This commit is contained in:
parent
c69e7d843d
commit
5829f8a897
@ -134,6 +134,7 @@ struct ideapad_private {
|
||||
struct ideapad_dytc_priv *dytc;
|
||||
struct dentry *debug;
|
||||
unsigned long cfg;
|
||||
unsigned long r_touchpad_val;
|
||||
struct {
|
||||
bool conservation_mode : 1;
|
||||
bool dytc : 1;
|
||||
@ -650,6 +651,8 @@ static ssize_t touchpad_show(struct device *dev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->r_touchpad_val = result;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", !!result);
|
||||
}
|
||||
|
||||
@ -669,6 +672,8 @@ static ssize_t touchpad_store(struct device *dev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->r_touchpad_val = state;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1159,6 +1164,7 @@ static const struct key_entry ideapad_keymap[] = {
|
||||
{ KE_KEY, 65, { KEY_PROG4 } },
|
||||
{ KE_KEY, 66, { KEY_TOUCHPAD_OFF } },
|
||||
{ KE_KEY, 67, { KEY_TOUCHPAD_ON } },
|
||||
{ KE_KEY, 68, { KEY_TOUCHPAD_TOGGLE } },
|
||||
{ KE_KEY, 128, { KEY_ESC } },
|
||||
|
||||
/*
|
||||
@ -1500,9 +1506,6 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_
|
||||
unsigned char param;
|
||||
int ret;
|
||||
|
||||
if (!priv->features.touchpad_ctrl_via_ec)
|
||||
return;
|
||||
|
||||
/* Without reading from EC touchpad LED doesn't switch state */
|
||||
ret = read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value);
|
||||
if (ret)
|
||||
@ -1518,9 +1521,20 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_
|
||||
i8042_command(¶m, value ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE);
|
||||
|
||||
if (send_events) {
|
||||
ideapad_input_report(priv, value ? 67 : 66);
|
||||
sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad");
|
||||
/*
|
||||
* On older models the EC controls the touchpad and toggles it
|
||||
* on/off itself, in this case we report KEY_TOUCHPAD_ON/_OFF.
|
||||
* If the EC did not toggle, report KEY_TOUCHPAD_TOGGLE.
|
||||
*/
|
||||
if (value != priv->r_touchpad_val) {
|
||||
ideapad_input_report(priv, value ? 67 : 66);
|
||||
sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad");
|
||||
} else {
|
||||
ideapad_input_report(priv, 68);
|
||||
}
|
||||
}
|
||||
|
||||
priv->r_touchpad_val = value;
|
||||
}
|
||||
|
||||
static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user