linux/drivers/hid/hid-retrode.c
<<
>>
Prefs
   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
  22static 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
  65static 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
  85static const struct hid_device_id retrode_devices[] = {
  86        { HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) },
  87        { }
  88};
  89MODULE_DEVICE_TABLE(hid, retrode_devices);
  90
  91static 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
  98module_hid_driver(retrode_driver);
  99
 100MODULE_LICENSE("GPL");
 101