Skip to content

Commit b3b1c68

Browse files
tht2005Jiri Kosina
authored andcommitted
HID: rapoo: Add support for side buttons on RAPOO 0x2015 mouse
This patch adds support for handling the side buttons on the RAPOO 0x2015 wireless mouse. These buttons were previously not generating input events due to missing driver logic. The new code handles raw HID input report with Report ID 1 and maps the side buttons to KEY_BACK and KEY_FORWARD using the input subsystem. Tested on a RAPOO mouse with USB ID 24AE:2015. Signed-off-by: Nguyen Dinh Dang Duong <dangduong31205@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent d7f6629 commit b3b1c68

4 files changed

Lines changed: 111 additions & 0 deletions

File tree

drivers/hid/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,12 @@ config HID_PXRC
10151015
To compile this driver as a module, choose M here: the
10161016
module will be called hid-pxrc.
10171017

1018+
config HID_RAPOO
1019+
tristate "Rapoo non-fully HID-compliant devices"
1020+
help
1021+
Support for Rapoo devices that are not fully compliant with the
1022+
HID standard.
1023+
10181024
config HID_RAZER
10191025
tristate "Razer non-fully HID-compliant devices"
10201026
help

drivers/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
113113
obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o
114114
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
115115
obj-$(CONFIG_HID_PXRC) += hid-pxrc.o
116+
obj-$(CONFIG_HID_RAPOO) += hid-rapoo.o
116117
obj-$(CONFIG_HID_RAZER) += hid-razer.o
117118
obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o
118119
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,9 @@
11661166
#define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33
11671167
#define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118
11681168

1169+
#define USB_VENDOR_ID_RAPOO 0x24ae
1170+
#define USB_DEVICE_ID_RAPOO_2_4G_RECEIVER 0x2015
1171+
11691172
#define USB_VENDOR_ID_RAZER 0x1532
11701173
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE 0x010D
11711174
#define USB_DEVICE_ID_RAZER_BLACKWIDOW 0x010e

drivers/hid/hid-rapoo.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <asm-generic/errno-base.h>
3+
#include <asm-generic/int-ll64.h>
4+
#include <linux/bitops.h>
5+
#include <linux/input.h>
6+
#include <linux/input-event-codes.h>
7+
#include <linux/module.h>
8+
#include <linux/hid.h>
9+
#include <linux/usb.h>
10+
11+
#include "hid-ids.h"
12+
13+
#define RAPOO_BTN_BACK 0x08
14+
#define RAPOO_BTN_FORWARD 0x10
15+
16+
static const struct hid_device_id rapoo_devices[] = {
17+
{ HID_USB_DEVICE(USB_VENDOR_ID_RAPOO, USB_DEVICE_ID_RAPOO_2_4G_RECEIVER) },
18+
{ }
19+
};
20+
MODULE_DEVICE_TABLE(hid, rapoo_devices);
21+
22+
static int rapoo_probe(struct hid_device *hdev, const struct hid_device_id *id)
23+
{
24+
int ret;
25+
struct input_dev *input;
26+
27+
ret = hid_parse(hdev);
28+
if (ret) {
29+
hid_err(hdev, "parse failed\n");
30+
return ret;
31+
}
32+
33+
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
34+
if (ret) {
35+
hid_err(hdev, "start failed\n");
36+
return ret;
37+
}
38+
39+
if (hdev->bus == BUS_USB) {
40+
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
41+
42+
if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
43+
return 0;
44+
}
45+
46+
input = devm_input_allocate_device(&hdev->dev);
47+
if (!input)
48+
return -ENOMEM;
49+
50+
input->name = "Rapoo 2.4G Wireless Mouse";
51+
input->phys = "rapoo/input1";
52+
input->id.bustype = hdev->bus;
53+
input->id.vendor = hdev->vendor;
54+
input->id.product = hdev->product;
55+
input->id.version = hdev->version;
56+
57+
__set_bit(EV_KEY, input->evbit);
58+
__set_bit(KEY_BACK, input->keybit);
59+
__set_bit(KEY_FORWARD, input->keybit);
60+
61+
ret = input_register_device(input);
62+
if (ret)
63+
return ret;
64+
65+
hid_set_drvdata(hdev, input);
66+
67+
return ret;
68+
}
69+
70+
static int rapoo_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
71+
{
72+
struct input_dev *input = hid_get_drvdata(hdev);
73+
74+
if (!input)
75+
return 0;
76+
77+
if (report->id == 1 && size >= 2) {
78+
u8 btn = data[1];
79+
80+
input_report_key(input, KEY_BACK, btn & RAPOO_BTN_BACK);
81+
input_report_key(input, KEY_FORWARD, btn & RAPOO_BTN_FORWARD);
82+
input_sync(input);
83+
return 1;
84+
}
85+
86+
return 0;
87+
}
88+
89+
static struct hid_driver rapoo_driver = {
90+
.name = "hid-rapoo",
91+
.id_table = rapoo_devices,
92+
.probe = rapoo_probe,
93+
.raw_event = rapoo_raw_event,
94+
};
95+
96+
module_hid_driver(rapoo_driver);
97+
98+
MODULE_LICENSE("GPL");
99+
MODULE_AUTHOR("Nguyen Dinh Dang Duong <dangduong31205@gmail.com>");
100+
MODULE_DESCRIPTION("RAPOO 2.4G Wireless Device Driver");
101+

0 commit comments

Comments
 (0)