hid-xinmo.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * HID driver for Xin-Mo devices, currently only the Dual Arcade controller.
  4. * Fixes the negative axis event values (the devices sends -2) to match the
  5. * logical axis minimum of the HID report descriptor (the report announces
  6. * -1). It is needed because hid-input discards out of bounds values.
  7. * (This module is based on "hid-saitek" and "hid-lg".)
  8. *
  9. * Copyright (c) 2013 Olivier Scherler
  10. */
  11. /*
  12. */
  13. #include <linux/device.h>
  14. #include <linux/hid.h>
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include "hid-ids.h"
  18. /*
  19. * Fix negative events that are out of bounds.
  20. */
  21. static int xinmo_event(struct hid_device *hdev, struct hid_field *field,
  22. struct hid_usage *usage, __s32 value)
  23. {
  24. switch (usage->code) {
  25. case ABS_X:
  26. case ABS_Y:
  27. case ABS_Z:
  28. case ABS_RX:
  29. if (value < -1) {
  30. input_event(field->hidinput->input, usage->type,
  31. usage->code, -1);
  32. return 1;
  33. }
  34. break;
  35. }
  36. return 0;
  37. }
  38. static const struct hid_device_id xinmo_devices[] = {
  39. { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
  40. { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
  41. { }
  42. };
  43. MODULE_DEVICE_TABLE(hid, xinmo_devices);
  44. static struct hid_driver xinmo_driver = {
  45. .name = "xinmo",
  46. .id_table = xinmo_devices,
  47. .event = xinmo_event
  48. };
  49. module_hid_driver(xinmo_driver);
  50. MODULE_LICENSE("GPL");