Skip to content

Commit 13b2e1b

Browse files
hadessJiri Kosina
authored andcommitted
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 <[email protected]> Reviewed-by: Benjamin Tissoires <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent db1b5cc commit 13b2e1b

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

drivers/hid/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ config HID_PRIMAX
741741
Support for Primax devices that are not fully compliant with the
742742
HID standard.
743743

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+
744752
config HID_ROCCAT
745753
tristate "Roccat device support"
746754
depends on USB_HID

drivers/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o
8181

8282
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
8383
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
84+
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o
8485
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
8586
hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
8687
hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \

drivers/hid/hid-core.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
21512151
#if IS_ENABLED(CONFIG_HID_PRODIKEYS)
21522152
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
21532153
#endif
2154+
#if IS_ENABLED(CONFIG_HID_RETRODE)
2155+
{ HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) },
2156+
#endif
21542157
#if IS_ENABLED(CONFIG_HID_RMI)
21552158
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
21562159
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,9 @@
386386
#define USB_VENDOR_ID_FUTABA 0x0547
387387
#define USB_DEVICE_ID_LED_DISPLAY 0x7000
388388

389+
#define USB_VENDOR_ID_FUTURE_TECHNOLOGY 0x0403
390+
#define USB_DEVICE_ID_RETRODE2 0x97c1
391+
389392
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
390393
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
391394

drivers/hid/hid-retrode.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* HID driver for Retrode 2 controller adapter and plug-in extensions
3+
*
4+
* Copyright (c) 2017 Bastien Nocera <[email protected]>
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");

0 commit comments

Comments
 (0)