Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: Add driver for Retrode2 joypad adapter

This driver does 2 things:

- Apply the MULTI_INPUT quirk to create separate joypad device nodes
for each one of the 4 connectors.
- Rename the input devices so that their names are different, and allow
users to recognise which device corresponds to which physical port,
including the SNES (Mario Paint) Mouse.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Bastien Nocera and committed by
Jiri Kosina
13b2e1ba db1b5ccd

+115
+8
drivers/hid/Kconfig
··· 741 741 Support for Primax devices that are not fully compliant with the 742 742 HID standard. 743 743 744 + config HID_RETRODE 745 + tristate "Retrode" 746 + depends on USB_HID 747 + ---help--- 748 + Support for 749 + 750 + * Retrode 2 cartridge and controller adapter 751 + 744 752 config HID_ROCCAT 745 753 tristate "Roccat device support" 746 754 depends on USB_HID
+1
drivers/hid/Makefile
··· 81 81 82 82 obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o 83 83 obj-$(CONFIG_HID_PRIMAX) += hid-primax.o 84 + obj-$(CONFIG_HID_RETRODE) += hid-retrode.o 84 85 obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 85 86 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 86 87 hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
+3
drivers/hid/hid-core.c
··· 2151 2151 #if IS_ENABLED(CONFIG_HID_PRODIKEYS) 2152 2152 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, 2153 2153 #endif 2154 + #if IS_ENABLED(CONFIG_HID_RETRODE) 2155 + { HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) }, 2156 + #endif 2154 2157 #if IS_ENABLED(CONFIG_HID_RMI) 2155 2158 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) }, 2156 2159 { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
+3
drivers/hid/hid-ids.h
··· 386 386 #define USB_VENDOR_ID_FUTABA 0x0547 387 387 #define USB_DEVICE_ID_LED_DISPLAY 0x7000 388 388 389 + #define USB_VENDOR_ID_FUTURE_TECHNOLOGY 0x0403 390 + #define USB_DEVICE_ID_RETRODE2 0x97c1 391 + 389 392 #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 390 393 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 391 394
+100
drivers/hid/hid-retrode.c
··· 1 + /* 2 + * HID driver for Retrode 2 controller adapter and plug-in extensions 3 + * 4 + * Copyright (c) 2017 Bastien Nocera <hadess@hadess.net> 5 + */ 6 + 7 + /* 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + */ 13 + 14 + #include <linux/input.h> 15 + #include <linux/slab.h> 16 + #include <linux/hid.h> 17 + #include <linux/module.h> 18 + #include "hid-ids.h" 19 + 20 + #define CONTROLLER_NAME_BASE "Retrode" 21 + 22 + static int retrode_input_configured(struct hid_device *hdev, 23 + struct hid_input *hi) 24 + { 25 + struct hid_field *field = hi->report->field[0]; 26 + const char *suffix; 27 + int number = 0; 28 + char *name; 29 + 30 + switch (field->report->id) { 31 + case 0: 32 + suffix = "SNES Mouse"; 33 + break; 34 + case 1: 35 + case 2: 36 + suffix = "SNES / N64"; 37 + number = field->report->id; 38 + break; 39 + case 3: 40 + case 4: 41 + suffix = "Mega Drive"; 42 + number = field->report->id - 2; 43 + break; 44 + default: 45 + hid_err(hdev, "Got unhandled report id %d\n", field->report->id); 46 + suffix = "Unknown"; 47 + } 48 + 49 + if (number) 50 + name = devm_kasprintf(&hdev->dev, GFP_KERNEL, 51 + "%s %s #%d", CONTROLLER_NAME_BASE, 52 + suffix, number); 53 + else 54 + name = devm_kasprintf(&hdev->dev, GFP_KERNEL, 55 + "%s %s", CONTROLLER_NAME_BASE, suffix); 56 + 57 + if (!name) 58 + return -ENOMEM; 59 + 60 + hi->input->name = name; 61 + 62 + return 0; 63 + } 64 + 65 + static int retrode_probe(struct hid_device *hdev, 66 + const struct hid_device_id *id) 67 + { 68 + 69 + int ret; 70 + 71 + /* Has no effect on the mouse device */ 72 + hdev->quirks |= HID_QUIRK_MULTI_INPUT; 73 + 74 + ret = hid_parse(hdev); 75 + if (ret) 76 + return ret; 77 + 78 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 79 + if (ret) 80 + return ret; 81 + 82 + return 0; 83 + } 84 + 85 + static const struct hid_device_id retrode_devices[] = { 86 + { HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) }, 87 + { } 88 + }; 89 + MODULE_DEVICE_TABLE(hid, retrode_devices); 90 + 91 + static struct hid_driver retrode_driver = { 92 + .name = "hid-retrode", 93 + .id_table = retrode_devices, 94 + .input_configured = retrode_input_configured, 95 + .probe = retrode_probe, 96 + }; 97 + 98 + module_hid_driver(retrode_driver); 99 + 100 + MODULE_LICENSE("GPL");