Skip to content

Commit f31c701

Browse files
committed
[FROM-ML] HID: hid-lenovo-go-s: Add Touchpad Mode Attributes
Adds attributes for managing the touchpad operating modes. Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca> Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
1 parent 9730c0e commit f31c701

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

drivers/hid/hid-lenovo-go-s.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct hid_gos_cfg {
4747
u8 os_mode;
4848
u8 rgb_en;
4949
u8 tp_en;
50+
u8 tp_linux_mode;
51+
u8 tp_windows_mode;
5052
} drvdata;
5153

5254
struct gos_cfg_attr {
@@ -145,6 +147,22 @@ static const char *const dpad_mode_text[] = {
145147
[DIR4] = "4-way",
146148
};
147149

150+
enum touchpad_mode_index {
151+
TP_REL,
152+
TP_ABS,
153+
};
154+
155+
static const char *const touchpad_mode_text[] = {
156+
[TP_REL] = "relative",
157+
[TP_ABS] = "absolute",
158+
};
159+
160+
enum touchpad_config_index {
161+
CFG_WINDOWS_MODE = 0x03,
162+
CFG_LINUX_MODE,
163+
164+
};
165+
148166
static int hid_gos_version_event(u8 *data)
149167
{
150168
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)
204222
return ret;
205223
}
206224

225+
static int hid_gos_touchpad_event(struct command_report *cmd_rep)
226+
{
227+
int ret = 0;
228+
229+
switch (cmd_rep->sub_cmd) {
230+
case CFG_LINUX_MODE:
231+
drvdata.tp_linux_mode = cmd_rep->data[0];
232+
break;
233+
case CFG_WINDOWS_MODE:
234+
drvdata.tp_windows_mode = cmd_rep->data[0];
235+
break;
236+
default:
237+
ret = -EINVAL;
238+
break;
239+
}
240+
241+
return ret;
242+
}
243+
207244
static int hid_gos_set_event_return(struct command_report *cmd_rep)
208245
{
209246
if (cmd_rep->data[0] != 0)
@@ -251,7 +288,11 @@ static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report,
251288
case GET_GAMEPAD_CFG:
252289
ret = hid_gos_gamepad_cfg_event(cmd_rep);
253290
break;
291+
case GET_TP_PARAM:
292+
ret = hid_gos_touchpad_event(cmd_rep);
293+
break;
254294
case SET_GAMEPAD_CFG:
295+
case SET_TP_PARAM:
255296
ret = hid_gos_set_event_return(cmd_rep);
256297
break;
257298
default:
@@ -537,6 +578,95 @@ static ssize_t gamepad_property_options(struct device *dev,
537578
return count;
538579
}
539580

581+
static ssize_t touchpad_property_store(struct device *dev,
582+
struct device_attribute *attr,
583+
const char *buf, size_t count,
584+
enum touchpad_config_index index)
585+
{
586+
size_t size = 1;
587+
u8 val = 0;
588+
int ret;
589+
590+
switch (index) {
591+
case CFG_WINDOWS_MODE:
592+
ret = sysfs_match_string(touchpad_mode_text, buf);
593+
if (ret < 0)
594+
return ret;
595+
val = ret;
596+
break;
597+
case CFG_LINUX_MODE:
598+
ret = sysfs_match_string(touchpad_mode_text, buf);
599+
if (ret < 0)
600+
return ret;
601+
val = ret;
602+
break;
603+
default:
604+
return -EINVAL;
605+
}
606+
if (!val)
607+
size = 0;
608+
609+
ret = mcu_property_out(drvdata.hdev, SET_TP_PARAM, index, &val, size);
610+
if (ret < 0)
611+
return ret;
612+
613+
return count;
614+
}
615+
616+
static ssize_t touchpad_property_show(struct device *dev,
617+
struct device_attribute *attr, char *buf,
618+
enum touchpad_config_index index)
619+
{
620+
int ret = 0;
621+
u8 i;
622+
623+
ret = mcu_property_out(drvdata.hdev, GET_TP_PARAM, index, 0, 0);
624+
if (ret < 0)
625+
return ret;
626+
627+
switch (index) {
628+
case CFG_WINDOWS_MODE:
629+
i = drvdata.tp_windows_mode;
630+
break;
631+
case CFG_LINUX_MODE:
632+
i = drvdata.tp_linux_mode;
633+
break;
634+
default:
635+
return -EINVAL;
636+
}
637+
638+
if (i >= ARRAY_SIZE(touchpad_mode_text))
639+
return -EINVAL;
640+
641+
return sysfs_emit(buf, "%s\n", touchpad_mode_text[i]);
642+
}
643+
644+
static ssize_t touchpad_property_options(struct device *dev,
645+
struct device_attribute *attr,
646+
char *buf,
647+
enum touchpad_config_index index)
648+
{
649+
size_t count = 0;
650+
unsigned int i;
651+
652+
switch (index) {
653+
case CFG_WINDOWS_MODE:
654+
case CFG_LINUX_MODE:
655+
for (i = 0; i < ARRAY_SIZE(touchpad_mode_text); i++) {
656+
count += sysfs_emit_at(buf, count, "%s ",
657+
touchpad_mode_text[i]);
658+
}
659+
break;
660+
default:
661+
return count;
662+
}
663+
664+
if (count)
665+
buf[count - 1] = '\n';
666+
667+
return count;
668+
}
669+
540670
static ssize_t mcu_id_show(struct device *dev, struct device_attribute *attr,
541671
char *buf)
542672
{
@@ -666,9 +796,21 @@ struct gos_cfg_attr touchpad_enabled = { FEATURE_TOUCHPAD_ENABLE };
666796
LEGOS_DEVICE_ATTR_RW(touchpad_enabled, "enabled", index, gamepad);
667797
static DEVICE_ATTR_RO_NAMED(touchpad_enabled_index, "enabled_index");
668798

799+
struct gos_cfg_attr touchpad_linux_mode = { CFG_LINUX_MODE };
800+
LEGOS_DEVICE_ATTR_RW(touchpad_linux_mode, "linux_mode", index, touchpad);
801+
static DEVICE_ATTR_RO_NAMED(touchpad_linux_mode_index, "linux_mode_index");
802+
803+
struct gos_cfg_attr touchpad_windows_mode = { CFG_WINDOWS_MODE };
804+
LEGOS_DEVICE_ATTR_RW(touchpad_windows_mode, "windows_mode", index, touchpad);
805+
static DEVICE_ATTR_RO_NAMED(touchpad_windows_mode_index, "windows_mode_index");
806+
669807
static struct attribute *legos_touchpad_attrs[] = {
670808
&dev_attr_touchpad_enabled.attr,
671809
&dev_attr_touchpad_enabled_index.attr,
810+
&dev_attr_touchpad_linux_mode.attr,
811+
&dev_attr_touchpad_linux_mode_index.attr,
812+
&dev_attr_touchpad_windows_mode.attr,
813+
&dev_attr_touchpad_windows_mode_index.attr,
672814
NULL,
673815
};
674816

0 commit comments

Comments
 (0)