Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * HID driver for Lenovo Legion Go series gamepads.
4 *
5 * Copyright (c) 2026 Derek J. Clark <derekjohn.clark@gmail.com>
6 * Copyright (c) 2026 Valve Corporation
7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/array_size.h>
12#include <linux/cleanup.h>
13#include <linux/completion.h>
14#include <linux/delay.h>
15#include <linux/dev_printk.h>
16#include <linux/device.h>
17#include <linux/device/devres.h>
18#include <linux/hid.h>
19#include <linux/jiffies.h>
20#include <linux/kstrtox.h>
21#include <linux/led-class-multicolor.h>
22#include <linux/mutex.h>
23#include <linux/printk.h>
24#include <linux/sysfs.h>
25#include <linux/types.h>
26#include <linux/unaligned.h>
27#include <linux/usb.h>
28#include <linux/workqueue.h>
29#include <linux/workqueue_types.h>
30
31#include "hid-ids.h"
32
33#define GO_GP_INTF_IN 0x83
34#define GO_OUTPUT_REPORT_ID 0x05
35#define GO_GP_RESET_SUCCESS 0x01
36#define GO_PACKET_SIZE 64
37
38static struct hid_go_cfg {
39 struct delayed_work go_cfg_setup;
40 struct completion send_cmd_complete;
41 struct led_classdev *led_cdev;
42 struct hid_device *hdev;
43 struct mutex cfg_mutex; /*ensure single synchronous output report*/
44 u8 fps_mode;
45 u8 gp_left_auto_sleep_time;
46 u8 gp_left_gyro_cal_status;
47 u8 gp_left_joy_cal_status;
48 u8 gp_left_notify_en;
49 u8 gp_left_rumble_mode;
50 u8 gp_left_trigg_cal_status;
51 u32 gp_left_version_firmware;
52 u8 gp_left_version_gen;
53 u32 gp_left_version_hardware;
54 u32 gp_left_version_product;
55 u32 gp_left_version_protocol;
56 u8 gp_mode;
57 u8 gp_right_auto_sleep_time;
58 u8 gp_right_gyro_cal_status;
59 u8 gp_right_joy_cal_status;
60 u8 gp_right_notify_en;
61 u8 gp_right_rumble_mode;
62 u8 gp_right_trigg_cal_status;
63 u32 gp_right_version_firmware;
64 u8 gp_right_version_gen;
65 u32 gp_right_version_hardware;
66 u32 gp_right_version_product;
67 u32 gp_right_version_protocol;
68 u8 gp_rumble_intensity;
69 u8 imu_left_bypass_en;
70 u8 imu_left_sensor_en;
71 u8 imu_right_bypass_en;
72 u8 imu_right_sensor_en;
73 u32 mcu_version_firmware;
74 u8 mcu_version_gen;
75 u32 mcu_version_hardware;
76 u32 mcu_version_product;
77 u32 mcu_version_protocol;
78 u32 mouse_dpi;
79 u8 os_mode;
80 u8 rgb_effect;
81 u8 rgb_en;
82 u8 rgb_mode;
83 u8 rgb_profile;
84 u8 rgb_speed;
85 u8 tp_en;
86 u8 tp_vibration_en;
87 u8 tp_vibration_intensity;
88 u32 tx_dongle_version_firmware;
89 u8 tx_dongle_version_gen;
90 u32 tx_dongle_version_hardware;
91 u32 tx_dongle_version_product;
92 u32 tx_dongle_version_protocol;
93} drvdata;
94
95struct go_cfg_attr {
96 u8 index;
97};
98
99struct command_report {
100 u8 report_id;
101 u8 id;
102 u8 cmd;
103 u8 sub_cmd;
104 u8 device_type;
105 u8 data[59];
106} __packed;
107
108enum command_id {
109 MCU_CONFIG_DATA = 0x00,
110 OS_MODE_DATA = 0x06,
111 GAMEPAD_DATA = 0x3c,
112};
113
114enum mcu_command_index {
115 GET_VERSION_DATA = 0x02,
116 GET_FEATURE_STATUS,
117 SET_FEATURE_STATUS,
118 GET_MOTOR_CFG,
119 SET_MOTOR_CFG,
120 GET_DPI_CFG,
121 SET_DPI_CFG,
122 SET_TRIGGER_CFG = 0x0a,
123 SET_JOYSTICK_CFG = 0x0c,
124 SET_GYRO_CFG = 0x0e,
125 GET_RGB_CFG,
126 SET_RGB_CFG,
127 GET_DEVICE_STATUS = 0xa0,
128
129};
130
131enum dev_type {
132 UNSPECIFIED,
133 USB_MCU,
134 TX_DONGLE,
135 LEFT_CONTROLLER,
136 RIGHT_CONTROLLER,
137};
138
139enum enabled_status_index {
140 FEATURE_UNKNOWN,
141 FEATURE_ENABLED,
142 FEATURE_DISABLED,
143};
144
145static const char *const enabled_status_text[] = {
146 [FEATURE_UNKNOWN] = "unknown",
147 [FEATURE_ENABLED] = "true",
148 [FEATURE_DISABLED] = "false",
149};
150
151enum version_data_index {
152 PRODUCT_VERSION = 0x02,
153 PROTOCOL_VERSION,
154 FIRMWARE_VERSION,
155 HARDWARE_VERSION,
156 HARDWARE_GENERATION,
157};
158
159enum feature_status_index {
160 FEATURE_RESET_GAMEPAD = 0x02,
161 FEATURE_IMU_BYPASS,
162 FEATURE_IMU_ENABLE = 0x05,
163 FEATURE_TOUCHPAD_ENABLE = 0x07,
164 FEATURE_LIGHT_ENABLE,
165 FEATURE_AUTO_SLEEP_TIME,
166 FEATURE_FPS_SWITCH_STATUS = 0x0b,
167 FEATURE_GAMEPAD_MODE = 0x0e,
168};
169
170#define FEATURE_OS_MODE 0x69
171
172enum fps_switch_status_index {
173 FPS_STATUS_UNKNOWN,
174 GAMEPAD,
175 FPS,
176};
177
178static const char *const fps_switch_text[] = {
179 [FPS_STATUS_UNKNOWN] = "unknown",
180 [GAMEPAD] = "gamepad",
181 [FPS] = "fps",
182};
183
184enum gamepad_mode_index {
185 GAMEPAD_MODE_UNKNOWN,
186 XINPUT,
187 DINPUT,
188};
189
190static const char *const gamepad_mode_text[] = {
191 [GAMEPAD_MODE_UNKNOWN] = "unknown",
192 [XINPUT] = "xinput",
193 [DINPUT] = "dinput",
194};
195
196enum motor_cfg_index {
197 MOTOR_CFG_ALL = 0x01,
198 MOTOR_INTENSITY,
199 VIBRATION_NOTIFY_ENABLE,
200 RUMBLE_MODE,
201 TP_VIBRATION_ENABLE,
202 TP_VIBRATION_INTENSITY,
203};
204
205enum intensity_index {
206 INTENSITY_UNKNOWN,
207 INTENSITY_OFF,
208 INTENSITY_LOW,
209 INTENSITY_MEDIUM,
210 INTENSITY_HIGH,
211};
212
213static const char *const intensity_text[] = {
214 [INTENSITY_UNKNOWN] = "unknown",
215 [INTENSITY_OFF] = "off",
216 [INTENSITY_LOW] = "low",
217 [INTENSITY_MEDIUM] = "medium",
218 [INTENSITY_HIGH] = "high",
219};
220
221enum rumble_mode_index {
222 RUMBLE_MODE_UNKNOWN,
223 RUMBLE_MODE_FPS,
224 RUMBLE_MODE_RACE,
225 RUMBLE_MODE_AVERAGE,
226 RUMBLE_MODE_SPG,
227 RUMBLE_MODE_RPG,
228};
229
230static const char *const rumble_mode_text[] = {
231 [RUMBLE_MODE_UNKNOWN] = "unknown",
232 [RUMBLE_MODE_FPS] = "fps",
233 [RUMBLE_MODE_RACE] = "racing",
234 [RUMBLE_MODE_AVERAGE] = "standard",
235 [RUMBLE_MODE_SPG] = "spg",
236 [RUMBLE_MODE_RPG] = "rpg",
237};
238
239#define FPS_MODE_DPI 0x02
240#define TRIGGER_CALIBRATE 0x04
241#define JOYSTICK_CALIBRATE 0x04
242#define GYRO_CALIBRATE 0x06
243
244enum cal_device_type {
245 CALDEV_GYROSCOPE = 0x01,
246 CALDEV_JOYSTICK,
247 CALDEV_TRIGGER,
248 CALDEV_JOY_TRIGGER,
249};
250
251enum cal_enable {
252 CAL_UNKNOWN,
253 CAL_START,
254 CAL_STOP,
255};
256
257static const char *const cal_enabled_text[] = {
258 [CAL_UNKNOWN] = "unknown",
259 [CAL_START] = "start",
260 [CAL_STOP] = "stop",
261};
262
263enum cal_status_index {
264 CAL_STAT_UNKNOWN,
265 CAL_STAT_SUCCESS,
266 CAL_STAT_FAILURE,
267};
268
269static const char *const cal_status_text[] = {
270 [CAL_STAT_UNKNOWN] = "unknown",
271 [CAL_STAT_SUCCESS] = "success",
272 [CAL_STAT_FAILURE] = "failure",
273};
274
275enum rgb_config_index {
276 LIGHT_CFG_ALL = 0x01,
277 LIGHT_MODE_SEL,
278 LIGHT_PROFILE_SEL,
279 USR_LIGHT_PROFILE_1,
280 USR_LIGHT_PROFILE_2,
281 USR_LIGHT_PROFILE_3,
282};
283
284enum rgb_mode_index {
285 RGB_MODE_UNKNOWN,
286 RGB_MODE_DYNAMIC,
287 RGB_MODE_CUSTOM,
288};
289
290static const char *const rgb_mode_text[] = {
291 [RGB_MODE_UNKNOWN] = "unknown",
292 [RGB_MODE_DYNAMIC] = "dynamic",
293 [RGB_MODE_CUSTOM] = "custom",
294};
295
296enum rgb_effect_index {
297 RGB_EFFECT_MONO,
298 RGB_EFFECT_BREATHE,
299 RGB_EFFECT_CHROMA,
300 RGB_EFFECT_RAINBOW,
301};
302
303static const char *const rgb_effect_text[] = {
304 [RGB_EFFECT_MONO] = "monocolor",
305 [RGB_EFFECT_BREATHE] = "breathe",
306 [RGB_EFFECT_CHROMA] = "chroma",
307 [RGB_EFFECT_RAINBOW] = "rainbow",
308};
309
310enum device_status_index {
311 GET_CAL_STATUS = 0x02,
312 GET_UPGRADE_STATUS,
313 GET_MACRO_REC_STATUS,
314 GET_HOTKEY_TRIGG_STATUS,
315};
316
317enum os_mode_cfg_index {
318 SET_OS_MODE = 0x09,
319 GET_OS_MODE,
320};
321
322enum os_mode_type_index {
323 OS_UNKNOWN,
324 WINDOWS,
325 LINUX,
326};
327
328static const char *const os_mode_text[] = {
329 [OS_UNKNOWN] = "unknown",
330 [WINDOWS] = "windows",
331 [LINUX] = "linux",
332};
333
334static int hid_go_version_event(struct command_report *cmd_rep)
335{
336 switch (cmd_rep->sub_cmd) {
337 case PRODUCT_VERSION:
338 switch (cmd_rep->device_type) {
339 case USB_MCU:
340 drvdata.mcu_version_product =
341 get_unaligned_be32(cmd_rep->data);
342 return 0;
343 case TX_DONGLE:
344 drvdata.tx_dongle_version_product =
345 get_unaligned_be32(cmd_rep->data);
346 return 0;
347 case LEFT_CONTROLLER:
348 drvdata.gp_left_version_product =
349 get_unaligned_be32(cmd_rep->data);
350 return 0;
351 case RIGHT_CONTROLLER:
352 drvdata.gp_right_version_product =
353 get_unaligned_be32(cmd_rep->data);
354 return 0;
355 default:
356 return -EINVAL;
357 }
358 case PROTOCOL_VERSION:
359 switch (cmd_rep->device_type) {
360 case USB_MCU:
361 drvdata.mcu_version_protocol =
362 get_unaligned_be32(cmd_rep->data);
363 return 0;
364 case TX_DONGLE:
365 drvdata.tx_dongle_version_protocol =
366 get_unaligned_be32(cmd_rep->data);
367 return 0;
368 case LEFT_CONTROLLER:
369 drvdata.gp_left_version_protocol =
370 get_unaligned_be32(cmd_rep->data);
371 return 0;
372 case RIGHT_CONTROLLER:
373 drvdata.gp_right_version_protocol =
374 get_unaligned_be32(cmd_rep->data);
375 return 0;
376 default:
377 return -EINVAL;
378 }
379 case FIRMWARE_VERSION:
380 switch (cmd_rep->device_type) {
381 case USB_MCU:
382 drvdata.mcu_version_firmware =
383 get_unaligned_be32(cmd_rep->data);
384 return 0;
385 case TX_DONGLE:
386 drvdata.tx_dongle_version_firmware =
387 get_unaligned_be32(cmd_rep->data);
388 return 0;
389 case LEFT_CONTROLLER:
390 drvdata.gp_left_version_firmware =
391 get_unaligned_be32(cmd_rep->data);
392 return 0;
393 case RIGHT_CONTROLLER:
394 drvdata.gp_right_version_firmware =
395 get_unaligned_be32(cmd_rep->data);
396 return 0;
397 default:
398 return -EINVAL;
399 }
400 case HARDWARE_VERSION:
401 switch (cmd_rep->device_type) {
402 case USB_MCU:
403 drvdata.mcu_version_hardware =
404 get_unaligned_be32(cmd_rep->data);
405 return 0;
406 case TX_DONGLE:
407 drvdata.tx_dongle_version_hardware =
408 get_unaligned_be32(cmd_rep->data);
409 return 0;
410 case LEFT_CONTROLLER:
411 drvdata.gp_left_version_hardware =
412 get_unaligned_be32(cmd_rep->data);
413 return 0;
414 case RIGHT_CONTROLLER:
415 drvdata.gp_right_version_hardware =
416 get_unaligned_be32(cmd_rep->data);
417 return 0;
418 default:
419 return -EINVAL;
420 }
421 case HARDWARE_GENERATION:
422 switch (cmd_rep->device_type) {
423 case USB_MCU:
424 drvdata.mcu_version_gen = cmd_rep->data[0];
425 return 0;
426 case TX_DONGLE:
427 drvdata.tx_dongle_version_gen = cmd_rep->data[0];
428 return 0;
429 case LEFT_CONTROLLER:
430 drvdata.gp_left_version_gen = cmd_rep->data[0];
431 return 0;
432 case RIGHT_CONTROLLER:
433 drvdata.gp_right_version_gen = cmd_rep->data[0];
434 return 0;
435 default:
436 return -EINVAL;
437 }
438 default:
439 return -EINVAL;
440 }
441}
442
443static int hid_go_feature_status_event(struct command_report *cmd_rep)
444{
445 switch (cmd_rep->sub_cmd) {
446 case FEATURE_RESET_GAMEPAD:
447 return 0;
448 case FEATURE_IMU_ENABLE:
449 switch (cmd_rep->device_type) {
450 case LEFT_CONTROLLER:
451 drvdata.imu_left_sensor_en = cmd_rep->data[0];
452 return 0;
453 case RIGHT_CONTROLLER:
454 drvdata.imu_right_sensor_en = cmd_rep->data[0];
455 return 0;
456 default:
457 return -EINVAL;
458 }
459 case FEATURE_IMU_BYPASS:
460 switch (cmd_rep->device_type) {
461 case LEFT_CONTROLLER:
462 drvdata.imu_left_bypass_en = cmd_rep->data[0];
463 return 0;
464 case RIGHT_CONTROLLER:
465 drvdata.imu_right_bypass_en = cmd_rep->data[0];
466 return 0;
467 default:
468 return -EINVAL;
469 }
470 break;
471 case FEATURE_LIGHT_ENABLE:
472 drvdata.rgb_en = cmd_rep->data[0];
473 return 0;
474 case FEATURE_AUTO_SLEEP_TIME:
475 switch (cmd_rep->device_type) {
476 case LEFT_CONTROLLER:
477 drvdata.gp_left_auto_sleep_time = cmd_rep->data[0];
478 return 0;
479 case RIGHT_CONTROLLER:
480 drvdata.gp_right_auto_sleep_time = cmd_rep->data[0];
481 return 0;
482 default:
483 return -EINVAL;
484 }
485 break;
486 case FEATURE_TOUCHPAD_ENABLE:
487 drvdata.tp_en = cmd_rep->data[0];
488 return 0;
489 case FEATURE_GAMEPAD_MODE:
490 drvdata.gp_mode = cmd_rep->data[0];
491 return 0;
492 case FEATURE_FPS_SWITCH_STATUS:
493 drvdata.fps_mode = cmd_rep->data[0];
494 return 0;
495 default:
496 return -EINVAL;
497 }
498}
499
500static int hid_go_motor_event(struct command_report *cmd_rep)
501{
502 switch (cmd_rep->sub_cmd) {
503 case MOTOR_CFG_ALL:
504 return -EINVAL;
505 case MOTOR_INTENSITY:
506 drvdata.gp_rumble_intensity = cmd_rep->data[0];
507 return 0;
508 case VIBRATION_NOTIFY_ENABLE:
509 switch (cmd_rep->device_type) {
510 case LEFT_CONTROLLER:
511 drvdata.gp_left_notify_en = cmd_rep->data[0];
512 return 0;
513 case RIGHT_CONTROLLER:
514 drvdata.gp_right_notify_en = cmd_rep->data[0];
515 return 0;
516 default:
517 return -EINVAL;
518 }
519 break;
520 case RUMBLE_MODE:
521 switch (cmd_rep->device_type) {
522 case LEFT_CONTROLLER:
523 drvdata.gp_left_rumble_mode = cmd_rep->data[0];
524 return 0;
525 case RIGHT_CONTROLLER:
526 drvdata.gp_right_rumble_mode = cmd_rep->data[0];
527 return 0;
528 default:
529 return -EINVAL;
530 }
531 case TP_VIBRATION_ENABLE:
532 drvdata.tp_vibration_en = cmd_rep->data[0];
533 return 0;
534 case TP_VIBRATION_INTENSITY:
535 drvdata.tp_vibration_intensity = cmd_rep->data[0];
536 return 0;
537 }
538 return -EINVAL;
539}
540
541static int hid_go_fps_dpi_event(struct command_report *cmd_rep)
542{
543 if (cmd_rep->sub_cmd != FPS_MODE_DPI)
544 return -EINVAL;
545
546 drvdata.mouse_dpi = get_unaligned_le32(cmd_rep->data);
547
548 return 0;
549}
550
551static int hid_go_light_event(struct command_report *cmd_rep)
552{
553 struct led_classdev_mc *mc_cdev;
554
555 switch (cmd_rep->sub_cmd) {
556 case LIGHT_MODE_SEL:
557 drvdata.rgb_mode = cmd_rep->data[0];
558 return 0;
559 case LIGHT_PROFILE_SEL:
560 drvdata.rgb_profile = cmd_rep->data[0];
561 return 0;
562 case USR_LIGHT_PROFILE_1:
563 case USR_LIGHT_PROFILE_2:
564 case USR_LIGHT_PROFILE_3:
565 mc_cdev = lcdev_to_mccdev(drvdata.led_cdev);
566 drvdata.rgb_effect = cmd_rep->data[0];
567 mc_cdev->subled_info[0].intensity = cmd_rep->data[1];
568 mc_cdev->subled_info[1].intensity = cmd_rep->data[2];
569 mc_cdev->subled_info[2].intensity = cmd_rep->data[3];
570 drvdata.led_cdev->brightness = cmd_rep->data[4];
571 drvdata.rgb_speed = 100 - cmd_rep->data[5];
572 return 0;
573 default:
574 return -EINVAL;
575 }
576}
577
578static int hid_go_device_status_event(struct command_report *cmd_rep)
579{
580 switch (cmd_rep->device_type) {
581 case LEFT_CONTROLLER:
582 switch (cmd_rep->data[0]) {
583 case CALDEV_GYROSCOPE:
584 drvdata.gp_left_gyro_cal_status = cmd_rep->data[1];
585 return 0;
586 case CALDEV_JOYSTICK:
587 drvdata.gp_left_joy_cal_status = cmd_rep->data[1];
588 return 0;
589 case CALDEV_TRIGGER:
590 drvdata.gp_left_trigg_cal_status = cmd_rep->data[1];
591 return 0;
592 default:
593 return -EINVAL;
594 }
595 break;
596 case RIGHT_CONTROLLER:
597 switch (cmd_rep->data[0]) {
598 case CALDEV_GYROSCOPE:
599 drvdata.gp_right_gyro_cal_status = cmd_rep->data[1];
600 return 0;
601 case CALDEV_JOYSTICK:
602 drvdata.gp_right_joy_cal_status = cmd_rep->data[1];
603 return 0;
604 case CALDEV_TRIGGER:
605 drvdata.gp_right_trigg_cal_status = cmd_rep->data[1];
606 return 0;
607 default:
608 return -EINVAL;
609 }
610 break;
611 default:
612 return -EINVAL;
613 }
614}
615
616static int hid_go_os_mode_cfg_event(struct command_report *cmd_rep)
617{
618 switch (cmd_rep->sub_cmd) {
619 case SET_OS_MODE:
620 if (cmd_rep->data[0] != 1)
621 return -EIO;
622 return 0;
623 case GET_OS_MODE:
624 drvdata.os_mode = cmd_rep->data[0];
625 return 0;
626 default:
627 return -EINVAL;
628 }
629}
630
631static int hid_go_set_event_return(struct command_report *cmd_rep)
632{
633 if (cmd_rep->data[0] != 0)
634 return -EIO;
635
636 return 0;
637}
638
639static int get_endpoint_address(struct hid_device *hdev)
640{
641 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
642 struct usb_host_endpoint *ep;
643
644 if (!intf)
645 return -ENODEV;
646
647 ep = intf->cur_altsetting->endpoint;
648 if (!ep)
649 return -ENODEV;
650
651 return ep->desc.bEndpointAddress;
652}
653
654static int hid_go_raw_event(struct hid_device *hdev, struct hid_report *report,
655 u8 *data, int size)
656{
657 struct command_report *cmd_rep;
658 int ep, ret;
659
660 if (size != GO_PACKET_SIZE)
661 goto passthrough;
662
663 ep = get_endpoint_address(hdev);
664 if (ep != GO_GP_INTF_IN)
665 goto passthrough;
666
667 cmd_rep = (struct command_report *)data;
668
669 switch (cmd_rep->id) {
670 case MCU_CONFIG_DATA:
671 switch (cmd_rep->cmd) {
672 case GET_VERSION_DATA:
673 ret = hid_go_version_event(cmd_rep);
674 break;
675 case GET_FEATURE_STATUS:
676 ret = hid_go_feature_status_event(cmd_rep);
677 break;
678 case GET_MOTOR_CFG:
679 ret = hid_go_motor_event(cmd_rep);
680 break;
681 case GET_DPI_CFG:
682 ret = hid_go_fps_dpi_event(cmd_rep);
683 break;
684 case GET_RGB_CFG:
685 ret = hid_go_light_event(cmd_rep);
686 break;
687 case GET_DEVICE_STATUS:
688 ret = hid_go_device_status_event(cmd_rep);
689 break;
690 case SET_FEATURE_STATUS:
691 case SET_MOTOR_CFG:
692 case SET_DPI_CFG:
693 case SET_RGB_CFG:
694 case SET_TRIGGER_CFG:
695 case SET_JOYSTICK_CFG:
696 case SET_GYRO_CFG:
697 ret = hid_go_set_event_return(cmd_rep);
698 break;
699 default:
700 ret = -EINVAL;
701 break;
702 }
703 break;
704 case OS_MODE_DATA:
705 ret = hid_go_os_mode_cfg_event(cmd_rep);
706 break;
707 default:
708 goto passthrough;
709 }
710 dev_dbg(&hdev->dev, "Rx data as raw input report: [%*ph]\n",
711 GO_PACKET_SIZE, data);
712
713 complete(&drvdata.send_cmd_complete);
714 return ret;
715
716passthrough:
717 /* Forward other HID reports so they generate events */
718 hid_input_report(hdev, HID_INPUT_REPORT, data, size, 1);
719 return 0;
720}
721
722static int mcu_property_out(struct hid_device *hdev, u8 id, u8 command,
723 u8 index, enum dev_type device, u8 *data, size_t len)
724{
725 unsigned char *dmabuf __free(kfree) = NULL;
726 u8 header[] = { GO_OUTPUT_REPORT_ID, id, command, index, device };
727 size_t header_size = ARRAY_SIZE(header);
728 int timeout = 50;
729 int ret;
730
731 if (header_size + len > GO_PACKET_SIZE)
732 return -EINVAL;
733
734 guard(mutex)(&drvdata.cfg_mutex);
735 /* We can't use a devm_alloc reusable buffer without side effects during suspend */
736 dmabuf = kzalloc(GO_PACKET_SIZE, GFP_KERNEL);
737 if (!dmabuf)
738 return -ENOMEM;
739
740 memcpy(dmabuf, header, header_size);
741 memcpy(dmabuf + header_size, data, len);
742
743 dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n",
744 GO_PACKET_SIZE, dmabuf);
745
746 ret = hid_hw_output_report(hdev, dmabuf, GO_PACKET_SIZE);
747 if (ret < 0)
748 return ret;
749
750 ret = ret == GO_PACKET_SIZE ? 0 : -EINVAL;
751 if (ret)
752 return ret;
753
754 ret = wait_for_completion_interruptible_timeout(&drvdata.send_cmd_complete,
755 msecs_to_jiffies(timeout));
756
757 if (ret == 0) /* timeout occurred */
758 ret = -EBUSY;
759
760 reinit_completion(&drvdata.send_cmd_complete);
761 return 0;
762}
763
764static ssize_t version_show(struct device *dev, struct device_attribute *attr,
765 char *buf, enum version_data_index index,
766 enum dev_type device_type)
767{
768 ssize_t count = 0;
769 int ret;
770
771 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
772 index, device_type, NULL, 0);
773 if (ret)
774 return ret;
775
776 switch (index) {
777 case PRODUCT_VERSION:
778 switch (device_type) {
779 case USB_MCU:
780 count = sysfs_emit(buf, "%x\n",
781 drvdata.mcu_version_product);
782 break;
783 case TX_DONGLE:
784 count = sysfs_emit(buf, "%x\n",
785 drvdata.tx_dongle_version_product);
786 break;
787 case LEFT_CONTROLLER:
788 count = sysfs_emit(buf, "%x\n",
789 drvdata.gp_left_version_product);
790 break;
791 case RIGHT_CONTROLLER:
792 count = sysfs_emit(buf, "%x\n",
793 drvdata.gp_right_version_product);
794 break;
795 default:
796 return -EINVAL;
797 }
798 break;
799 case PROTOCOL_VERSION:
800 switch (device_type) {
801 case USB_MCU:
802 count = sysfs_emit(buf, "%x\n",
803 drvdata.mcu_version_protocol);
804 break;
805 case TX_DONGLE:
806 count = sysfs_emit(buf, "%x\n",
807 drvdata.tx_dongle_version_protocol);
808 break;
809 case LEFT_CONTROLLER:
810 count = sysfs_emit(buf, "%x\n",
811 drvdata.gp_left_version_protocol);
812 break;
813 case RIGHT_CONTROLLER:
814 count = sysfs_emit(buf, "%x\n",
815 drvdata.gp_right_version_protocol);
816 break;
817 default:
818 return -EINVAL;
819 }
820 break;
821 case FIRMWARE_VERSION:
822 switch (device_type) {
823 case USB_MCU:
824 count = sysfs_emit(buf, "%x\n",
825 drvdata.mcu_version_firmware);
826 break;
827 case TX_DONGLE:
828 count = sysfs_emit(buf, "%x\n",
829 drvdata.tx_dongle_version_firmware);
830 break;
831 case LEFT_CONTROLLER:
832 count = sysfs_emit(buf, "%x\n",
833 drvdata.gp_left_version_firmware);
834 break;
835 case RIGHT_CONTROLLER:
836 count = sysfs_emit(buf, "%x\n",
837 drvdata.gp_right_version_firmware);
838 break;
839 default:
840 return -EINVAL;
841 }
842 break;
843 case HARDWARE_VERSION:
844 switch (device_type) {
845 case USB_MCU:
846 count = sysfs_emit(buf, "%x\n",
847 drvdata.mcu_version_hardware);
848 break;
849 case TX_DONGLE:
850 count = sysfs_emit(buf, "%x\n",
851 drvdata.tx_dongle_version_hardware);
852 break;
853 case LEFT_CONTROLLER:
854 count = sysfs_emit(buf, "%x\n",
855 drvdata.gp_left_version_hardware);
856 break;
857 case RIGHT_CONTROLLER:
858 count = sysfs_emit(buf, "%x\n",
859 drvdata.gp_right_version_hardware);
860 break;
861 default:
862 return -EINVAL;
863 }
864 break;
865 case HARDWARE_GENERATION:
866 switch (device_type) {
867 case USB_MCU:
868 count = sysfs_emit(buf, "%x\n",
869 drvdata.mcu_version_gen);
870 break;
871 case TX_DONGLE:
872 count = sysfs_emit(buf, "%x\n",
873 drvdata.tx_dongle_version_gen);
874 break;
875 case LEFT_CONTROLLER:
876 count = sysfs_emit(buf, "%x\n",
877 drvdata.gp_left_version_gen);
878 break;
879 case RIGHT_CONTROLLER:
880 count = sysfs_emit(buf, "%x\n",
881 drvdata.gp_right_version_gen);
882 break;
883 default:
884 return -EINVAL;
885 }
886 break;
887 }
888
889 return count;
890}
891
892static ssize_t feature_status_store(struct device *dev,
893 struct device_attribute *attr,
894 const char *buf, size_t count,
895 enum feature_status_index index,
896 enum dev_type device_type)
897{
898 size_t size = 1;
899 u8 val = 0;
900 int ret;
901
902 switch (index) {
903 case FEATURE_IMU_ENABLE:
904 case FEATURE_IMU_BYPASS:
905 case FEATURE_LIGHT_ENABLE:
906 case FEATURE_TOUCHPAD_ENABLE:
907 ret = sysfs_match_string(enabled_status_text, buf);
908 val = ret;
909 break;
910 case FEATURE_AUTO_SLEEP_TIME:
911 ret = kstrtou8(buf, 10, &val);
912 break;
913 case FEATURE_RESET_GAMEPAD:
914 ret = kstrtou8(buf, 10, &val);
915 if (val != GO_GP_RESET_SUCCESS)
916 return -EINVAL;
917 break;
918 case FEATURE_FPS_SWITCH_STATUS:
919 ret = sysfs_match_string(fps_switch_text, buf);
920 val = ret;
921 break;
922 case FEATURE_GAMEPAD_MODE:
923 ret = sysfs_match_string(gamepad_mode_text, buf);
924 val = ret;
925 break;
926 default:
927 return -EINVAL;
928 }
929
930 if (ret < 0)
931 return ret;
932
933 if (!val)
934 size = 0;
935
936 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA,
937 SET_FEATURE_STATUS, index, device_type, &val,
938 size);
939 if (ret < 0)
940 return ret;
941
942 return count;
943}
944
945static ssize_t feature_status_show(struct device *dev,
946 struct device_attribute *attr, char *buf,
947 enum feature_status_index index,
948 enum dev_type device_type)
949{
950 ssize_t count = 0;
951 int ret;
952 u8 i;
953
954 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA,
955 GET_FEATURE_STATUS, index, device_type, NULL, 0);
956 if (ret)
957 return ret;
958
959 switch (index) {
960 case FEATURE_IMU_ENABLE:
961 switch (device_type) {
962 case LEFT_CONTROLLER:
963 i = drvdata.imu_left_sensor_en;
964 break;
965 case RIGHT_CONTROLLER:
966 i = drvdata.imu_right_sensor_en;
967 break;
968 default:
969 return -EINVAL;
970 }
971 if (i >= ARRAY_SIZE(enabled_status_text))
972 return -EINVAL;
973
974 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
975 break;
976 case FEATURE_IMU_BYPASS:
977 switch (device_type) {
978 case LEFT_CONTROLLER:
979 i = drvdata.imu_left_bypass_en;
980 break;
981 case RIGHT_CONTROLLER:
982 i = drvdata.imu_right_bypass_en;
983 break;
984 default:
985 return -EINVAL;
986 }
987 if (i >= ARRAY_SIZE(enabled_status_text))
988 return -EINVAL;
989
990 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
991 break;
992 case FEATURE_LIGHT_ENABLE:
993 i = drvdata.rgb_en;
994 if (i >= ARRAY_SIZE(enabled_status_text))
995 return -EINVAL;
996
997 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
998 break;
999 case FEATURE_TOUCHPAD_ENABLE:
1000 i = drvdata.tp_en;
1001 if (i >= ARRAY_SIZE(enabled_status_text))
1002 return -EINVAL;
1003
1004 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
1005 break;
1006 case FEATURE_AUTO_SLEEP_TIME:
1007 switch (device_type) {
1008 case LEFT_CONTROLLER:
1009 i = drvdata.gp_left_auto_sleep_time;
1010 break;
1011 case RIGHT_CONTROLLER:
1012 i = drvdata.gp_right_auto_sleep_time;
1013 break;
1014 default:
1015 return -EINVAL;
1016 }
1017 count = sysfs_emit(buf, "%u\n", i);
1018 break;
1019 case FEATURE_FPS_SWITCH_STATUS:
1020 i = drvdata.fps_mode;
1021 if (i >= ARRAY_SIZE(fps_switch_text))
1022 return -EINVAL;
1023
1024 count = sysfs_emit(buf, "%s\n", fps_switch_text[i]);
1025 break;
1026 case FEATURE_GAMEPAD_MODE:
1027 i = drvdata.gp_mode;
1028 if (i >= ARRAY_SIZE(gamepad_mode_text))
1029 return -EINVAL;
1030
1031 count = sysfs_emit(buf, "%s\n", gamepad_mode_text[i]);
1032 break;
1033 default:
1034 return -EINVAL;
1035 }
1036
1037 return count;
1038}
1039
1040static ssize_t feature_status_options(struct device *dev,
1041 struct device_attribute *attr, char *buf,
1042 enum feature_status_index index)
1043{
1044 ssize_t count = 0;
1045 unsigned int i;
1046
1047 switch (index) {
1048 case FEATURE_IMU_ENABLE:
1049 case FEATURE_IMU_BYPASS:
1050 case FEATURE_LIGHT_ENABLE:
1051 case FEATURE_TOUCHPAD_ENABLE:
1052 for (i = 1; i < ARRAY_SIZE(enabled_status_text); i++) {
1053 count += sysfs_emit_at(buf, count, "%s ",
1054 enabled_status_text[i]);
1055 }
1056 break;
1057 case FEATURE_AUTO_SLEEP_TIME:
1058 return sysfs_emit(buf, "0-255\n");
1059 case FEATURE_FPS_SWITCH_STATUS:
1060 for (i = 1; i < ARRAY_SIZE(fps_switch_text); i++) {
1061 count += sysfs_emit_at(buf, count, "%s ",
1062 fps_switch_text[i]);
1063 }
1064 break;
1065 case FEATURE_GAMEPAD_MODE:
1066 for (i = 1; i < ARRAY_SIZE(gamepad_mode_text); i++) {
1067 count += sysfs_emit_at(buf, count, "%s ",
1068 gamepad_mode_text[i]);
1069 }
1070 break;
1071 default:
1072 return -EINVAL;
1073 }
1074
1075 if (count)
1076 buf[count - 1] = '\n';
1077
1078 return count;
1079}
1080
1081static ssize_t motor_config_store(struct device *dev,
1082 struct device_attribute *attr,
1083 const char *buf, size_t count,
1084 enum motor_cfg_index index,
1085 enum dev_type device_type)
1086{
1087 size_t size = 1;
1088 u8 val = 0;
1089 int ret;
1090
1091 switch (index) {
1092 case MOTOR_CFG_ALL:
1093 return -EINVAL;
1094 case MOTOR_INTENSITY:
1095 ret = sysfs_match_string(intensity_text, buf);
1096 val = ret;
1097 break;
1098 case VIBRATION_NOTIFY_ENABLE:
1099 ret = sysfs_match_string(enabled_status_text, buf);
1100 val = ret;
1101 break;
1102 case RUMBLE_MODE:
1103 ret = sysfs_match_string(rumble_mode_text, buf);
1104 val = ret;
1105 break;
1106 case TP_VIBRATION_ENABLE:
1107 ret = sysfs_match_string(enabled_status_text, buf);
1108 val = ret;
1109 break;
1110 case TP_VIBRATION_INTENSITY:
1111 ret = sysfs_match_string(intensity_text, buf);
1112 val = ret;
1113 break;
1114 }
1115
1116 if (ret < 0)
1117 return ret;
1118
1119 if (!val)
1120 size = 0;
1121
1122 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, SET_MOTOR_CFG,
1123 index, device_type, &val, size);
1124 if (ret < 0)
1125 return ret;
1126
1127 return count;
1128}
1129
1130static ssize_t motor_config_show(struct device *dev,
1131 struct device_attribute *attr, char *buf,
1132 enum motor_cfg_index index,
1133 enum dev_type device_type)
1134{
1135 ssize_t count = 0;
1136 int ret;
1137 u8 i;
1138
1139 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_MOTOR_CFG,
1140 index, device_type, NULL, 0);
1141 if (ret)
1142 return ret;
1143
1144 switch (index) {
1145 case MOTOR_CFG_ALL:
1146 return -EINVAL;
1147 case MOTOR_INTENSITY:
1148 i = drvdata.gp_rumble_intensity;
1149 if (i >= ARRAY_SIZE(intensity_text))
1150 return -EINVAL;
1151
1152 count = sysfs_emit(buf, "%s\n", intensity_text[i]);
1153 break;
1154 case VIBRATION_NOTIFY_ENABLE:
1155 switch (device_type) {
1156 case LEFT_CONTROLLER:
1157 i = drvdata.gp_left_notify_en;
1158 break;
1159 case RIGHT_CONTROLLER:
1160 i = drvdata.gp_right_notify_en;
1161 break;
1162 default:
1163 return -EINVAL;
1164 }
1165 if (i >= ARRAY_SIZE(enabled_status_text))
1166 return -EINVAL;
1167
1168 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
1169 break;
1170 case RUMBLE_MODE:
1171 switch (device_type) {
1172 case LEFT_CONTROLLER:
1173 i = drvdata.gp_left_rumble_mode;
1174 break;
1175 case RIGHT_CONTROLLER:
1176 i = drvdata.gp_right_rumble_mode;
1177 break;
1178 default:
1179 return -EINVAL;
1180 }
1181 if (i >= ARRAY_SIZE(rumble_mode_text))
1182 return -EINVAL;
1183
1184 count = sysfs_emit(buf, "%s\n", rumble_mode_text[i]);
1185 break;
1186 case TP_VIBRATION_ENABLE:
1187 i = drvdata.tp_vibration_en;
1188 if (i >= ARRAY_SIZE(enabled_status_text))
1189 return -EINVAL;
1190
1191 count = sysfs_emit(buf, "%s\n", enabled_status_text[i]);
1192 break;
1193 case TP_VIBRATION_INTENSITY:
1194 i = drvdata.tp_vibration_intensity;
1195 if (i >= ARRAY_SIZE(intensity_text))
1196 return -EINVAL;
1197
1198 count = sysfs_emit(buf, "%s\n", intensity_text[i]);
1199 break;
1200 }
1201
1202 return count;
1203}
1204
1205static ssize_t motor_config_options(struct device *dev,
1206 struct device_attribute *attr, char *buf,
1207 enum motor_cfg_index index)
1208{
1209 ssize_t count = 0;
1210 unsigned int i;
1211
1212 switch (index) {
1213 case MOTOR_CFG_ALL:
1214 break;
1215 case RUMBLE_MODE:
1216 for (i = 1; i < ARRAY_SIZE(rumble_mode_text); i++) {
1217 count += sysfs_emit_at(buf, count, "%s ",
1218 rumble_mode_text[i]);
1219 }
1220 break;
1221 case MOTOR_INTENSITY:
1222 case TP_VIBRATION_INTENSITY:
1223 for (i = 1; i < ARRAY_SIZE(intensity_text); i++) {
1224 count += sysfs_emit_at(buf, count, "%s ",
1225 intensity_text[i]);
1226 }
1227 break;
1228 case VIBRATION_NOTIFY_ENABLE:
1229 case TP_VIBRATION_ENABLE:
1230 for (i = 1; i < ARRAY_SIZE(enabled_status_text); i++) {
1231 count += sysfs_emit_at(buf, count, "%s ",
1232 enabled_status_text[i]);
1233 }
1234 break;
1235 }
1236
1237 if (count)
1238 buf[count - 1] = '\n';
1239
1240 return count;
1241}
1242
1243static ssize_t fps_mode_dpi_store(struct device *dev,
1244 struct device_attribute *attr,
1245 const char *buf, size_t count)
1246
1247{
1248 size_t size = 4;
1249 u32 value;
1250 u8 val[4];
1251 int ret;
1252
1253 ret = kstrtou32(buf, 10, &value);
1254 if (ret)
1255 return ret;
1256
1257 if (value != 500 && value != 800 && value != 1200 && value != 1800)
1258 return -EINVAL;
1259
1260 put_unaligned_le32(value, val);
1261
1262 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, SET_DPI_CFG,
1263 FPS_MODE_DPI, UNSPECIFIED, val, size);
1264 if (ret < 0)
1265 return ret;
1266
1267 return count;
1268}
1269
1270static ssize_t fps_mode_dpi_show(struct device *dev,
1271 struct device_attribute *attr, char *buf)
1272{
1273 int ret;
1274
1275 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_DPI_CFG,
1276 FPS_MODE_DPI, UNSPECIFIED, NULL, 0);
1277 if (ret < 0)
1278 return ret;
1279
1280 return sysfs_emit(buf, "%u\n", drvdata.mouse_dpi);
1281}
1282
1283static ssize_t fps_mode_dpi_index_show(struct device *dev,
1284 struct device_attribute *attr, char *buf)
1285{
1286 return sysfs_emit(buf, "500 800 1200 1800\n");
1287}
1288
1289static ssize_t device_status_show(struct device *dev,
1290 struct device_attribute *attr, char *buf,
1291 enum device_status_index index,
1292 enum dev_type device_type,
1293 enum cal_device_type cal_type)
1294{
1295 u8 i;
1296
1297 switch (index) {
1298 case GET_CAL_STATUS:
1299 switch (device_type) {
1300 case LEFT_CONTROLLER:
1301 switch (cal_type) {
1302 case CALDEV_GYROSCOPE:
1303 i = drvdata.gp_left_gyro_cal_status;
1304 break;
1305 case CALDEV_JOYSTICK:
1306 i = drvdata.gp_left_joy_cal_status;
1307 break;
1308 case CALDEV_TRIGGER:
1309 i = drvdata.gp_left_trigg_cal_status;
1310 break;
1311 default:
1312 return -EINVAL;
1313 }
1314 break;
1315 case RIGHT_CONTROLLER:
1316 switch (cal_type) {
1317 case CALDEV_GYROSCOPE:
1318 i = drvdata.gp_right_gyro_cal_status;
1319 break;
1320 case CALDEV_JOYSTICK:
1321 i = drvdata.gp_right_joy_cal_status;
1322 break;
1323 case CALDEV_TRIGGER:
1324 i = drvdata.gp_right_trigg_cal_status;
1325 break;
1326 default:
1327 return -EINVAL;
1328 }
1329 break;
1330 default:
1331 return -EINVAL;
1332 }
1333 break;
1334 default:
1335 return -EINVAL;
1336 }
1337
1338 if (i >= ARRAY_SIZE(cal_status_text))
1339 return -EINVAL;
1340
1341 return sysfs_emit(buf, "%s\n", cal_status_text[i]);
1342}
1343
1344static ssize_t calibrate_config_store(struct device *dev,
1345 struct device_attribute *attr,
1346 const char *buf, u8 cmd, u8 sub_cmd,
1347 size_t count, enum dev_type device_type)
1348{
1349 size_t size = 1;
1350 u8 val = 0;
1351 int ret;
1352
1353 ret = sysfs_match_string(cal_enabled_text, buf);
1354 if (ret < 0)
1355 return ret;
1356
1357 val = ret;
1358 if (!val)
1359 size = 0;
1360
1361 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, cmd, sub_cmd,
1362 device_type, &val, size);
1363 if (ret < 0)
1364 return ret;
1365
1366 return count;
1367}
1368
1369static ssize_t calibrate_config_options(struct device *dev,
1370 struct device_attribute *attr,
1371 char *buf)
1372{
1373 ssize_t count = 0;
1374 unsigned int i;
1375
1376 for (i = 1; i < ARRAY_SIZE(cal_enabled_text); i++)
1377 count += sysfs_emit_at(buf, count, "%s ", cal_enabled_text[i]);
1378
1379 buf[count - 1] = '\n';
1380
1381 return count;
1382}
1383
1384static ssize_t os_mode_store(struct device *dev, struct device_attribute *attr,
1385 const char *buf, size_t count)
1386{
1387 size_t size = 1;
1388 int ret;
1389 u8 val;
1390
1391 ret = sysfs_match_string(os_mode_text, buf);
1392 if (ret <= 0)
1393 return ret;
1394
1395 val = ret;
1396 ret = mcu_property_out(drvdata.hdev, OS_MODE_DATA, FEATURE_OS_MODE,
1397 SET_OS_MODE, USB_MCU, &val, size);
1398 if (ret < 0)
1399 return ret;
1400
1401 drvdata.os_mode = val;
1402
1403 return count;
1404}
1405
1406static ssize_t os_mode_show(struct device *dev, struct device_attribute *attr,
1407 char *buf)
1408{
1409 ssize_t count = 0;
1410 int ret;
1411 u8 i;
1412
1413 ret = mcu_property_out(drvdata.hdev, OS_MODE_DATA, FEATURE_OS_MODE,
1414 GET_OS_MODE, USB_MCU, NULL, 0);
1415 if (ret)
1416 return ret;
1417
1418 i = drvdata.os_mode;
1419 if (i >= ARRAY_SIZE(os_mode_text))
1420 return -EINVAL;
1421
1422 count = sysfs_emit(buf, "%s\n", os_mode_text[i]);
1423
1424 return count;
1425}
1426
1427static ssize_t os_mode_index_show(struct device *dev,
1428 struct device_attribute *attr, char *buf)
1429{
1430 ssize_t count = 0;
1431 unsigned int i;
1432
1433 for (i = 1; i < ARRAY_SIZE(os_mode_text); i++)
1434 count += sysfs_emit_at(buf, count, "%s ", os_mode_text[i]);
1435
1436 if (count)
1437 buf[count - 1] = '\n';
1438
1439 return count;
1440}
1441
1442static int rgb_cfg_call(struct hid_device *hdev, enum mcu_command_index cmd,
1443 enum rgb_config_index index, u8 *val, size_t size)
1444{
1445 if (cmd != SET_RGB_CFG && cmd != GET_RGB_CFG)
1446 return -EINVAL;
1447
1448 if (index < LIGHT_CFG_ALL || index > USR_LIGHT_PROFILE_3)
1449 return -EINVAL;
1450
1451 return mcu_property_out(hdev, MCU_CONFIG_DATA, cmd, index, UNSPECIFIED,
1452 val, size);
1453}
1454
1455static int rgb_attr_show(void)
1456{
1457 enum rgb_config_index index;
1458
1459 index = drvdata.rgb_profile + 3;
1460
1461 return rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, index, NULL, 0);
1462}
1463
1464static ssize_t rgb_effect_store(struct device *dev,
1465 struct device_attribute *attr, const char *buf,
1466 size_t count)
1467{
1468 struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev);
1469 enum rgb_config_index index;
1470 u8 effect;
1471 int ret;
1472
1473 ret = sysfs_match_string(rgb_effect_text, buf);
1474 if (ret < 0)
1475 return ret;
1476
1477 effect = ret;
1478 index = drvdata.rgb_profile + 3;
1479 u8 rgb_profile[6] = { effect,
1480 mc_cdev->subled_info[0].intensity,
1481 mc_cdev->subled_info[1].intensity,
1482 mc_cdev->subled_info[2].intensity,
1483 drvdata.led_cdev->brightness,
1484 drvdata.rgb_speed };
1485
1486 ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6);
1487 if (ret)
1488 return ret;
1489
1490 drvdata.rgb_effect = effect;
1491 return count;
1492}
1493
1494static ssize_t rgb_effect_show(struct device *dev,
1495 struct device_attribute *attr, char *buf)
1496{
1497 int ret;
1498
1499 ret = rgb_attr_show();
1500 if (ret)
1501 return ret;
1502
1503 if (drvdata.rgb_effect >= ARRAY_SIZE(rgb_effect_text))
1504 return -EINVAL;
1505
1506 return sysfs_emit(buf, "%s\n", rgb_effect_text[drvdata.rgb_effect]);
1507}
1508
1509static ssize_t rgb_effect_index_show(struct device *dev,
1510 struct device_attribute *attr, char *buf)
1511{
1512 ssize_t count = 0;
1513 unsigned int i;
1514
1515 for (i = 0; i < ARRAY_SIZE(rgb_effect_text); i++)
1516 count += sysfs_emit_at(buf, count, "%s ", rgb_effect_text[i]);
1517
1518 if (count)
1519 buf[count - 1] = '\n';
1520
1521 return count;
1522}
1523
1524static ssize_t rgb_speed_store(struct device *dev,
1525 struct device_attribute *attr, const char *buf,
1526 size_t count)
1527{
1528 struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev);
1529 enum rgb_config_index index;
1530 int val = 0;
1531 int ret;
1532
1533 ret = kstrtoint(buf, 10, &val);
1534 if (ret)
1535 return ret;
1536
1537 if (val < 0 || val > 100)
1538 return -EINVAL;
1539
1540 /* This is a delay setting, invert logic for consistency with other drivers */
1541 val = 100 - val;
1542
1543 index = drvdata.rgb_profile + 3;
1544 u8 rgb_profile[6] = { drvdata.rgb_effect,
1545 mc_cdev->subled_info[0].intensity,
1546 mc_cdev->subled_info[1].intensity,
1547 mc_cdev->subled_info[2].intensity,
1548 drvdata.led_cdev->brightness,
1549 val };
1550
1551 ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6);
1552 if (ret)
1553 return ret;
1554
1555 drvdata.rgb_speed = val;
1556
1557 return count;
1558}
1559
1560static ssize_t rgb_speed_show(struct device *dev, struct device_attribute *attr,
1561 char *buf)
1562{
1563 int ret, val;
1564
1565 ret = rgb_attr_show();
1566 if (ret)
1567 return ret;
1568
1569 if (drvdata.rgb_speed > 100)
1570 return -EINVAL;
1571
1572 val = drvdata.rgb_speed;
1573
1574 return sysfs_emit(buf, "%hhu\n", val);
1575}
1576
1577static ssize_t rgb_speed_range_show(struct device *dev,
1578 struct device_attribute *attr, char *buf)
1579{
1580 return sysfs_emit(buf, "0-100\n");
1581}
1582
1583static ssize_t rgb_mode_store(struct device *dev, struct device_attribute *attr,
1584 const char *buf, size_t count)
1585{
1586 int ret;
1587 u8 val;
1588
1589 ret = sysfs_match_string(rgb_mode_text, buf);
1590 if (ret <= 0)
1591 return ret;
1592
1593 val = ret;
1594
1595 ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_MODE_SEL, &val, 1);
1596 if (ret)
1597 return ret;
1598
1599 drvdata.rgb_mode = val;
1600
1601 return count;
1602}
1603
1604static ssize_t rgb_mode_show(struct device *dev, struct device_attribute *attr,
1605 char *buf)
1606{
1607 int ret;
1608
1609 ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_MODE_SEL, NULL, 0);
1610 if (ret)
1611 return ret;
1612
1613 if (drvdata.rgb_mode >= ARRAY_SIZE(rgb_mode_text))
1614 return -EINVAL;
1615
1616 return sysfs_emit(buf, "%s\n", rgb_mode_text[drvdata.rgb_mode]);
1617}
1618
1619static ssize_t rgb_mode_index_show(struct device *dev,
1620 struct device_attribute *attr, char *buf)
1621{
1622 ssize_t count = 0;
1623 unsigned int i;
1624
1625 for (i = 1; i < ARRAY_SIZE(rgb_mode_text); i++)
1626 count += sysfs_emit_at(buf, count, "%s ", rgb_mode_text[i]);
1627
1628 if (count)
1629 buf[count - 1] = '\n';
1630
1631 return count;
1632}
1633
1634static ssize_t rgb_profile_store(struct device *dev,
1635 struct device_attribute *attr, const char *buf,
1636 size_t count)
1637{
1638 size_t size = 1;
1639 int ret;
1640 u8 val;
1641
1642 ret = kstrtou8(buf, 10, &val);
1643 if (ret < 0)
1644 return ret;
1645
1646 if (val < 1 || val > 3)
1647 return -EINVAL;
1648
1649 ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_PROFILE_SEL, &val, size);
1650 if (ret)
1651 return ret;
1652
1653 drvdata.rgb_profile = val;
1654
1655 return count;
1656}
1657
1658static ssize_t rgb_profile_show(struct device *dev,
1659 struct device_attribute *attr, char *buf)
1660{
1661 int ret;
1662
1663 ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_PROFILE_SEL, NULL, 0);
1664 if (ret)
1665 return ret;
1666
1667 if (drvdata.rgb_profile < 1 || drvdata.rgb_profile > 3)
1668 return -EINVAL;
1669
1670 return sysfs_emit(buf, "%hhu\n", drvdata.rgb_profile);
1671}
1672
1673static ssize_t rgb_profile_range_show(struct device *dev,
1674 struct device_attribute *attr, char *buf)
1675{
1676 return sysfs_emit(buf, "1-3\n");
1677}
1678
1679static void hid_go_brightness_set(struct led_classdev *led_cdev,
1680 enum led_brightness brightness)
1681{
1682 struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev);
1683 enum rgb_config_index index;
1684 int ret;
1685
1686 if (brightness > led_cdev->max_brightness) {
1687 dev_err(led_cdev->dev, "Invalid argument\n");
1688 return;
1689 }
1690
1691 index = drvdata.rgb_profile + 3;
1692 u8 rgb_profile[6] = { drvdata.rgb_effect,
1693 mc_cdev->subled_info[0].intensity,
1694 mc_cdev->subled_info[1].intensity,
1695 mc_cdev->subled_info[2].intensity,
1696 brightness,
1697 drvdata.rgb_speed };
1698
1699 ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6);
1700 switch (ret) {
1701 case 0:
1702 led_cdev->brightness = brightness;
1703 break;
1704 case -ENODEV: /* during switch to IAP -ENODEV is expected */
1705 case -ENOSYS: /* during rmmod -ENOSYS is expected */
1706 dev_dbg(led_cdev->dev, "Failed to write RGB profile: %i\n", ret);
1707 break;
1708 default:
1709 dev_err(led_cdev->dev, "Failed to write RGB profile: %i\n", ret);
1710 }
1711}
1712
1713#define LEGO_DEVICE_ATTR_RW(_name, _attrname, _dtype, _rtype, _group) \
1714 static ssize_t _name##_store(struct device *dev, \
1715 struct device_attribute *attr, \
1716 const char *buf, size_t count) \
1717 { \
1718 return _group##_store(dev, attr, buf, count, _name.index, \
1719 _dtype); \
1720 } \
1721 static ssize_t _name##_show(struct device *dev, \
1722 struct device_attribute *attr, char *buf) \
1723 { \
1724 return _group##_show(dev, attr, buf, _name.index, _dtype); \
1725 } \
1726 static ssize_t _name##_##_rtype##_show( \
1727 struct device *dev, struct device_attribute *attr, char *buf) \
1728 { \
1729 return _group##_options(dev, attr, buf, _name.index); \
1730 } \
1731 static DEVICE_ATTR_RW_NAMED(_name, _attrname)
1732
1733#define LEGO_DEVICE_ATTR_WO(_name, _attrname, _dtype, _group) \
1734 static ssize_t _name##_store(struct device *dev, \
1735 struct device_attribute *attr, \
1736 const char *buf, size_t count) \
1737 { \
1738 return _group##_store(dev, attr, buf, count, _name.index, \
1739 _dtype); \
1740 } \
1741 static DEVICE_ATTR_WO_NAMED(_name, _attrname)
1742
1743#define LEGO_DEVICE_ATTR_RO(_name, _attrname, _dtype, _group) \
1744 static ssize_t _name##_show(struct device *dev, \
1745 struct device_attribute *attr, char *buf) \
1746 { \
1747 return _group##_show(dev, attr, buf, _name.index, _dtype); \
1748 } \
1749 static DEVICE_ATTR_RO_NAMED(_name, _attrname)
1750
1751#define LEGO_CAL_DEVICE_ATTR(_name, _attrname, _scmd, _dtype, _rtype) \
1752 static ssize_t _name##_store(struct device *dev, \
1753 struct device_attribute *attr, \
1754 const char *buf, size_t count) \
1755 { \
1756 return calibrate_config_store(dev, attr, buf, _name.index, \
1757 _scmd, count, _dtype); \
1758 } \
1759 static ssize_t _name##_##_rtype##_show( \
1760 struct device *dev, struct device_attribute *attr, char *buf) \
1761 { \
1762 return calibrate_config_options(dev, attr, buf); \
1763 } \
1764 static DEVICE_ATTR_WO_NAMED(_name, _attrname)
1765
1766#define LEGO_DEVICE_STATUS_ATTR(_name, _attrname, _scmd, _dtype) \
1767 static ssize_t _name##_show(struct device *dev, \
1768 struct device_attribute *attr, char *buf) \
1769 { \
1770 return device_status_show(dev, attr, buf, _name.index, _scmd, \
1771 _dtype); \
1772 } \
1773 static DEVICE_ATTR_RO_NAMED(_name, _attrname)
1774
1775/* Gamepad - MCU */
1776static struct go_cfg_attr version_product_mcu = { PRODUCT_VERSION };
1777LEGO_DEVICE_ATTR_RO(version_product_mcu, "product_version", USB_MCU, version);
1778
1779static struct go_cfg_attr version_protocol_mcu = { PROTOCOL_VERSION };
1780LEGO_DEVICE_ATTR_RO(version_protocol_mcu, "protocol_version", USB_MCU, version);
1781
1782static struct go_cfg_attr version_firmware_mcu = { FIRMWARE_VERSION };
1783LEGO_DEVICE_ATTR_RO(version_firmware_mcu, "firmware_version", USB_MCU, version);
1784
1785static struct go_cfg_attr version_hardware_mcu = { HARDWARE_VERSION };
1786LEGO_DEVICE_ATTR_RO(version_hardware_mcu, "hardware_version", USB_MCU, version);
1787
1788static struct go_cfg_attr version_gen_mcu = { HARDWARE_GENERATION };
1789LEGO_DEVICE_ATTR_RO(version_gen_mcu, "hardware_generation", USB_MCU, version);
1790
1791static struct go_cfg_attr fps_switch_status = { FEATURE_FPS_SWITCH_STATUS };
1792LEGO_DEVICE_ATTR_RO(fps_switch_status, "fps_switch_status", UNSPECIFIED,
1793 feature_status);
1794
1795static struct go_cfg_attr gamepad_mode = { FEATURE_GAMEPAD_MODE };
1796LEGO_DEVICE_ATTR_RW(gamepad_mode, "mode", UNSPECIFIED, index, feature_status);
1797static DEVICE_ATTR_RO_NAMED(gamepad_mode_index, "mode_index");
1798
1799static struct go_cfg_attr reset_mcu = { FEATURE_RESET_GAMEPAD };
1800LEGO_DEVICE_ATTR_WO(reset_mcu, "reset_mcu", USB_MCU, feature_status);
1801
1802static struct go_cfg_attr gamepad_rumble_intensity = { MOTOR_INTENSITY };
1803LEGO_DEVICE_ATTR_RW(gamepad_rumble_intensity, "rumble_intensity", UNSPECIFIED,
1804 index, motor_config);
1805static DEVICE_ATTR_RO_NAMED(gamepad_rumble_intensity_index,
1806 "rumble_intensity_index");
1807
1808static DEVICE_ATTR_RW(fps_mode_dpi);
1809static DEVICE_ATTR_RO(fps_mode_dpi_index);
1810
1811static DEVICE_ATTR_RW(os_mode);
1812static DEVICE_ATTR_RO(os_mode_index);
1813
1814static struct attribute *mcu_attrs[] = {
1815 &dev_attr_fps_mode_dpi.attr,
1816 &dev_attr_fps_mode_dpi_index.attr,
1817 &dev_attr_fps_switch_status.attr,
1818 &dev_attr_gamepad_mode.attr,
1819 &dev_attr_gamepad_mode_index.attr,
1820 &dev_attr_gamepad_rumble_intensity.attr,
1821 &dev_attr_gamepad_rumble_intensity_index.attr,
1822 &dev_attr_os_mode.attr,
1823 &dev_attr_os_mode_index.attr,
1824 &dev_attr_reset_mcu.attr,
1825 &dev_attr_version_firmware_mcu.attr,
1826 &dev_attr_version_gen_mcu.attr,
1827 &dev_attr_version_hardware_mcu.attr,
1828 &dev_attr_version_product_mcu.attr,
1829 &dev_attr_version_protocol_mcu.attr,
1830 NULL,
1831};
1832
1833static const struct attribute_group mcu_attr_group = {
1834 .attrs = mcu_attrs,
1835};
1836
1837/* Gamepad - TX Dongle */
1838static struct go_cfg_attr version_product_tx_dongle = { PRODUCT_VERSION };
1839LEGO_DEVICE_ATTR_RO(version_product_tx_dongle, "product_version", TX_DONGLE, version);
1840
1841static struct go_cfg_attr version_protocol_tx_dongle = { PROTOCOL_VERSION };
1842LEGO_DEVICE_ATTR_RO(version_protocol_tx_dongle, "protocol_version", TX_DONGLE, version);
1843
1844static struct go_cfg_attr version_firmware_tx_dongle = { FIRMWARE_VERSION };
1845LEGO_DEVICE_ATTR_RO(version_firmware_tx_dongle, "firmware_version", TX_DONGLE, version);
1846
1847static struct go_cfg_attr version_hardware_tx_dongle = { HARDWARE_VERSION };
1848LEGO_DEVICE_ATTR_RO(version_hardware_tx_dongle, "hardware_version", TX_DONGLE, version);
1849
1850static struct go_cfg_attr version_gen_tx_dongle = { HARDWARE_GENERATION };
1851LEGO_DEVICE_ATTR_RO(version_gen_tx_dongle, "hardware_generation", TX_DONGLE, version);
1852
1853static struct go_cfg_attr reset_tx_dongle = { FEATURE_RESET_GAMEPAD };
1854LEGO_DEVICE_ATTR_RO(reset_tx_dongle, "reset", TX_DONGLE, feature_status);
1855
1856static struct attribute *tx_dongle_attrs[] = {
1857 &dev_attr_reset_tx_dongle.attr,
1858 &dev_attr_version_hardware_tx_dongle.attr,
1859 &dev_attr_version_firmware_tx_dongle.attr,
1860 &dev_attr_version_gen_tx_dongle.attr,
1861 &dev_attr_version_product_tx_dongle.attr,
1862 &dev_attr_version_protocol_tx_dongle.attr,
1863 NULL,
1864};
1865
1866static const struct attribute_group tx_dongle_attr_group = {
1867 .name = "tx_dongle",
1868 .attrs = tx_dongle_attrs,
1869};
1870
1871/* Gamepad - Left */
1872static struct go_cfg_attr version_product_left = { PRODUCT_VERSION };
1873LEGO_DEVICE_ATTR_RO(version_product_left, "product_version", LEFT_CONTROLLER, version);
1874
1875static struct go_cfg_attr version_protocol_left = { PROTOCOL_VERSION };
1876LEGO_DEVICE_ATTR_RO(version_protocol_left, "protocol_version", LEFT_CONTROLLER, version);
1877
1878static struct go_cfg_attr version_firmware_left = { FIRMWARE_VERSION };
1879LEGO_DEVICE_ATTR_RO(version_firmware_left, "firmware_version", LEFT_CONTROLLER, version);
1880
1881static struct go_cfg_attr version_hardware_left = { HARDWARE_VERSION };
1882LEGO_DEVICE_ATTR_RO(version_hardware_left, "hardware_version", LEFT_CONTROLLER, version);
1883
1884static struct go_cfg_attr version_gen_left = { HARDWARE_GENERATION };
1885LEGO_DEVICE_ATTR_RO(version_gen_left, "hardware_generation", LEFT_CONTROLLER, version);
1886
1887static struct go_cfg_attr auto_sleep_time_left = { FEATURE_AUTO_SLEEP_TIME };
1888LEGO_DEVICE_ATTR_RW(auto_sleep_time_left, "auto_sleep_time", LEFT_CONTROLLER,
1889 range, feature_status);
1890static DEVICE_ATTR_RO_NAMED(auto_sleep_time_left_range,
1891 "auto_sleep_time_range");
1892
1893static struct go_cfg_attr imu_bypass_left = { FEATURE_IMU_BYPASS };
1894LEGO_DEVICE_ATTR_RW(imu_bypass_left, "imu_bypass_enabled", LEFT_CONTROLLER,
1895 index, feature_status);
1896static DEVICE_ATTR_RO_NAMED(imu_bypass_left_index, "imu_bypass_enabled_index");
1897
1898static struct go_cfg_attr imu_enabled_left = { FEATURE_IMU_ENABLE };
1899LEGO_DEVICE_ATTR_RW(imu_enabled_left, "imu_enabled", LEFT_CONTROLLER, index,
1900 feature_status);
1901static DEVICE_ATTR_RO_NAMED(imu_enabled_left_index, "imu_enabled_index");
1902
1903static struct go_cfg_attr reset_left = { FEATURE_RESET_GAMEPAD };
1904LEGO_DEVICE_ATTR_WO(reset_left, "reset", LEFT_CONTROLLER, feature_status);
1905
1906static struct go_cfg_attr rumble_mode_left = { RUMBLE_MODE };
1907LEGO_DEVICE_ATTR_RW(rumble_mode_left, "rumble_mode", LEFT_CONTROLLER, index,
1908 motor_config);
1909static DEVICE_ATTR_RO_NAMED(rumble_mode_left_index, "rumble_mode_index");
1910
1911static struct go_cfg_attr rumble_notification_left = { VIBRATION_NOTIFY_ENABLE };
1912LEGO_DEVICE_ATTR_RW(rumble_notification_left, "rumble_notification",
1913 LEFT_CONTROLLER, index, motor_config);
1914static DEVICE_ATTR_RO_NAMED(rumble_notification_left_index,
1915 "rumble_notification_index");
1916
1917static struct go_cfg_attr cal_trigg_left = { TRIGGER_CALIBRATE };
1918LEGO_CAL_DEVICE_ATTR(cal_trigg_left, "calibrate_trigger", SET_TRIGGER_CFG,
1919 LEFT_CONTROLLER, index);
1920static DEVICE_ATTR_RO_NAMED(cal_trigg_left_index, "calibrate_trigger_index");
1921
1922static struct go_cfg_attr cal_joy_left = { JOYSTICK_CALIBRATE };
1923LEGO_CAL_DEVICE_ATTR(cal_joy_left, "calibrate_joystick", SET_JOYSTICK_CFG,
1924 LEFT_CONTROLLER, index);
1925static DEVICE_ATTR_RO_NAMED(cal_joy_left_index, "calibrate_joystick_index");
1926
1927static struct go_cfg_attr cal_gyro_left = { GYRO_CALIBRATE };
1928LEGO_CAL_DEVICE_ATTR(cal_gyro_left, "calibrate_gyro", SET_GYRO_CFG,
1929 LEFT_CONTROLLER, index);
1930static DEVICE_ATTR_RO_NAMED(cal_gyro_left_index, "calibrate_gyro_index");
1931
1932static struct go_cfg_attr cal_trigg_left_status = { GET_CAL_STATUS };
1933LEGO_DEVICE_STATUS_ATTR(cal_trigg_left_status, "calibrate_trigger_status",
1934 LEFT_CONTROLLER, CALDEV_TRIGGER);
1935
1936static struct go_cfg_attr cal_joy_left_status = { GET_CAL_STATUS };
1937LEGO_DEVICE_STATUS_ATTR(cal_joy_left_status, "calibrate_joystick_status",
1938 LEFT_CONTROLLER, CALDEV_JOYSTICK);
1939
1940static struct go_cfg_attr cal_gyro_left_status = { GET_CAL_STATUS };
1941LEGO_DEVICE_STATUS_ATTR(cal_gyro_left_status, "calibrate_gyro_status",
1942 LEFT_CONTROLLER, CALDEV_GYROSCOPE);
1943
1944static struct attribute *left_gamepad_attrs[] = {
1945 &dev_attr_auto_sleep_time_left.attr,
1946 &dev_attr_auto_sleep_time_left_range.attr,
1947 &dev_attr_cal_gyro_left.attr,
1948 &dev_attr_cal_gyro_left_index.attr,
1949 &dev_attr_cal_gyro_left_status.attr,
1950 &dev_attr_cal_joy_left.attr,
1951 &dev_attr_cal_joy_left_index.attr,
1952 &dev_attr_cal_joy_left_status.attr,
1953 &dev_attr_cal_trigg_left.attr,
1954 &dev_attr_cal_trigg_left_index.attr,
1955 &dev_attr_cal_trigg_left_status.attr,
1956 &dev_attr_imu_bypass_left.attr,
1957 &dev_attr_imu_bypass_left_index.attr,
1958 &dev_attr_imu_enabled_left.attr,
1959 &dev_attr_imu_enabled_left_index.attr,
1960 &dev_attr_reset_left.attr,
1961 &dev_attr_rumble_mode_left.attr,
1962 &dev_attr_rumble_mode_left_index.attr,
1963 &dev_attr_rumble_notification_left.attr,
1964 &dev_attr_rumble_notification_left_index.attr,
1965 &dev_attr_version_hardware_left.attr,
1966 &dev_attr_version_firmware_left.attr,
1967 &dev_attr_version_gen_left.attr,
1968 &dev_attr_version_product_left.attr,
1969 &dev_attr_version_protocol_left.attr,
1970 NULL,
1971};
1972
1973static const struct attribute_group left_gamepad_attr_group = {
1974 .name = "left_handle",
1975 .attrs = left_gamepad_attrs,
1976};
1977
1978/* Gamepad - Right */
1979static struct go_cfg_attr version_product_right = { PRODUCT_VERSION };
1980LEGO_DEVICE_ATTR_RO(version_product_right, "product_version", RIGHT_CONTROLLER, version);
1981
1982static struct go_cfg_attr version_protocol_right = { PROTOCOL_VERSION };
1983LEGO_DEVICE_ATTR_RO(version_protocol_right, "protocol_version", RIGHT_CONTROLLER, version);
1984
1985static struct go_cfg_attr version_firmware_right = { FIRMWARE_VERSION };
1986LEGO_DEVICE_ATTR_RO(version_firmware_right, "firmware_version", RIGHT_CONTROLLER, version);
1987
1988static struct go_cfg_attr version_hardware_right = { HARDWARE_VERSION };
1989LEGO_DEVICE_ATTR_RO(version_hardware_right, "hardware_version", RIGHT_CONTROLLER, version);
1990
1991static struct go_cfg_attr version_gen_right = { HARDWARE_GENERATION };
1992LEGO_DEVICE_ATTR_RO(version_gen_right, "hardware_generation", RIGHT_CONTROLLER, version);
1993
1994static struct go_cfg_attr auto_sleep_time_right = { FEATURE_AUTO_SLEEP_TIME };
1995LEGO_DEVICE_ATTR_RW(auto_sleep_time_right, "auto_sleep_time", RIGHT_CONTROLLER,
1996 range, feature_status);
1997static DEVICE_ATTR_RO_NAMED(auto_sleep_time_right_range,
1998 "auto_sleep_time_range");
1999
2000static struct go_cfg_attr imu_bypass_right = { FEATURE_IMU_BYPASS };
2001LEGO_DEVICE_ATTR_RW(imu_bypass_right, "imu_bypass_enabled", RIGHT_CONTROLLER,
2002 index, feature_status);
2003static DEVICE_ATTR_RO_NAMED(imu_bypass_right_index, "imu_bypass_enabled_index");
2004
2005static struct go_cfg_attr imu_enabled_right = { FEATURE_IMU_BYPASS };
2006LEGO_DEVICE_ATTR_RW(imu_enabled_right, "imu_enabled", RIGHT_CONTROLLER, index,
2007 feature_status);
2008static DEVICE_ATTR_RO_NAMED(imu_enabled_right_index, "imu_enabled_index");
2009
2010static struct go_cfg_attr reset_right = { FEATURE_RESET_GAMEPAD };
2011LEGO_DEVICE_ATTR_WO(reset_right, "reset", LEFT_CONTROLLER, feature_status);
2012
2013static struct go_cfg_attr rumble_mode_right = { RUMBLE_MODE };
2014LEGO_DEVICE_ATTR_RW(rumble_mode_right, "rumble_mode", RIGHT_CONTROLLER, index,
2015 motor_config);
2016static DEVICE_ATTR_RO_NAMED(rumble_mode_right_index, "rumble_mode_index");
2017
2018static struct go_cfg_attr rumble_notification_right = { VIBRATION_NOTIFY_ENABLE };
2019LEGO_DEVICE_ATTR_RW(rumble_notification_right, "rumble_notification",
2020 RIGHT_CONTROLLER, index, motor_config);
2021static DEVICE_ATTR_RO_NAMED(rumble_notification_right_index,
2022 "rumble_notification_index");
2023
2024static struct go_cfg_attr cal_trigg_right = { TRIGGER_CALIBRATE };
2025LEGO_CAL_DEVICE_ATTR(cal_trigg_right, "calibrate_trigger", SET_TRIGGER_CFG,
2026 RIGHT_CONTROLLER, index);
2027static DEVICE_ATTR_RO_NAMED(cal_trigg_right_index, "calibrate_trigger_index");
2028
2029static struct go_cfg_attr cal_joy_right = { JOYSTICK_CALIBRATE };
2030LEGO_CAL_DEVICE_ATTR(cal_joy_right, "calibrate_joystick", SET_JOYSTICK_CFG,
2031 RIGHT_CONTROLLER, index);
2032static DEVICE_ATTR_RO_NAMED(cal_joy_right_index, "calibrate_joystick_index");
2033
2034static struct go_cfg_attr cal_gyro_right = { GYRO_CALIBRATE };
2035LEGO_CAL_DEVICE_ATTR(cal_gyro_right, "calibrate_gyro", SET_GYRO_CFG,
2036 RIGHT_CONTROLLER, index);
2037static DEVICE_ATTR_RO_NAMED(cal_gyro_right_index, "calibrate_gyro_index");
2038
2039static struct go_cfg_attr cal_trigg_right_status = { GET_CAL_STATUS };
2040LEGO_DEVICE_STATUS_ATTR(cal_trigg_right_status, "calibrate_trigger_status",
2041 RIGHT_CONTROLLER, CALDEV_TRIGGER);
2042
2043static struct go_cfg_attr cal_joy_right_status = { GET_CAL_STATUS };
2044LEGO_DEVICE_STATUS_ATTR(cal_joy_right_status, "calibrate_joystick_status",
2045 RIGHT_CONTROLLER, CALDEV_JOYSTICK);
2046
2047static struct go_cfg_attr cal_gyro_right_status = { GET_CAL_STATUS };
2048LEGO_DEVICE_STATUS_ATTR(cal_gyro_right_status, "calibrate_gyro_status",
2049 RIGHT_CONTROLLER, CALDEV_GYROSCOPE);
2050
2051static struct attribute *right_gamepad_attrs[] = {
2052 &dev_attr_auto_sleep_time_right.attr,
2053 &dev_attr_auto_sleep_time_right_range.attr,
2054 &dev_attr_cal_gyro_right.attr,
2055 &dev_attr_cal_gyro_right_index.attr,
2056 &dev_attr_cal_gyro_right_status.attr,
2057 &dev_attr_cal_joy_right.attr,
2058 &dev_attr_cal_joy_right_index.attr,
2059 &dev_attr_cal_joy_right_status.attr,
2060 &dev_attr_cal_trigg_right.attr,
2061 &dev_attr_cal_trigg_right_index.attr,
2062 &dev_attr_cal_trigg_right_status.attr,
2063 &dev_attr_imu_bypass_right.attr,
2064 &dev_attr_imu_bypass_right_index.attr,
2065 &dev_attr_imu_enabled_right.attr,
2066 &dev_attr_imu_enabled_right_index.attr,
2067 &dev_attr_reset_right.attr,
2068 &dev_attr_rumble_mode_right.attr,
2069 &dev_attr_rumble_mode_right_index.attr,
2070 &dev_attr_rumble_notification_right.attr,
2071 &dev_attr_rumble_notification_right_index.attr,
2072 &dev_attr_version_hardware_right.attr,
2073 &dev_attr_version_firmware_right.attr,
2074 &dev_attr_version_gen_right.attr,
2075 &dev_attr_version_product_right.attr,
2076 &dev_attr_version_protocol_right.attr,
2077 NULL,
2078};
2079
2080static const struct attribute_group right_gamepad_attr_group = {
2081 .name = "right_handle",
2082 .attrs = right_gamepad_attrs,
2083};
2084
2085/* Touchpad */
2086static struct go_cfg_attr touchpad_enabled = { FEATURE_TOUCHPAD_ENABLE };
2087LEGO_DEVICE_ATTR_RW(touchpad_enabled, "enabled", UNSPECIFIED, index,
2088 feature_status);
2089static DEVICE_ATTR_RO_NAMED(touchpad_enabled_index, "enabled_index");
2090
2091static struct go_cfg_attr touchpad_vibration_enabled = { TP_VIBRATION_ENABLE };
2092LEGO_DEVICE_ATTR_RW(touchpad_vibration_enabled, "vibration_enabled", UNSPECIFIED,
2093 index, motor_config);
2094static DEVICE_ATTR_RO_NAMED(touchpad_vibration_enabled_index,
2095 "vibration_enabled_index");
2096
2097static struct go_cfg_attr touchpad_vibration_intensity = { TP_VIBRATION_INTENSITY };
2098LEGO_DEVICE_ATTR_RW(touchpad_vibration_intensity, "vibration_intensity",
2099 UNSPECIFIED, index, motor_config);
2100static DEVICE_ATTR_RO_NAMED(touchpad_vibration_intensity_index,
2101 "vibration_intensity_index");
2102
2103static struct attribute *touchpad_attrs[] = {
2104 &dev_attr_touchpad_enabled.attr,
2105 &dev_attr_touchpad_enabled_index.attr,
2106 &dev_attr_touchpad_vibration_enabled.attr,
2107 &dev_attr_touchpad_vibration_enabled_index.attr,
2108 &dev_attr_touchpad_vibration_intensity.attr,
2109 &dev_attr_touchpad_vibration_intensity_index.attr,
2110 NULL,
2111};
2112
2113static const struct attribute_group touchpad_attr_group = {
2114 .name = "touchpad",
2115 .attrs = touchpad_attrs,
2116};
2117
2118static const struct attribute_group *top_level_attr_groups[] = {
2119 &mcu_attr_group, &tx_dongle_attr_group,
2120 &left_gamepad_attr_group, &right_gamepad_attr_group,
2121 &touchpad_attr_group, NULL,
2122};
2123
2124/* RGB */
2125static struct go_cfg_attr rgb_enabled = { FEATURE_LIGHT_ENABLE };
2126
2127LEGO_DEVICE_ATTR_RW(rgb_enabled, "enabled", UNSPECIFIED, index, feature_status);
2128static DEVICE_ATTR_RO_NAMED(rgb_effect_index, "effect_index");
2129static DEVICE_ATTR_RO_NAMED(rgb_enabled_index, "enabled_index");
2130static DEVICE_ATTR_RO_NAMED(rgb_mode_index, "mode_index");
2131static DEVICE_ATTR_RO_NAMED(rgb_profile_range, "profile_range");
2132static DEVICE_ATTR_RO_NAMED(rgb_speed_range, "speed_range");
2133static DEVICE_ATTR_RW_NAMED(rgb_effect, "effect");
2134static DEVICE_ATTR_RW_NAMED(rgb_mode, "mode");
2135static DEVICE_ATTR_RW_NAMED(rgb_profile, "profile");
2136static DEVICE_ATTR_RW_NAMED(rgb_speed, "speed");
2137
2138static struct attribute *go_rgb_attrs[] = {
2139 &dev_attr_rgb_effect.attr,
2140 &dev_attr_rgb_effect_index.attr,
2141 &dev_attr_rgb_enabled.attr,
2142 &dev_attr_rgb_enabled_index.attr,
2143 &dev_attr_rgb_mode.attr,
2144 &dev_attr_rgb_mode_index.attr,
2145 &dev_attr_rgb_profile.attr,
2146 &dev_attr_rgb_profile_range.attr,
2147 &dev_attr_rgb_speed.attr,
2148 &dev_attr_rgb_speed_range.attr,
2149 NULL,
2150};
2151
2152static struct attribute_group rgb_attr_group = {
2153 .attrs = go_rgb_attrs,
2154};
2155
2156static struct mc_subled go_rgb_subled_info[] = {
2157 {
2158 .color_index = LED_COLOR_ID_RED,
2159 .brightness = 0x50,
2160 .intensity = 0x24,
2161 .channel = 0x1,
2162 },
2163 {
2164 .color_index = LED_COLOR_ID_GREEN,
2165 .brightness = 0x50,
2166 .intensity = 0x22,
2167 .channel = 0x2,
2168 },
2169 {
2170 .color_index = LED_COLOR_ID_BLUE,
2171 .brightness = 0x50,
2172 .intensity = 0x99,
2173 .channel = 0x3,
2174 },
2175};
2176
2177static struct led_classdev_mc go_cdev_rgb = {
2178 .led_cdev = {
2179 .name = "go:rgb:joystick_rings",
2180 .color = LED_COLOR_ID_RGB,
2181 .brightness = 0x50,
2182 .max_brightness = 0x64,
2183 .brightness_set = hid_go_brightness_set,
2184 },
2185 .num_colors = ARRAY_SIZE(go_rgb_subled_info),
2186 .subled_info = go_rgb_subled_info,
2187};
2188
2189static void cfg_setup(struct work_struct *work)
2190{
2191 int ret;
2192
2193 /* MCU Version Attrs */
2194 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2195 PRODUCT_VERSION, USB_MCU, NULL, 0);
2196 if (ret < 0) {
2197 dev_err(&drvdata.hdev->dev,
2198 "Failed to retrieve USB_MCU Product Version: %i\n", ret);
2199 return;
2200 }
2201
2202 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2203 PROTOCOL_VERSION, USB_MCU, NULL, 0);
2204 if (ret < 0) {
2205 dev_err(&drvdata.hdev->dev,
2206 "Failed to retrieve USB_MCU Protocol Version: %i\n", ret);
2207 return;
2208 }
2209
2210 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2211 FIRMWARE_VERSION, USB_MCU, NULL, 0);
2212 if (ret < 0) {
2213 dev_err(&drvdata.hdev->dev,
2214 "Failed to retrieve USB_MCU Firmware Version: %i\n", ret);
2215 return;
2216 }
2217
2218 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2219 HARDWARE_VERSION, USB_MCU, NULL, 0);
2220 if (ret < 0) {
2221 dev_err(&drvdata.hdev->dev,
2222 "Failed to retrieve USB_MCU Hardware Version: %i\n", ret);
2223 return;
2224 }
2225
2226 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2227 HARDWARE_GENERATION, USB_MCU, NULL, 0);
2228 if (ret < 0) {
2229 dev_err(&drvdata.hdev->dev,
2230 "Failed to retrieve USB_MCU Hardware Generation: %i\n", ret);
2231 return;
2232 }
2233
2234 /* TX Dongle Version Attrs */
2235 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2236 PRODUCT_VERSION, TX_DONGLE, NULL, 0);
2237 if (ret < 0) {
2238 dev_err(&drvdata.hdev->dev,
2239 "Failed to retrieve TX_DONGLE Product Version: %i\n", ret);
2240 return;
2241 }
2242
2243 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2244 PROTOCOL_VERSION, TX_DONGLE, NULL, 0);
2245 if (ret < 0) {
2246 dev_err(&drvdata.hdev->dev,
2247 "Failed to retrieve TX_DONGLE Protocol Version: %i\n", ret);
2248 return;
2249 }
2250
2251 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2252 FIRMWARE_VERSION, TX_DONGLE, NULL, 0);
2253 if (ret < 0) {
2254 dev_err(&drvdata.hdev->dev,
2255 "Failed to retrieve TX_DONGLE Firmware Version: %i\n", ret);
2256 return;
2257 }
2258
2259 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2260 HARDWARE_VERSION, TX_DONGLE, NULL, 0);
2261 if (ret < 0) {
2262 dev_err(&drvdata.hdev->dev,
2263 "Failed to retrieve TX_DONGLE Hardware Version: %i\n", ret);
2264 return;
2265 }
2266
2267 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2268 HARDWARE_GENERATION, TX_DONGLE, NULL, 0);
2269 if (ret < 0) {
2270 dev_err(&drvdata.hdev->dev,
2271 "Failed to retrieve TX_DONGLE Hardware Generation: %i\n", ret);
2272 return;
2273 }
2274
2275 /* Left Handle Version Attrs */
2276 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2277 PRODUCT_VERSION, LEFT_CONTROLLER, NULL, 0);
2278 if (ret < 0) {
2279 dev_err(&drvdata.hdev->dev,
2280 "Failed to retrieve LEFT_CONTROLLER Product Version: %i\n", ret);
2281 return;
2282 }
2283
2284 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2285 PROTOCOL_VERSION, LEFT_CONTROLLER, NULL, 0);
2286 if (ret < 0) {
2287 dev_err(&drvdata.hdev->dev,
2288 "Failed to retrieve LEFT_CONTROLLER Protocol Version: %i\n", ret);
2289 return;
2290 }
2291
2292 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2293 FIRMWARE_VERSION, LEFT_CONTROLLER, NULL, 0);
2294 if (ret < 0) {
2295 dev_err(&drvdata.hdev->dev,
2296 "Failed to retrieve LEFT_CONTROLLER Firmware Version: %i\n", ret);
2297 return;
2298 }
2299
2300 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2301 HARDWARE_VERSION, LEFT_CONTROLLER, NULL, 0);
2302 if (ret < 0) {
2303 dev_err(&drvdata.hdev->dev,
2304 "Failed to retrieve LEFT_CONTROLLER Hardware Version: %i\n", ret);
2305 return;
2306 }
2307
2308 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2309 HARDWARE_GENERATION, LEFT_CONTROLLER, NULL, 0);
2310 if (ret < 0) {
2311 dev_err(&drvdata.hdev->dev,
2312 "Failed to retrieve LEFT_CONTROLLER Hardware Generation: %i\n", ret);
2313 return;
2314 }
2315
2316 /* Right Handle Version Attrs */
2317 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2318 PRODUCT_VERSION, RIGHT_CONTROLLER, NULL, 0);
2319 if (ret < 0) {
2320 dev_err(&drvdata.hdev->dev,
2321 "Failed to retrieve RIGHT_CONTROLLER Product Version: %i\n", ret);
2322 return;
2323 }
2324
2325 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2326 PROTOCOL_VERSION, RIGHT_CONTROLLER, NULL, 0);
2327 if (ret < 0) {
2328 dev_err(&drvdata.hdev->dev,
2329 "Failed to retrieve RIGHT_CONTROLLER Protocol Version: %i\n", ret);
2330 return;
2331 }
2332
2333 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2334 FIRMWARE_VERSION, RIGHT_CONTROLLER, NULL, 0);
2335 if (ret < 0) {
2336 dev_err(&drvdata.hdev->dev,
2337 "Failed to retrieve RIGHT_CONTROLLER Firmware Version: %i\n", ret);
2338 return;
2339 }
2340
2341 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2342 HARDWARE_VERSION, RIGHT_CONTROLLER, NULL, 0);
2343 if (ret < 0) {
2344 dev_err(&drvdata.hdev->dev,
2345 "Failed to retrieve RIGHT_CONTROLLER Hardware Version: %i\n", ret);
2346 return;
2347 }
2348
2349 ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA,
2350 HARDWARE_GENERATION, RIGHT_CONTROLLER, NULL, 0);
2351 if (ret < 0) {
2352 dev_err(&drvdata.hdev->dev,
2353 "Failed to retrieve RIGHT_CONTROLLER Hardware Generation: %i\n", ret);
2354 return;
2355 }
2356}
2357
2358static int hid_go_cfg_probe(struct hid_device *hdev,
2359 const struct hid_device_id *_id)
2360{
2361 unsigned char *buf;
2362 int ret;
2363
2364 buf = devm_kzalloc(&hdev->dev, GO_PACKET_SIZE, GFP_KERNEL);
2365 if (!buf)
2366 return -ENOMEM;
2367
2368 hid_set_drvdata(hdev, &drvdata);
2369 drvdata.hdev = hdev;
2370 mutex_init(&drvdata.cfg_mutex);
2371
2372 ret = sysfs_create_groups(&hdev->dev.kobj, top_level_attr_groups);
2373 if (ret) {
2374 dev_err_probe(&hdev->dev, ret,
2375 "Failed to create gamepad configuration attributes\n");
2376 return ret;
2377 }
2378
2379 ret = devm_led_classdev_multicolor_register(&hdev->dev, &go_cdev_rgb);
2380 if (ret) {
2381 dev_err_probe(&hdev->dev, ret, "Failed to create RGB device\n");
2382 return ret;
2383 }
2384
2385 ret = devm_device_add_group(go_cdev_rgb.led_cdev.dev, &rgb_attr_group);
2386 if (ret) {
2387 dev_err_probe(&hdev->dev, ret,
2388 "Failed to create RGB configuration attributes\n");
2389 return ret;
2390 }
2391
2392 drvdata.led_cdev = &go_cdev_rgb.led_cdev;
2393
2394 init_completion(&drvdata.send_cmd_complete);
2395
2396 /* Executing calls prior to returning from probe will lock the MCU. Schedule
2397 * initial data call after probe has completed and MCU can accept calls.
2398 */
2399 INIT_DELAYED_WORK(&drvdata.go_cfg_setup, &cfg_setup);
2400 ret = schedule_delayed_work(&drvdata.go_cfg_setup, msecs_to_jiffies(2));
2401 if (!ret) {
2402 dev_err(&hdev->dev,
2403 "Failed to schedule startup delayed work\n");
2404 return -ENODEV;
2405 }
2406 return 0;
2407}
2408
2409static void hid_go_cfg_remove(struct hid_device *hdev)
2410{
2411 guard(mutex)(&drvdata.cfg_mutex);
2412 sysfs_remove_groups(&hdev->dev.kobj, top_level_attr_groups);
2413 hid_hw_close(hdev);
2414 hid_hw_stop(hdev);
2415 hid_set_drvdata(hdev, NULL);
2416}
2417
2418static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id)
2419{
2420 int ret, ep;
2421
2422 hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT;
2423
2424 ret = hid_parse(hdev);
2425 if (ret) {
2426 hid_err(hdev, "Parse failed\n");
2427 return ret;
2428 }
2429
2430 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2431 if (ret) {
2432 hid_err(hdev, "Failed to start HID device\n");
2433 return ret;
2434 }
2435
2436 ret = hid_hw_open(hdev);
2437 if (ret) {
2438 hid_err(hdev, "Failed to open HID device\n");
2439 hid_hw_stop(hdev);
2440 return ret;
2441 }
2442
2443 ep = get_endpoint_address(hdev);
2444 if (ep != GO_GP_INTF_IN) {
2445 dev_dbg(&hdev->dev, "Started interface %x as generic HID device\n", ep);
2446 return 0;
2447 }
2448
2449 ret = hid_go_cfg_probe(hdev, id);
2450 if (ret)
2451 dev_err_probe(&hdev->dev, ret, "Failed to start configuration interface\n");
2452
2453 dev_dbg(&hdev->dev, "Started Legion Go HID Device: %x\n", ep);
2454
2455 return ret;
2456}
2457
2458static void hid_go_remove(struct hid_device *hdev)
2459{
2460 int ep = get_endpoint_address(hdev);
2461
2462 if (ep <= 0)
2463 return;
2464
2465 switch (ep) {
2466 case GO_GP_INTF_IN:
2467 hid_go_cfg_remove(hdev);
2468 break;
2469 default:
2470 hid_hw_close(hdev);
2471 hid_hw_stop(hdev);
2472 break;
2473 }
2474}
2475
2476static const struct hid_device_id hid_go_devices[] = {
2477 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO,
2478 USB_DEVICE_ID_LENOVO_LEGION_GO2_XINPUT) },
2479 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO,
2480 USB_DEVICE_ID_LENOVO_LEGION_GO2_DINPUT) },
2481 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO,
2482 USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT) },
2483 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO,
2484 USB_DEVICE_ID_LENOVO_LEGION_GO2_FPS) },
2485 {}
2486};
2487MODULE_DEVICE_TABLE(hid, hid_go_devices);
2488
2489static struct hid_driver hid_lenovo_go = {
2490 .name = "hid-lenovo-go",
2491 .id_table = hid_go_devices,
2492 .probe = hid_go_probe,
2493 .remove = hid_go_remove,
2494 .raw_event = hid_go_raw_event,
2495};
2496module_hid_driver(hid_lenovo_go);
2497
2498MODULE_AUTHOR("Derek J. Clark");
2499MODULE_DESCRIPTION("HID Driver for Lenovo Legion Go Series Gamepads.");
2500MODULE_LICENSE("GPL");