hid-chicony.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * HID driver for some chicony "special" devices
  3. *
  4. * Copyright (c) 1999 Andreas Gal
  5. * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  6. * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
  7. * Copyright (c) 2006-2007 Jiri Kosina
  8. * Copyright (c) 2007 Paul Walmsley
  9. * Copyright (c) 2008 Jiri Slaby
  10. */
  11. /*
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU General Public License as published by the Free
  14. * Software Foundation; either version 2 of the License, or (at your option)
  15. * any later version.
  16. */
  17. #include <linux/device.h>
  18. #include <linux/input.h>
  19. #include <linux/hid.h>
  20. #include <linux/module.h>
  21. #include <linux/usb.h>
  22. #include "hid-ids.h"
  23. #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
  24. EV_KEY, (c))
  25. static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  26. struct hid_field *field, struct hid_usage *usage,
  27. unsigned long **bit, int *max)
  28. {
  29. if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
  30. return 0;
  31. set_bit(EV_REP, hi->input->evbit);
  32. switch (usage->hid & HID_USAGE) {
  33. case 0xff01: ch_map_key_clear(BTN_1); break;
  34. case 0xff02: ch_map_key_clear(BTN_2); break;
  35. case 0xff03: ch_map_key_clear(BTN_3); break;
  36. case 0xff04: ch_map_key_clear(BTN_4); break;
  37. case 0xff05: ch_map_key_clear(BTN_5); break;
  38. case 0xff06: ch_map_key_clear(BTN_6); break;
  39. case 0xff07: ch_map_key_clear(BTN_7); break;
  40. case 0xff08: ch_map_key_clear(BTN_8); break;
  41. case 0xff09: ch_map_key_clear(BTN_9); break;
  42. case 0xff0a: ch_map_key_clear(BTN_A); break;
  43. case 0xff0b: ch_map_key_clear(BTN_B); break;
  44. case 0x00f1: ch_map_key_clear(KEY_WLAN); break;
  45. case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break;
  46. case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break;
  47. case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break;
  48. case 0x00f7: ch_map_key_clear(KEY_CAMERA); break;
  49. case 0x00f8: ch_map_key_clear(KEY_PROG1); break;
  50. default:
  51. return 0;
  52. }
  53. return 1;
  54. }
  55. static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc,
  56. unsigned int *rsize)
  57. {
  58. struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  59. if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
  60. /* Change usage maximum and logical maximum from 0x7fff to
  61. * 0x2fff, so they don't exceed HID_MAX_USAGES */
  62. switch (hdev->product) {
  63. case USB_DEVICE_ID_CHICONY_ACER_SWITCH12:
  64. if (*rsize >= 128 && rdesc[64] == 0xff && rdesc[65] == 0x7f
  65. && rdesc[69] == 0xff && rdesc[70] == 0x7f) {
  66. hid_info(hdev, "Fixing up report descriptor\n");
  67. rdesc[65] = rdesc[70] = 0x2f;
  68. }
  69. break;
  70. }
  71. }
  72. return rdesc;
  73. }
  74. static const struct hid_device_id ch_devices[] = {
  75. { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
  76. { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
  77. { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
  78. { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
  79. { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) },
  80. { }
  81. };
  82. MODULE_DEVICE_TABLE(hid, ch_devices);
  83. static struct hid_driver ch_driver = {
  84. .name = "chicony",
  85. .id_table = ch_devices,
  86. .report_fixup = ch_switch12_report_fixup,
  87. .input_mapping = ch_input_mapping,
  88. };
  89. module_hid_driver(ch_driver);
  90. MODULE_LICENSE("GPL");