Skip to content

Commit 1fe30b4

Browse files
author
Jiri Kosina
committed
Merge branch 'for-5.18/razer' into for-linus
- driver for Razer Blackwidow keyboards (Jelle van der Waa)
2 parents 5d3ab41 + 047b618 commit 1fe30b4

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

drivers/hid/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,13 @@ config PLAYSTATION_FF
931931
Say Y here if you would like to enable force feedback support for
932932
PlayStation game controllers.
933933

934+
config HID_RAZER
935+
tristate "Razer non-fully HID-compliant devices"
936+
depends on HID
937+
help
938+
Support for Razer devices that are not fully compliant with the
939+
HID standard.
940+
934941
config HID_PRIMAX
935942
tristate "Primax non-fully HID-compliant devices"
936943
depends on HID

drivers/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o
9999
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
100100
obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o
101101
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
102+
obj-$(CONFIG_HID_RAZER) += hid-razer.o
102103
obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o
103104
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o
104105
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,9 @@
10381038
#define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118
10391039

10401040
#define USB_VENDOR_ID_RAZER 0x1532
1041+
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE 0x010D
1042+
#define USB_DEVICE_ID_RAZER_BLACKWIDOW 0x010e
1043+
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_CLASSIC 0x011b
10411044
#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
10421045

10431046
#define USB_VENDOR_ID_REALTEK 0x0bda

drivers/hid/hid-razer.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* HID driver for gaming keys on Razer Blackwidow gaming keyboards
4+
* Macro Key Keycodes: M1 = 191, M2 = 192, M3 = 193, M4 = 194, M5 = 195
5+
*
6+
* Copyright (c) 2021 Jelle van der Waa <[email protected]>
7+
*/
8+
9+
#include <linux/device.h>
10+
#include <linux/hid.h>
11+
#include <linux/module.h>
12+
#include <linux/random.h>
13+
#include <linux/sched.h>
14+
#include <linux/usb.h>
15+
#include <linux/wait.h>
16+
17+
#include "hid-ids.h"
18+
19+
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
20+
21+
#define RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE 91
22+
23+
static bool macro_key_remapping = 1;
24+
module_param(macro_key_remapping, bool, 0644);
25+
MODULE_PARM_DESC(macro_key_remapping, " on (Y) off (N)");
26+
27+
28+
static unsigned char blackwidow_init[RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE] = {
29+
0x00,
30+
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04,
31+
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41+
0x04, 0x00
42+
};
43+
44+
static int razer_input_mapping(struct hid_device *hdev,
45+
struct hid_input *hi, struct hid_field *field,
46+
struct hid_usage *usage, unsigned long **bit, int *max)
47+
{
48+
49+
if (!macro_key_remapping)
50+
return 0;
51+
52+
if ((usage->hid & HID_UP_KEYBOARD) != HID_UP_KEYBOARD)
53+
return 0;
54+
55+
switch (usage->hid & ~HID_UP_KEYBOARD) {
56+
case 0x68:
57+
map_key_clear(KEY_MACRO1);
58+
return 1;
59+
case 0x69:
60+
map_key_clear(KEY_MACRO2);
61+
return 1;
62+
case 0x6a:
63+
map_key_clear(KEY_MACRO3);
64+
return 1;
65+
case 0x6b:
66+
map_key_clear(KEY_MACRO4);
67+
return 1;
68+
case 0x6c:
69+
map_key_clear(KEY_MACRO5);
70+
return 1;
71+
}
72+
73+
return 0;
74+
}
75+
76+
static int razer_probe(struct hid_device *hdev, const struct hid_device_id *id)
77+
{
78+
char *buf;
79+
int ret = 0;
80+
81+
ret = hid_parse(hdev);
82+
if (ret)
83+
return ret;
84+
85+
/*
86+
* Only send the enable macro keys command for the third device
87+
* identified as mouse input.
88+
*/
89+
if (hdev->type == HID_TYPE_USBMOUSE) {
90+
buf = kmemdup(blackwidow_init, RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE, GFP_KERNEL);
91+
if (buf == NULL)
92+
return -ENOMEM;
93+
94+
ret = hid_hw_raw_request(hdev, 0, buf, RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE,
95+
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
96+
if (ret != RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE)
97+
hid_err(hdev, "failed to enable macro keys: %d\n", ret);
98+
99+
kfree(buf);
100+
}
101+
102+
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
103+
}
104+
105+
static const struct hid_device_id razer_devices[] = {
106+
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
107+
USB_DEVICE_ID_RAZER_BLACKWIDOW) },
108+
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
109+
USB_DEVICE_ID_RAZER_BLACKWIDOW_CLASSIC) },
110+
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
111+
USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE) },
112+
{ }
113+
};
114+
MODULE_DEVICE_TABLE(hid, razer_devices);
115+
116+
static struct hid_driver razer_driver = {
117+
.name = "razer",
118+
.id_table = razer_devices,
119+
.input_mapping = razer_input_mapping,
120+
.probe = razer_probe,
121+
};
122+
module_hid_driver(razer_driver);
123+
124+
MODULE_AUTHOR("Jelle van der Waa <[email protected]>");
125+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)