1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * HID driver for Retrode 2 controller adapter and plug-in extensions 4 * 5 * Copyright (c) 2017 Bastien Nocera <hadess@hadess.net> 6 */ 7 8 /* 9 */ 10 11 #include <linux/input.h> 12 #include <linux/slab.h> 13 #include <linux/hid.h> 14 #include <linux/module.h> 15 #include "hid-ids.h" 16 17 #define CONTROLLER_NAME_BASE "Retrode" 18 19 static int retrode_input_configured(struct hid_device *hdev, 20 struct hid_input *hi) 21 { 22 struct hid_field *field = hi->report->field[0]; 23 const char *suffix; 24 int number = 0; 25 char *name; 26 27 switch (field->report->id) { 28 case 0: 29 suffix = "SNES Mouse"; 30 break; 31 case 1: 32 case 2: 33 suffix = "SNES / N64"; 34 number = field->report->id; 35 break; 36 case 3: 37 case 4: 38 suffix = "Mega Drive"; 39 number = field->report->id - 2; 40 break; 41 default: 42 hid_err(hdev, "Got unhandled report id %d\n", field->report->id); 43 suffix = "Unknown"; 44 } 45 46 if (number) 47 name = devm_kasprintf(&hdev->dev, GFP_KERNEL, 48 "%s %s #%d", CONTROLLER_NAME_BASE, 49 suffix, number); 50 else 51 name = devm_kasprintf(&hdev->dev, GFP_KERNEL, 52 "%s %s", CONTROLLER_NAME_BASE, suffix); 53 54 if (!name) 55 return -ENOMEM; 56 57 hi->input->name = name; 58 59 return 0; 60 } 61 62 static int retrode_probe(struct hid_device *hdev, 63 const struct hid_device_id *id) 64 { 65 66 int ret; 67 68 /* Has no effect on the mouse device */ 69 hdev->quirks |= HID_QUIRK_MULTI_INPUT; 70 71 ret = hid_parse(hdev); 72 if (ret) 73 return ret; 74 75 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 76 if (ret) 77 return ret; 78 79 return 0; 80 } 81 82 static const struct hid_device_id retrode_devices[] = { 83 { HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) }, 84 { } 85 }; 86 MODULE_DEVICE_TABLE(hid, retrode_devices); 87 88 static struct hid_driver retrode_driver = { 89 .name = "hid-retrode", 90 .id_table = retrode_devices, 91 .input_configured = retrode_input_configured, 92 .probe = retrode_probe, 93 }; 94 95 module_hid_driver(retrode_driver); 96 97 MODULE_LICENSE("GPL"); 98