Blame view

drivers/hid/hid-elecom.c 3.46 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
64b386ea1   Richard Nauber   HID: add proper s...
2
  /*
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
3
4
   *  HID driver for ELECOM devices:
   *  - BM084 Bluetooth Mouse
fbb77e88f   Tomasz Kramkowski   HID: elecom: add ...
5
   *  - EX-G Trackballs (M-XT3DRBK, M-XT3URBK, M-XT4DRBK)
79837eded   Tomasz Kramkowski   HID: elecom: refe...
6
7
   *  - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
   *  - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
8
   *
64b386ea1   Richard Nauber   HID: add proper s...
9
   *  Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
0bb7a37f8   Diego Elio Pettenò   HID: elecom: exte...
10
11
   *  Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
   *  Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu>
a0933a456   Alex Manoussakis   HID: hid-elecom: ...
12
   *  Copyright (c) 2017 Alex Manoussakis <amanou@gnu.org>
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
13
   *  Copyright (c) 2017 Tomasz Kramkowski <tk@the-tk.com>
64b386ea1   Richard Nauber   HID: add proper s...
14
15
16
   */
  
  /*
64b386ea1   Richard Nauber   HID: add proper s...
17
18
19
20
21
22
23
   */
  
  #include <linux/device.h>
  #include <linux/hid.h>
  #include <linux/module.h>
  
  #include "hid-ids.h"
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  /*
   * Certain ELECOM mice misreport their button count meaning that they only work
   * correctly with the ELECOM mouse assistant software which is unavailable for
   * Linux. A four extra INPUT reports and a FEATURE report are described by the
   * report descriptor but it does not appear that these enable software to
   * control what the extra buttons map to. The only simple and straightforward
   * solution seems to involve fixing up the report descriptor.
   *
   * Report descriptor format:
   * Positions 13, 15, 21 and 31 store the button bit count, button usage minimum,
   * button usage maximum and padding bit count respectively.
   */
  #define MOUSE_BUTTONS_MAX 8
  static void mouse_button_fixup(struct hid_device *hdev,
  			       __u8 *rdesc, unsigned int rsize,
  			       int nbuttons)
  {
  	if (rsize < 32 || rdesc[12] != 0x95 ||
  	    rdesc[14] != 0x75 || rdesc[15] != 0x01 ||
  	    rdesc[20] != 0x29 || rdesc[30] != 0x75)
  		return;
  	hid_info(hdev, "Fixing up Elecom mouse button count
  ");
  	nbuttons = clamp(nbuttons, 0, MOUSE_BUTTONS_MAX);
  	rdesc[13] = nbuttons;
  	rdesc[21] = nbuttons;
  	rdesc[31] = MOUSE_BUTTONS_MAX - nbuttons;
  }
73e4008dd   Nikolai Kondrashov   HID: allow resizi...
52
53
  static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
  		unsigned int *rsize)
64b386ea1   Richard Nauber   HID: add proper s...
54
  {
0bb7a37f8   Diego Elio Pettenò   HID: elecom: exte...
55
56
57
58
59
60
61
62
63
64
  	switch (hdev->product) {
  	case USB_DEVICE_ID_ELECOM_BM084:
  		/* The BM084 Bluetooth mouse includes a non-existing horizontal
  		 * wheel in the HID descriptor. */
  		if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
  			hid_info(hdev, "Fixing up Elecom BM084 report descriptor
  ");
  			rdesc[47] = 0x00;
  		}
  		break;
79837eded   Tomasz Kramkowski   HID: elecom: refe...
65
66
  	case USB_DEVICE_ID_ELECOM_M_XT3URBK:
  	case USB_DEVICE_ID_ELECOM_M_XT3DRBK:
fbb77e88f   Tomasz Kramkowski   HID: elecom: add ...
67
  	case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
68
69
  		mouse_button_fixup(hdev, rdesc, *rsize, 6);
  		break;
79837eded   Tomasz Kramkowski   HID: elecom: refe...
70
71
72
73
  	case USB_DEVICE_ID_ELECOM_M_DT1URBK:
  	case USB_DEVICE_ID_ELECOM_M_DT1DRBK:
  	case USB_DEVICE_ID_ELECOM_M_HT1URBK:
  	case USB_DEVICE_ID_ELECOM_M_HT1DRBK:
ac58eec2c   Tomasz Kramkowski   HID: elecom: rewr...
74
  		mouse_button_fixup(hdev, rdesc, *rsize, 8);
0bb7a37f8   Diego Elio Pettenò   HID: elecom: exte...
75
  		break;
64b386ea1   Richard Nauber   HID: add proper s...
76
  	}
636a89d43   Jiri Slaby   HID: fix some ind...
77
  	return rdesc;
64b386ea1   Richard Nauber   HID: add proper s...
78
79
80
  }
  
  static const struct hid_device_id elecom_devices[] = {
0bb7a37f8   Diego Elio Pettenò   HID: elecom: exte...
81
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
79837eded   Tomasz Kramkowski   HID: elecom: refe...
82
83
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) },
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
fbb77e88f   Tomasz Kramkowski   HID: elecom: add ...
84
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
79837eded   Tomasz Kramkowski   HID: elecom: refe...
85
86
87
88
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK) },
  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK) },
64b386ea1   Richard Nauber   HID: add proper s...
89
90
91
92
93
94
95
96
97
  	{ }
  };
  MODULE_DEVICE_TABLE(hid, elecom_devices);
  
  static struct hid_driver elecom_driver = {
  	.name = "elecom",
  	.id_table = elecom_devices,
  	.report_fixup = elecom_report_fixup
  };
f425458ea   H Hartley Sweeten   HID: Use module_h...
98
  module_hid_driver(elecom_driver);
64b386ea1   Richard Nauber   HID: add proper s...
99

64b386ea1   Richard Nauber   HID: add proper s...
100
  MODULE_LICENSE("GPL");