Created
March 3, 2022 01:03
-
-
Save camthesaxman/af7099505103a555518741b4083eaea8 to your computer and use it in GitHub Desktop.
Kernel Module to fix wrong button mapping of PowerA wired Nintendo Switch controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
obj-m += powera_switch_fix.o | |
all: | |
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules | |
clean: | |
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Linux kernel module to fix up the wrong button mapping for the | |
* PowerA Wired Nintendo Switch controller | |
*/ | |
#include <linux/hid.h> | |
#include <linux/input.h> | |
#include <linux/module.h> | |
MODULE_VERSION("0.1"); | |
MODULE_LICENSE("GPL"); | |
static const struct hid_device_id hidTable[] = { | |
{ HID_USB_DEVICE(0x20D6, 0xA711) }, | |
{ 0 }, | |
}; | |
// button mapping | |
static const unsigned int buttonmap[] = { | |
[1] = BTN_WEST, // Y button | |
[2] = BTN_SOUTH, // B button | |
[3] = BTN_EAST, // A button | |
[4] = BTN_NORTH, // X button | |
[5] = BTN_TL, // L button | |
[6] = BTN_TR, // R button | |
[7] = BTN_TL2, // ZL button | |
[8] = BTN_TR2, // ZR button | |
[9] = BTN_SELECT, // - button | |
[10] = BTN_START, // + button | |
[11] = BTN_THUMBL, // left stick press | |
[12] = BTN_THUMBR, // right stick press | |
[13] = BTN_MODE, // home button | |
[14] = BTN_C, // camera button, not sure what else to map this to | |
}; | |
static int my_mapping(struct hid_device *hdev, struct hid_input *hi, | |
struct hid_field *field, struct hid_usage *usage, | |
unsigned long **bit, int *max) | |
{ | |
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | |
unsigned int button = usage->hid & HID_USAGE; | |
if (button >= ARRAY_SIZE(buttonmap)) | |
return -1; | |
button = buttonmap[button]; | |
if (button == 0) | |
return -1; | |
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, button); | |
return 1; | |
} | |
return 0; | |
} | |
static struct hid_driver driver = { | |
.name = "powera_switch_fix", | |
.id_table = hidTable, | |
.input_mapping = my_mapping, | |
}; | |
static int __init my_init(void) | |
{ | |
printk(KERN_INFO "%s: module_init\n", driver.name); | |
return hid_register_driver(&driver); | |
} | |
static void __exit my_exit(void) | |
{ | |
printk(KERN_INFO "%s: module_exit\n", driver.name); | |
hid_unregister_driver(&driver); | |
} | |
module_init(my_init); | |
module_exit(my_exit); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment