From: Derek J. Clark Date: Tue, 10 Mar 2026 07:29:31 +0000 (+0000) Subject: HID: hid-lenovo-go-s: Add Touchpad Mode Attributes X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e10f5499384d33d4a818f4309b46b974ac1a155e;p=thirdparty%2Fkernel%2Flinux.git HID: hid-lenovo-go-s: Add Touchpad Mode Attributes Adds attributes for managing the touchpad operating modes. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/hid-lenovo-go-s.c b/drivers/hid/hid-lenovo-go-s.c index 97c572cfe66cc..5899cabe950fa 100644 --- a/drivers/hid/hid-lenovo-go-s.c +++ b/drivers/hid/hid-lenovo-go-s.c @@ -47,6 +47,8 @@ static struct hid_gos_cfg { u8 os_mode; u8 rgb_en; u8 tp_en; + u8 tp_linux_mode; + u8 tp_windows_mode; } drvdata; struct gos_cfg_attr { @@ -145,6 +147,22 @@ static const char *const dpad_mode_text[] = { [DIR4] = "4-way", }; +enum touchpad_mode_index { + TP_REL, + TP_ABS, +}; + +static const char *const touchpad_mode_text[] = { + [TP_REL] = "relative", + [TP_ABS] = "absolute", +}; + +enum touchpad_config_index { + CFG_WINDOWS_MODE = 0x03, + CFG_LINUX_MODE, + +}; + static int hid_gos_version_event(u8 *data) { struct version_report *ver_rep = (struct version_report *)data; @@ -204,6 +222,25 @@ static int hid_gos_gamepad_cfg_event(struct command_report *cmd_rep) return ret; } +static int hid_gos_touchpad_event(struct command_report *cmd_rep) +{ + int ret = 0; + + switch (cmd_rep->sub_cmd) { + case CFG_LINUX_MODE: + drvdata.tp_linux_mode = cmd_rep->data[0]; + break; + case CFG_WINDOWS_MODE: + drvdata.tp_windows_mode = cmd_rep->data[0]; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + static int hid_gos_set_event_return(struct command_report *cmd_rep) { if (cmd_rep->data[0] != 0) @@ -251,7 +288,11 @@ static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, case GET_GAMEPAD_CFG: ret = hid_gos_gamepad_cfg_event(cmd_rep); break; + case GET_TP_PARAM: + ret = hid_gos_touchpad_event(cmd_rep); + break; case SET_GAMEPAD_CFG: + case SET_TP_PARAM: ret = hid_gos_set_event_return(cmd_rep); break; default: @@ -530,6 +571,95 @@ static ssize_t gamepad_property_options(struct device *dev, return count; } +static ssize_t touchpad_property_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count, + enum touchpad_config_index index) +{ + size_t size = 1; + u8 val = 0; + int ret; + + switch (index) { + case CFG_WINDOWS_MODE: + ret = sysfs_match_string(touchpad_mode_text, buf); + if (ret < 0) + return ret; + val = ret; + break; + case CFG_LINUX_MODE: + ret = sysfs_match_string(touchpad_mode_text, buf); + if (ret < 0) + return ret; + val = ret; + break; + default: + return -EINVAL; + } + if (!val) + size = 0; + + ret = mcu_property_out(drvdata.hdev, SET_TP_PARAM, index, &val, size); + if (ret < 0) + return ret; + + return count; +} + +static ssize_t touchpad_property_show(struct device *dev, + struct device_attribute *attr, char *buf, + enum touchpad_config_index index) +{ + int ret = 0; + u8 i; + + ret = mcu_property_out(drvdata.hdev, GET_TP_PARAM, index, NULL, 0); + if (ret < 0) + return ret; + + switch (index) { + case CFG_WINDOWS_MODE: + i = drvdata.tp_windows_mode; + break; + case CFG_LINUX_MODE: + i = drvdata.tp_linux_mode; + break; + default: + return -EINVAL; + } + + if (i >= ARRAY_SIZE(touchpad_mode_text)) + return -EINVAL; + + return sysfs_emit(buf, "%s\n", touchpad_mode_text[i]); +} + +static ssize_t touchpad_property_options(struct device *dev, + struct device_attribute *attr, + char *buf, + enum touchpad_config_index index) +{ + size_t count = 0; + unsigned int i; + + switch (index) { + case CFG_WINDOWS_MODE: + case CFG_LINUX_MODE: + for (i = 0; i < ARRAY_SIZE(touchpad_mode_text); i++) { + count += sysfs_emit_at(buf, count, "%s ", + touchpad_mode_text[i]); + } + break; + default: + return count; + } + + if (count) + buf[count - 1] = '\n'; + + return count; +} + static ssize_t mcu_id_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -659,9 +789,21 @@ static struct gos_cfg_attr touchpad_enabled = { FEATURE_TOUCHPAD_ENABLE }; LEGOS_DEVICE_ATTR_RW(touchpad_enabled, "enabled", index, gamepad); static DEVICE_ATTR_RO_NAMED(touchpad_enabled_index, "enabled_index"); +static struct gos_cfg_attr touchpad_linux_mode = { CFG_LINUX_MODE }; +LEGOS_DEVICE_ATTR_RW(touchpad_linux_mode, "linux_mode", index, touchpad); +static DEVICE_ATTR_RO_NAMED(touchpad_linux_mode_index, "linux_mode_index"); + +static struct gos_cfg_attr touchpad_windows_mode = { CFG_WINDOWS_MODE }; +LEGOS_DEVICE_ATTR_RW(touchpad_windows_mode, "windows_mode", index, touchpad); +static DEVICE_ATTR_RO_NAMED(touchpad_windows_mode_index, "windows_mode_index"); + static struct attribute *legos_touchpad_attrs[] = { &dev_attr_touchpad_enabled.attr, &dev_attr_touchpad_enabled_index.attr, + &dev_attr_touchpad_linux_mode.attr, + &dev_attr_touchpad_linux_mode_index.attr, + &dev_attr_touchpad_windows_mode.attr, + &dev_attr_touchpad_windows_mode_index.attr, NULL, };