Skip to content

Commit 9515772

Browse files
IlyaSkriblovskyJiri Kosina
authored andcommitted
HID: Add support for side buttons of Xiaomi Mi Dual Mode Wireless Mouse Silent
This patch enables side-buttons of Xiaomi Bluetooth mouse (specifically Xiaomi Mi Dual Mode Wireless Mouse Silent Edition). The mouse sends invalid button count in its HID Report Descriptor and this patch just replaces its descriptor with corrected one. With this driver side buttons work as expected acting like Back/Forward buttons. Signed-off-by: Ilya Skriblovsky <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 83ec916 commit 9515772

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

drivers/hid/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ config HID_VIEWSONIC
468468
help
469469
Support for ViewSonic/Signotec PD1011 signature pad.
470470

471+
config HID_XIAOMI
472+
tristate "Xiaomi"
473+
depends on HID
474+
help
475+
Adds support for side buttons of Xiaomi Mi Dual Mode Wireless
476+
Mouse Silent Edition.
477+
471478
config HID_GYRATION
472479
tristate "Gyration remote control"
473480
depends on HID

drivers/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ hid-uclogic-objs := hid-uclogic-core.o \
125125
obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
126126
obj-$(CONFIG_HID_UDRAW_PS3) += hid-udraw-ps3.o
127127
obj-$(CONFIG_HID_LED) += hid-led.o
128+
obj-$(CONFIG_HID_XIAOMI) += hid-xiaomi.o
128129
obj-$(CONFIG_HID_XINMO) += hid-xinmo.o
129130
obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
130131
obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,9 @@
12981298
#define USB_VENDOR_ID_XAT 0x2505
12991299
#define USB_DEVICE_ID_XAT_CSR 0x0220
13001300

1301+
#define USB_VENDOR_ID_XIAOMI 0x2717
1302+
#define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014
1303+
13011304
#define USB_VENDOR_ID_XIN_MO 0x16c0
13021305
#define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE 0x05e1
13031306
#define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1

drivers/hid/hid-xiaomi.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* HID driver for Xiaomi Mi Dual Mode Wireless Mouse Silent Edition
4+
*
5+
* Copyright (c) 2021 Ilya Skriblovsky
6+
*/
7+
8+
#include <linux/init.h>
9+
#include <linux/module.h>
10+
#include <linux/hid.h>
11+
12+
#include "hid-ids.h"
13+
14+
/* Fixed Mi Silent Mouse report descriptor */
15+
/* Button's Usage Maximum changed from 3 to 5 to make side buttons work */
16+
#define MI_SILENT_MOUSE_ORIG_RDESC_LENGTH 87
17+
static __u8 mi_silent_mouse_rdesc_fixed[] = {
18+
0x05, 0x01, /* Usage Page (Desktop), */
19+
0x09, 0x02, /* Usage (Mouse), */
20+
0xA1, 0x01, /* Collection (Application), */
21+
0x85, 0x03, /* Report ID (3), */
22+
0x09, 0x01, /* Usage (Pointer), */
23+
0xA1, 0x00, /* Collection (Physical), */
24+
0x05, 0x09, /* Usage Page (Button), */
25+
0x19, 0x01, /* Usage Minimum (01h), */
26+
0x29, 0x05, /* X */ /* Usage Maximum (05h), */
27+
0x15, 0x00, /* Logical Minimum (0), */
28+
0x25, 0x01, /* Logical Maximum (1), */
29+
0x75, 0x01, /* Report Size (1), */
30+
0x95, 0x05, /* Report Count (5), */
31+
0x81, 0x02, /* Input (Variable), */
32+
0x75, 0x03, /* Report Size (3), */
33+
0x95, 0x01, /* Report Count (1), */
34+
0x81, 0x01, /* Input (Constant), */
35+
0x05, 0x01, /* Usage Page (Desktop), */
36+
0x09, 0x30, /* Usage (X), */
37+
0x09, 0x31, /* Usage (Y), */
38+
0x15, 0x81, /* Logical Minimum (-127), */
39+
0x25, 0x7F, /* Logical Maximum (127), */
40+
0x75, 0x08, /* Report Size (8), */
41+
0x95, 0x02, /* Report Count (2), */
42+
0x81, 0x06, /* Input (Variable, Relative), */
43+
0x09, 0x38, /* Usage (Wheel), */
44+
0x15, 0x81, /* Logical Minimum (-127), */
45+
0x25, 0x7F, /* Logical Maximum (127), */
46+
0x75, 0x08, /* Report Size (8), */
47+
0x95, 0x01, /* Report Count (1), */
48+
0x81, 0x06, /* Input (Variable, Relative), */
49+
0xC0, /* End Collection, */
50+
0xC0, /* End Collection, */
51+
0x06, 0x01, 0xFF, /* Usage Page (FF01h), */
52+
0x09, 0x01, /* Usage (01h), */
53+
0xA1, 0x01, /* Collection (Application), */
54+
0x85, 0x05, /* Report ID (5), */
55+
0x09, 0x05, /* Usage (05h), */
56+
0x15, 0x00, /* Logical Minimum (0), */
57+
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
58+
0x75, 0x08, /* Report Size (8), */
59+
0x95, 0x04, /* Report Count (4), */
60+
0xB1, 0x02, /* Feature (Variable), */
61+
0xC0 /* End Collection */
62+
};
63+
64+
static __u8 *xiaomi_report_fixup(struct hid_device *hdev, __u8 *rdesc,
65+
unsigned int *rsize)
66+
{
67+
switch (hdev->product) {
68+
case USB_DEVICE_ID_MI_SILENT_MOUSE:
69+
if (*rsize == MI_SILENT_MOUSE_ORIG_RDESC_LENGTH) {
70+
hid_info(hdev, "fixing up Mi Silent Mouse report descriptor\n");
71+
rdesc = mi_silent_mouse_rdesc_fixed;
72+
*rsize = sizeof(mi_silent_mouse_rdesc_fixed);
73+
}
74+
break;
75+
}
76+
return rdesc;
77+
}
78+
79+
static const struct hid_device_id xiaomi_devices[] = {
80+
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_XIAOMI, USB_DEVICE_ID_MI_SILENT_MOUSE) },
81+
{ }
82+
};
83+
MODULE_DEVICE_TABLE(hid, xiaomi_devices);
84+
85+
static struct hid_driver xiaomi_driver = {
86+
.name = "xiaomi",
87+
.id_table = xiaomi_devices,
88+
.report_fixup = xiaomi_report_fixup,
89+
};
90+
module_hid_driver(xiaomi_driver);
91+
92+
MODULE_LICENSE("GPL");
93+
MODULE_AUTHOR("Ilya Skriblovsky <[email protected]>");
94+
MODULE_DESCRIPTION("Fixing side buttons of Xiaomi Mi Silent Mouse");

0 commit comments

Comments
 (0)