Commit bbd128b5acae85b2ef346e95cc5a729ac5252f19
Exists in
master
and in
7 other branches
Merge branches '3m', 'egalax', 'logitech', 'magicmouse', 'ntrig' and 'roccat' into for-linus
Showing 20 changed files Inline Diff
- Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
- Documentation/input/ntrig.txt
- drivers/hid/Kconfig
- drivers/hid/Makefile
- drivers/hid/hid-3m-pct.c
- drivers/hid/hid-core.c
- drivers/hid/hid-egalax.c
- drivers/hid/hid-ids.h
- drivers/hid/hid-input.c
- drivers/hid/hid-lg.c
- drivers/hid/hid-lg.h
- drivers/hid/hid-lg2ff.c
- drivers/hid/hid-lg4ff.c
- drivers/hid/hid-magicmouse.c
- drivers/hid/hid-ntrig.c
- drivers/hid/hid-roccat-pyra.c
- drivers/hid/hid-roccat-pyra.h
- drivers/hid/usbhid/hid-core.c
- drivers/hid/usbhid/hid-quirks.c
- include/linux/hid.h
Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
File was created | 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_cpi | |
2 | Date: August 2010 | ||
3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
4 | Description: It is possible to switch the cpi setting of the mouse with the | ||
5 | press of a button. | ||
6 | When read, this file returns the raw number of the actual cpi | ||
7 | setting reported by the mouse. This number has to be further | ||
8 | processed to receive the real dpi value. | ||
9 | |||
10 | VALUE DPI | ||
11 | 1 400 | ||
12 | 2 800 | ||
13 | 4 1600 | ||
14 | |||
15 | This file is readonly. | ||
16 | |||
17 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile | ||
18 | Date: August 2010 | ||
19 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
20 | Description: When read, this file returns the number of the actual profile in | ||
21 | range 0-4. | ||
22 | This file is readonly. | ||
23 | |||
24 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version | ||
25 | Date: August 2010 | ||
26 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
27 | Description: When read, this file returns the raw integer version number of the | ||
28 | firmware reported by the mouse. Using the integer value eases | ||
29 | further usage in other programs. To receive the real version | ||
30 | number the decimal point has to be shifted 2 positions to the | ||
31 | left. E.g. a returned value of 138 means 1.38 | ||
32 | This file is readonly. | ||
33 | |||
34 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_settings | ||
35 | Date: August 2010 | ||
36 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
37 | Description: The mouse can store 5 profiles which can be switched by the | ||
38 | press of a button. A profile is split in settings and buttons. | ||
39 | profile_settings holds informations like resolution, sensitivity | ||
40 | and light effects. | ||
41 | When written, this file lets one write the respective profile | ||
42 | settings back to the mouse. The data has to be 13 bytes long. | ||
43 | The mouse will reject invalid data. | ||
44 | Which profile to write is determined by the profile number | ||
45 | contained in the data. | ||
46 | This file is writeonly. | ||
47 | |||
48 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_settings | ||
49 | Date: August 2010 | ||
50 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
51 | Description: The mouse can store 5 profiles which can be switched by the | ||
52 | press of a button. A profile is split in settings and buttons. | ||
53 | profile_settings holds informations like resolution, sensitivity | ||
54 | and light effects. | ||
55 | When read, these files return the respective profile settings. | ||
56 | The returned data is 13 bytes in size. | ||
57 | This file is readonly. | ||
58 | |||
59 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_buttons | ||
60 | Date: August 2010 | ||
61 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
62 | Description: The mouse can store 5 profiles which can be switched by the | ||
63 | press of a button. A profile is split in settings and buttons. | ||
64 | profile_buttons holds informations about button layout. | ||
65 | When written, this file lets one write the respective profile | ||
66 | buttons back to the mouse. The data has to be 19 bytes long. | ||
67 | The mouse will reject invalid data. | ||
68 | Which profile to write is determined by the profile number | ||
69 | contained in the data. | ||
70 | This file is writeonly. | ||
71 | |||
72 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_buttons | ||
73 | Date: August 2010 | ||
74 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
75 | Description: The mouse can store 5 profiles which can be switched by the | ||
76 | press of a button. A profile is split in settings and buttons. | ||
77 | profile_buttons holds informations about button layout. | ||
78 | When read, these files return the respective profile buttons. | ||
79 | The returned data is 19 bytes in size. | ||
80 | This file is readonly. | ||
81 | |||
82 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile | ||
83 | Date: August 2010 | ||
84 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
85 | Description: The integer value of this attribute ranges from 0-4. | ||
86 | When read, this attribute returns the number of the profile | ||
87 | that's active when the mouse is powered on. | ||
88 | This file is readonly. | ||
89 | |||
90 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings | ||
91 | Date: August 2010 | ||
92 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
93 | Description: When read, this file returns the settings stored in the mouse. | ||
94 | The size of the data is 3 bytes and holds information on the | ||
95 | startup_profile. | ||
96 | When written, this file lets write settings back to the mouse. | ||
97 | The data has to be 3 bytes long. The mouse will reject invalid | ||
98 | data. | ||
99 |
Documentation/input/ntrig.txt
File was created | 1 | N-Trig touchscreen Driver | |
2 | ------------------------- | ||
3 | Copyright (c) 2008-2010 Rafi Rubin <rafi@seas.upenn.edu> | ||
4 | Copyright (c) 2009-2010 Stephane Chatty | ||
5 | |||
6 | This driver provides support for N-Trig pen and multi-touch sensors. Single | ||
7 | and multi-touch events are translated to the appropriate protocols for | ||
8 | the hid and input systems. Pen events are sufficiently hid compliant and | ||
9 | are left to the hid core. The driver also provides additional filtering | ||
10 | and utility functions accessible with sysfs and module parameters. | ||
11 | |||
12 | This driver has been reported to work properly with multiple N-Trig devices | ||
13 | attached. | ||
14 | |||
15 | |||
16 | Parameters | ||
17 | ---------- | ||
18 | |||
19 | Note: values set at load time are global and will apply to all applicable | ||
20 | devices. Adjusting parameters with sysfs will override the load time values, | ||
21 | but only for that one device. | ||
22 | |||
23 | The following parameters are used to configure filters to reduce noise: | ||
24 | |||
25 | activate_slack number of fingers to ignore before processing events | ||
26 | |||
27 | activation_height size threshold to activate immediately | ||
28 | activation_width | ||
29 | |||
30 | min_height size threshold bellow which fingers are ignored | ||
31 | min_width both to decide activation and during activity | ||
32 | |||
33 | deactivate_slack the number of "no contact" frames to ignore before | ||
34 | propagating the end of activity events | ||
35 | |||
36 | When the last finger is removed from the device, it sends a number of empty | ||
37 | frames. By holding off on deactivation for a few frames we can tolerate false | ||
38 | erroneous disconnects, where the sensor may mistakenly not detect a finger that | ||
39 | is still present. Thus deactivate_slack addresses problems where a users might | ||
40 | see breaks in lines during drawing, or drop an object during a long drag. | ||
41 | |||
42 | |||
43 | Additional sysfs items | ||
44 | ---------------------- | ||
45 | |||
46 | These nodes just provide easy access to the ranges reported by the device. | ||
47 | sensor_logical_height the range for positions reported during activity | ||
48 | sensor_logical_width | ||
49 | |||
50 | sensor_physical_height internal ranges not used for normal events but | ||
51 | sensor_physical_width useful for tuning | ||
52 | |||
53 | All N-Trig devices with product id of 1 report events in the ranges of | ||
54 | X: 0-9600 | ||
55 | Y: 0-7200 | ||
56 | However not all of these devices have the same physical dimensions. Most | ||
57 | seem to be 12" sensors (Dell Latitude XT and XT2 and the HP TX2), and | ||
58 | at least one model (Dell Studio 17) has a 17" sensor. The ratio of physical | ||
59 | to logical sizes is used to adjust the size based filter parameters. | ||
60 | |||
61 | |||
62 | Filtering | ||
63 | --------- | ||
64 | |||
65 | With the release of the early multi-touch firmwares it became increasingly | ||
66 | obvious that these sensors were prone to erroneous events. Users reported | ||
67 | seeing both inappropriately dropped contact and ghosts, contacts reported | ||
68 | where no finger was actually touching the screen. | ||
69 | |||
70 | Deactivation slack helps prevent dropped contact for single touch use, but does | ||
71 | not address the problem of dropping one of more contacts while other contacts | ||
72 | are still active. Drops in the multi-touch context require additional | ||
73 | processing and should be handled in tandem with tacking. | ||
74 | |||
75 | As observed ghost contacts are similar to actual use of the sensor, but they | ||
76 | seem to have different profiles. Ghost activity typically shows up as small | ||
77 | short lived touches. As such, I assume that the longer the continuous stream | ||
78 | of events the more likely those events are from a real contact, and that the | ||
79 | larger the size of each contact the more likely it is real. Balancing the | ||
80 | goals of preventing ghosts and accepting real events quickly (to minimize | ||
81 | user observable latency), the filter accumulates confidence for incoming | ||
82 | events until it hits thresholds and begins propagating. In the interest in | ||
83 | minimizing stored state as well as the cost of operations to make a decision, | ||
84 | I've kept that decision simple. | ||
85 | |||
86 | Time is measured in terms of the number of fingers reported, not frames since | ||
87 | the probability of multiple simultaneous ghosts is expected to drop off | ||
88 | dramatically with increasing numbers. Rather than accumulate weight as a | ||
89 | function of size, I just use it as a binary threshold. A sufficiently large | ||
90 | contact immediately overrides the waiting period and leads to activation. | ||
91 | |||
92 | Setting the activation size thresholds to large values will result in deciding | ||
93 | primarily on activation slack. If you see longer lived ghosts, turning up the | ||
94 | activation slack while reducing the size thresholds may suffice to eliminate | ||
95 | the ghosts while keeping the screen quite responsive to firm taps. | ||
96 | |||
97 | Contacts continue to be filtered with min_height and min_width even after | ||
98 | the initial activation filter is satisfied. The intent is to provide | ||
99 | a mechanism for filtering out ghosts in the form of an extra finger while | ||
100 | you actually are using the screen. In practice this sort of ghost has | ||
101 | been far less problematic or relatively rare and I've left the defaults | ||
102 | set to 0 for both parameters, effectively turning off that filter. | ||
103 | |||
104 | I don't know what the optimal values are for these filters. If the defaults | ||
105 | don't work for you, please play with the parameters. If you do find other | ||
106 | values more comfortable, I would appreciate feedback. | ||
107 | |||
108 | The calibration of these devices does drift over time. If ghosts or contact | ||
109 | dropping worsen and interfere with the normal usage of your device, try | ||
110 | recalibrating it. | ||
111 | |||
112 | |||
113 | Calibration | ||
114 | ----------- | ||
115 | |||
116 | The N-Trig windows tools provide calibration and testing routines. Also an | ||
117 | unofficial unsupported set of user space tools including a calibrator is | ||
118 | available at: | ||
119 | http://code.launchpad.net/~rafi-seas/+junk/ntrig_calib | ||
120 | |||
121 | |||
122 | Tracking | ||
123 | -------- | ||
124 | |||
125 | As of yet, all tested N-Trig firmwares do not track fingers. When multiple | ||
126 | contacts are active they seem to be sorted primarily by Y position. | ||
127 |
drivers/hid/Kconfig
1 | # | 1 | # |
2 | # HID driver configuration | 2 | # HID driver configuration |
3 | # | 3 | # |
4 | menuconfig HID_SUPPORT | 4 | menuconfig HID_SUPPORT |
5 | bool "HID Devices" | 5 | bool "HID Devices" |
6 | depends on INPUT | 6 | depends on INPUT |
7 | default y | 7 | default y |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here to get to see options for various computer-human interface | 9 | Say Y here to get to see options for various computer-human interface |
10 | device drivers. This option alone does not add any kernel code. | 10 | device drivers. This option alone does not add any kernel code. |
11 | 11 | ||
12 | If you say N, all options in this submenu will be skipped and disabled. | 12 | If you say N, all options in this submenu will be skipped and disabled. |
13 | 13 | ||
14 | if HID_SUPPORT | 14 | if HID_SUPPORT |
15 | 15 | ||
16 | config HID | 16 | config HID |
17 | tristate "Generic HID support" | 17 | tristate "Generic HID support" |
18 | depends on INPUT | 18 | depends on INPUT |
19 | default y | 19 | default y |
20 | ---help--- | 20 | ---help--- |
21 | A human interface device (HID) is a type of computer device that | 21 | A human interface device (HID) is a type of computer device that |
22 | interacts directly with and takes input from humans. The term "HID" | 22 | interacts directly with and takes input from humans. The term "HID" |
23 | most commonly used to refer to the USB-HID specification, but other | 23 | most commonly used to refer to the USB-HID specification, but other |
24 | devices (such as, but not strictly limited to, Bluetooth) are | 24 | devices (such as, but not strictly limited to, Bluetooth) are |
25 | designed using HID specification (this involves certain keyboards, | 25 | designed using HID specification (this involves certain keyboards, |
26 | mice, tablets, etc). This option compiles into kernel the generic | 26 | mice, tablets, etc). This option compiles into kernel the generic |
27 | HID layer code (parser, usages, etc.), which can then be used by | 27 | HID layer code (parser, usages, etc.), which can then be used by |
28 | transport-specific HID implementation (like USB or Bluetooth). | 28 | transport-specific HID implementation (like USB or Bluetooth). |
29 | 29 | ||
30 | For docs and specs, see http://www.usb.org/developers/hidpage/ | 30 | For docs and specs, see http://www.usb.org/developers/hidpage/ |
31 | 31 | ||
32 | If unsure, say Y. | 32 | If unsure, say Y. |
33 | 33 | ||
34 | config HIDRAW | 34 | config HIDRAW |
35 | bool "/dev/hidraw raw HID device support" | 35 | bool "/dev/hidraw raw HID device support" |
36 | depends on HID | 36 | depends on HID |
37 | ---help--- | 37 | ---help--- |
38 | Say Y here if you want to support HID devices (from the USB | 38 | Say Y here if you want to support HID devices (from the USB |
39 | specification standpoint) that aren't strictly user interface | 39 | specification standpoint) that aren't strictly user interface |
40 | devices, like monitor controls and Uninterruptable Power Supplies. | 40 | devices, like monitor controls and Uninterruptable Power Supplies. |
41 | 41 | ||
42 | This module supports these devices separately using a separate | 42 | This module supports these devices separately using a separate |
43 | event interface on /dev/hidraw. | 43 | event interface on /dev/hidraw. |
44 | 44 | ||
45 | There is also a /dev/hiddev configuration option in the USB HID | 45 | There is also a /dev/hiddev configuration option in the USB HID |
46 | configuration menu. In comparison to hiddev, this device does not process | 46 | configuration menu. In comparison to hiddev, this device does not process |
47 | the hid events at all (no parsing, no lookups). This lets applications | 47 | the hid events at all (no parsing, no lookups). This lets applications |
48 | to work on raw hid events when they want to, and avoid using transport-specific | 48 | to work on raw hid events when they want to, and avoid using transport-specific |
49 | userspace libhid/libusb libraries. | 49 | userspace libhid/libusb libraries. |
50 | 50 | ||
51 | If unsure, say Y. | 51 | If unsure, say Y. |
52 | 52 | ||
53 | source "drivers/hid/usbhid/Kconfig" | 53 | source "drivers/hid/usbhid/Kconfig" |
54 | 54 | ||
55 | menu "Special HID drivers" | 55 | menu "Special HID drivers" |
56 | depends on HID | 56 | depends on HID |
57 | 57 | ||
58 | config HID_3M_PCT | 58 | config HID_3M_PCT |
59 | tristate "3M PCT touchscreen" | 59 | tristate "3M PCT touchscreen" |
60 | depends on USB_HID | 60 | depends on USB_HID |
61 | ---help--- | 61 | ---help--- |
62 | Support for 3M PCT touch screens. | 62 | Support for 3M PCT touch screens. |
63 | 63 | ||
64 | config HID_A4TECH | 64 | config HID_A4TECH |
65 | tristate "A4 tech mice" if EMBEDDED | 65 | tristate "A4 tech mice" if EMBEDDED |
66 | depends on USB_HID | 66 | depends on USB_HID |
67 | default !EMBEDDED | 67 | default !EMBEDDED |
68 | ---help--- | 68 | ---help--- |
69 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | 69 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. |
70 | 70 | ||
71 | config HID_ACRUX_FF | 71 | config HID_ACRUX_FF |
72 | tristate "ACRUX force feedback" | 72 | tristate "ACRUX force feedback" |
73 | depends on USB_HID | 73 | depends on USB_HID |
74 | select INPUT_FF_MEMLESS | 74 | select INPUT_FF_MEMLESS |
75 | ---help--- | 75 | ---help--- |
76 | Say Y here if you want to enable force feedback support for ACRUX | 76 | Say Y here if you want to enable force feedback support for ACRUX |
77 | game controllers. | 77 | game controllers. |
78 | 78 | ||
79 | config HID_APPLE | 79 | config HID_APPLE |
80 | tristate "Apple {i,Power,Mac}Books" if EMBEDDED | 80 | tristate "Apple {i,Power,Mac}Books" if EMBEDDED |
81 | depends on (USB_HID || BT_HIDP) | 81 | depends on (USB_HID || BT_HIDP) |
82 | default !EMBEDDED | 82 | default !EMBEDDED |
83 | ---help--- | 83 | ---help--- |
84 | Support for some Apple devices which less or more break | 84 | Support for some Apple devices which less or more break |
85 | HID specification. | 85 | HID specification. |
86 | 86 | ||
87 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, | 87 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, |
88 | MacBooks, MacBook Pros and Apple Aluminum. | 88 | MacBooks, MacBook Pros and Apple Aluminum. |
89 | 89 | ||
90 | config HID_BELKIN | 90 | config HID_BELKIN |
91 | tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED | 91 | tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED |
92 | depends on USB_HID | 92 | depends on USB_HID |
93 | default !EMBEDDED | 93 | default !EMBEDDED |
94 | ---help--- | 94 | ---help--- |
95 | Support for Belkin Flip KVM and Wireless keyboard. | 95 | Support for Belkin Flip KVM and Wireless keyboard. |
96 | 96 | ||
97 | config HID_CANDO | 97 | config HID_CANDO |
98 | tristate "Cando dual touch panel" | 98 | tristate "Cando dual touch panel" |
99 | depends on USB_HID | 99 | depends on USB_HID |
100 | ---help--- | 100 | ---help--- |
101 | Support for Cando dual touch panel. | 101 | Support for Cando dual touch panel. |
102 | 102 | ||
103 | config HID_CHERRY | 103 | config HID_CHERRY |
104 | tristate "Cherry Cymotion keyboard" if EMBEDDED | 104 | tristate "Cherry Cymotion keyboard" if EMBEDDED |
105 | depends on USB_HID | 105 | depends on USB_HID |
106 | default !EMBEDDED | 106 | default !EMBEDDED |
107 | ---help--- | 107 | ---help--- |
108 | Support for Cherry Cymotion keyboard. | 108 | Support for Cherry Cymotion keyboard. |
109 | 109 | ||
110 | config HID_CHICONY | 110 | config HID_CHICONY |
111 | tristate "Chicony Tactical pad" if EMBEDDED | 111 | tristate "Chicony Tactical pad" if EMBEDDED |
112 | depends on USB_HID | 112 | depends on USB_HID |
113 | default !EMBEDDED | 113 | default !EMBEDDED |
114 | ---help--- | 114 | ---help--- |
115 | Support for Chicony Tactical pad. | 115 | Support for Chicony Tactical pad. |
116 | 116 | ||
117 | config HID_PRODIKEYS | 117 | config HID_PRODIKEYS |
118 | tristate "Prodikeys PC-MIDI Keyboard support" | 118 | tristate "Prodikeys PC-MIDI Keyboard support" |
119 | depends on USB_HID && SND | 119 | depends on USB_HID && SND |
120 | select SND_RAWMIDI | 120 | select SND_RAWMIDI |
121 | ---help--- | 121 | ---help--- |
122 | Support for Prodikeys PC-MIDI Keyboard device support. | 122 | Support for Prodikeys PC-MIDI Keyboard device support. |
123 | Say Y here to enable support for this device. | 123 | Say Y here to enable support for this device. |
124 | - Prodikeys PC-MIDI keyboard. | 124 | - Prodikeys PC-MIDI keyboard. |
125 | The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI | 125 | The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI |
126 | input and one MIDI output. These MIDI jacks appear as | 126 | input and one MIDI output. These MIDI jacks appear as |
127 | a sound "card" in the ALSA sound system. | 127 | a sound "card" in the ALSA sound system. |
128 | Note: if you say N here, this device will still function as a basic | 128 | Note: if you say N here, this device will still function as a basic |
129 | multimedia keyboard, but will lack support for the musical keyboard | 129 | multimedia keyboard, but will lack support for the musical keyboard |
130 | and some additional multimedia keys. | 130 | and some additional multimedia keys. |
131 | 131 | ||
132 | config HID_CYPRESS | 132 | config HID_CYPRESS |
133 | tristate "Cypress mouse and barcode readers" if EMBEDDED | 133 | tristate "Cypress mouse and barcode readers" if EMBEDDED |
134 | depends on USB_HID | 134 | depends on USB_HID |
135 | default !EMBEDDED | 135 | default !EMBEDDED |
136 | ---help--- | 136 | ---help--- |
137 | Support for cypress mouse and barcode readers. | 137 | Support for cypress mouse and barcode readers. |
138 | 138 | ||
139 | config HID_DRAGONRISE | 139 | config HID_DRAGONRISE |
140 | tristate "DragonRise Inc. game controller" | 140 | tristate "DragonRise Inc. game controller" |
141 | depends on USB_HID | 141 | depends on USB_HID |
142 | ---help--- | 142 | ---help--- |
143 | Say Y here if you have DragonRise Inc.game controllers. | 143 | Say Y here if you have DragonRise Inc.game controllers. |
144 | 144 | ||
145 | config DRAGONRISE_FF | 145 | config DRAGONRISE_FF |
146 | bool "DragonRise Inc. force feedback" | 146 | bool "DragonRise Inc. force feedback" |
147 | depends on HID_DRAGONRISE | 147 | depends on HID_DRAGONRISE |
148 | select INPUT_FF_MEMLESS | 148 | select INPUT_FF_MEMLESS |
149 | ---help--- | 149 | ---help--- |
150 | Say Y here if you want to enable force feedback support for DragonRise Inc. | 150 | Say Y here if you want to enable force feedback support for DragonRise Inc. |
151 | game controllers. | 151 | game controllers. |
152 | 152 | ||
153 | config HID_EGALAX | 153 | config HID_EGALAX |
154 | tristate "eGalax multi-touch panel" | 154 | tristate "eGalax multi-touch panel" |
155 | depends on USB_HID | 155 | depends on USB_HID |
156 | ---help--- | 156 | ---help--- |
157 | Support for the eGalax dual-touch panel. | 157 | Support for the eGalax dual-touch panel. |
158 | 158 | ||
159 | config HID_ELECOM | 159 | config HID_ELECOM |
160 | tristate "ELECOM BM084 bluetooth mouse" | 160 | tristate "ELECOM BM084 bluetooth mouse" |
161 | depends on BT_HIDP | 161 | depends on BT_HIDP |
162 | ---help--- | 162 | ---help--- |
163 | Support for the ELECOM BM084 (bluetooth mouse). | 163 | Support for the ELECOM BM084 (bluetooth mouse). |
164 | 164 | ||
165 | config HID_EZKEY | 165 | config HID_EZKEY |
166 | tristate "Ezkey BTC 8193 keyboard" if EMBEDDED | 166 | tristate "Ezkey BTC 8193 keyboard" if EMBEDDED |
167 | depends on USB_HID | 167 | depends on USB_HID |
168 | default !EMBEDDED | 168 | default !EMBEDDED |
169 | ---help--- | 169 | ---help--- |
170 | Support for Ezkey BTC 8193 keyboard. | 170 | Support for Ezkey BTC 8193 keyboard. |
171 | 171 | ||
172 | config HID_KYE | 172 | config HID_KYE |
173 | tristate "Kye/Genius Ergo Mouse" if EMBEDDED | 173 | tristate "Kye/Genius Ergo Mouse" if EMBEDDED |
174 | depends on USB_HID | 174 | depends on USB_HID |
175 | default !EMBEDDED | 175 | default !EMBEDDED |
176 | ---help--- | 176 | ---help--- |
177 | Support for Kye/Genius Ergo Mouse. | 177 | Support for Kye/Genius Ergo Mouse. |
178 | 178 | ||
179 | config HID_GYRATION | 179 | config HID_GYRATION |
180 | tristate "Gyration remote control" | 180 | tristate "Gyration remote control" |
181 | depends on USB_HID | 181 | depends on USB_HID |
182 | ---help--- | 182 | ---help--- |
183 | Support for Gyration remote control. | 183 | Support for Gyration remote control. |
184 | 184 | ||
185 | config HID_TWINHAN | 185 | config HID_TWINHAN |
186 | tristate "Twinhan IR remote control" | 186 | tristate "Twinhan IR remote control" |
187 | depends on USB_HID | 187 | depends on USB_HID |
188 | ---help--- | 188 | ---help--- |
189 | Support for Twinhan IR remote control. | 189 | Support for Twinhan IR remote control. |
190 | 190 | ||
191 | config HID_KENSINGTON | 191 | config HID_KENSINGTON |
192 | tristate "Kensington Slimblade Trackball" if EMBEDDED | 192 | tristate "Kensington Slimblade Trackball" if EMBEDDED |
193 | depends on USB_HID | 193 | depends on USB_HID |
194 | default !EMBEDDED | 194 | default !EMBEDDED |
195 | ---help--- | 195 | ---help--- |
196 | Support for Kensington Slimblade Trackball. | 196 | Support for Kensington Slimblade Trackball. |
197 | 197 | ||
198 | config HID_LOGITECH | 198 | config HID_LOGITECH |
199 | tristate "Logitech devices" if EMBEDDED | 199 | tristate "Logitech devices" if EMBEDDED |
200 | depends on USB_HID | 200 | depends on USB_HID |
201 | default !EMBEDDED | 201 | default !EMBEDDED |
202 | ---help--- | 202 | ---help--- |
203 | Support for Logitech devices that are not fully compliant with HID standard. | 203 | Support for Logitech devices that are not fully compliant with HID standard. |
204 | 204 | ||
205 | config LOGITECH_FF | 205 | config LOGITECH_FF |
206 | bool "Logitech force feedback support" | 206 | bool "Logitech force feedback support" |
207 | depends on HID_LOGITECH | 207 | depends on HID_LOGITECH |
208 | select INPUT_FF_MEMLESS | 208 | select INPUT_FF_MEMLESS |
209 | help | 209 | help |
210 | Say Y here if you have one of these devices: | 210 | Say Y here if you have one of these devices: |
211 | - Logitech WingMan Cordless RumblePad | 211 | - Logitech WingMan Cordless RumblePad |
212 | - Logitech WingMan Cordless RumblePad 2 | 212 | - Logitech WingMan Cordless RumblePad 2 |
213 | - Logitech WingMan Force 3D | 213 | - Logitech WingMan Force 3D |
214 | - Logitech Formula Force EX | 214 | - Logitech Formula Force EX |
215 | - Logitech WingMan Formula Force GP | 215 | - Logitech WingMan Formula Force GP |
216 | - Logitech MOMO Force wheel | 216 | - Logitech MOMO Force wheel |
217 | 217 | ||
218 | and if you want to enable force feedback for them. | 218 | and if you want to enable force feedback for them. |
219 | Note: if you say N here, this device will still be supported, but without | 219 | Note: if you say N here, this device will still be supported, but without |
220 | force feedback. | 220 | force feedback. |
221 | 221 | ||
222 | config LOGIRUMBLEPAD2_FF | 222 | config LOGIRUMBLEPAD2_FF |
223 | bool "Logitech Rumblepad 2 force feedback support" | 223 | bool "Logitech RumblePad/Rumblepad 2 force feedback support" |
224 | depends on HID_LOGITECH | 224 | depends on HID_LOGITECH |
225 | select INPUT_FF_MEMLESS | 225 | select INPUT_FF_MEMLESS |
226 | help | 226 | help |
227 | Say Y here if you want to enable force feedback support for Logitech | 227 | Say Y here if you want to enable force feedback support for Logitech |
228 | Rumblepad 2 devices. | 228 | RumblePad and Rumblepad 2 devices. |
229 | 229 | ||
230 | config LOGIG940_FF | 230 | config LOGIG940_FF |
231 | bool "Logitech Flight System G940 force feedback support" | 231 | bool "Logitech Flight System G940 force feedback support" |
232 | depends on HID_LOGITECH | 232 | depends on HID_LOGITECH |
233 | select INPUT_FF_MEMLESS | 233 | select INPUT_FF_MEMLESS |
234 | help | 234 | help |
235 | Say Y here if you want to enable force feedback support for Logitech | 235 | Say Y here if you want to enable force feedback support for Logitech |
236 | Flight System G940 devices. | 236 | Flight System G940 devices. |
237 | 237 | ||
238 | config LOGIWII_FF | ||
239 | bool "Logitech Speed Force Wireless force feedback support" | ||
240 | depends on HID_LOGITECH | ||
241 | select INPUT_FF_MEMLESS | ||
242 | help | ||
243 | Say Y here if you want to enable force feedback support for Logitech | ||
244 | Speed Force Wireless (Wii) devices. | ||
245 | |||
238 | config HID_MAGICMOUSE | 246 | config HID_MAGICMOUSE |
239 | tristate "Apple MagicMouse multi-touch support" | 247 | tristate "Apple MagicMouse multi-touch support" |
240 | depends on BT_HIDP | 248 | depends on BT_HIDP |
241 | ---help--- | 249 | ---help--- |
242 | Support for the Apple Magic Mouse multi-touch. | 250 | Support for the Apple Magic Mouse multi-touch. |
243 | 251 | ||
244 | Say Y here if you want support for the multi-touch features of the | 252 | Say Y here if you want support for the multi-touch features of the |
245 | Apple Wireless "Magic" Mouse. | 253 | Apple Wireless "Magic" Mouse. |
246 | 254 | ||
247 | config HID_MICROSOFT | 255 | config HID_MICROSOFT |
248 | tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED | 256 | tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED |
249 | depends on USB_HID | 257 | depends on USB_HID |
250 | default !EMBEDDED | 258 | default !EMBEDDED |
251 | ---help--- | 259 | ---help--- |
252 | Support for Microsoft devices that are not fully compliant with HID standard. | 260 | Support for Microsoft devices that are not fully compliant with HID standard. |
253 | 261 | ||
254 | config HID_MOSART | 262 | config HID_MOSART |
255 | tristate "MosArt dual-touch panels" | 263 | tristate "MosArt dual-touch panels" |
256 | depends on USB_HID | 264 | depends on USB_HID |
257 | ---help--- | 265 | ---help--- |
258 | Support for MosArt dual-touch panels. | 266 | Support for MosArt dual-touch panels. |
259 | 267 | ||
260 | config HID_MONTEREY | 268 | config HID_MONTEREY |
261 | tristate "Monterey Genius KB29E keyboard" if EMBEDDED | 269 | tristate "Monterey Genius KB29E keyboard" if EMBEDDED |
262 | depends on USB_HID | 270 | depends on USB_HID |
263 | default !EMBEDDED | 271 | default !EMBEDDED |
264 | ---help--- | 272 | ---help--- |
265 | Support for Monterey Genius KB29E. | 273 | Support for Monterey Genius KB29E. |
266 | 274 | ||
267 | config HID_NTRIG | 275 | config HID_NTRIG |
268 | tristate "N-Trig touch screen" | 276 | tristate "N-Trig touch screen" |
269 | depends on USB_HID | 277 | depends on USB_HID |
270 | ---help--- | 278 | ---help--- |
271 | Support for N-Trig touch screen. | 279 | Support for N-Trig touch screen. |
272 | 280 | ||
273 | config HID_ORTEK | 281 | config HID_ORTEK |
274 | tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" | 282 | tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" |
275 | depends on USB_HID | 283 | depends on USB_HID |
276 | ---help--- | 284 | ---help--- |
277 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. | 285 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. |
278 | 286 | ||
279 | config HID_PANTHERLORD | 287 | config HID_PANTHERLORD |
280 | tristate "Pantherlord/GreenAsia game controller" | 288 | tristate "Pantherlord/GreenAsia game controller" |
281 | depends on USB_HID | 289 | depends on USB_HID |
282 | ---help--- | 290 | ---help--- |
283 | Say Y here if you have a PantherLord/GreenAsia based game controller | 291 | Say Y here if you have a PantherLord/GreenAsia based game controller |
284 | or adapter. | 292 | or adapter. |
285 | 293 | ||
286 | config PANTHERLORD_FF | 294 | config PANTHERLORD_FF |
287 | bool "Pantherlord force feedback support" | 295 | bool "Pantherlord force feedback support" |
288 | depends on HID_PANTHERLORD | 296 | depends on HID_PANTHERLORD |
289 | select INPUT_FF_MEMLESS | 297 | select INPUT_FF_MEMLESS |
290 | ---help--- | 298 | ---help--- |
291 | Say Y here if you have a PantherLord/GreenAsia based game controller | 299 | Say Y here if you have a PantherLord/GreenAsia based game controller |
292 | or adapter and want to enable force feedback support for it. | 300 | or adapter and want to enable force feedback support for it. |
293 | 301 | ||
294 | config HID_PETALYNX | 302 | config HID_PETALYNX |
295 | tristate "Petalynx Maxter remote control" | 303 | tristate "Petalynx Maxter remote control" |
296 | depends on USB_HID | 304 | depends on USB_HID |
297 | ---help--- | 305 | ---help--- |
298 | Support for Petalynx Maxter remote control. | 306 | Support for Petalynx Maxter remote control. |
299 | 307 | ||
300 | config HID_PICOLCD | 308 | config HID_PICOLCD |
301 | tristate "PicoLCD (graphic version)" | 309 | tristate "PicoLCD (graphic version)" |
302 | depends on USB_HID | 310 | depends on USB_HID |
303 | ---help--- | 311 | ---help--- |
304 | This provides support for Minibox PicoLCD devices, currently | 312 | This provides support for Minibox PicoLCD devices, currently |
305 | only the graphical ones are supported. | 313 | only the graphical ones are supported. |
306 | 314 | ||
307 | This includes support for the following device features: | 315 | This includes support for the following device features: |
308 | - Keypad | 316 | - Keypad |
309 | - Switching between Firmware and Flash mode | 317 | - Switching between Firmware and Flash mode |
310 | - EEProm / Flash access (via debugfs) | 318 | - EEProm / Flash access (via debugfs) |
311 | Features selectively enabled: | 319 | Features selectively enabled: |
312 | - Framebuffer for monochrome 256x64 display | 320 | - Framebuffer for monochrome 256x64 display |
313 | - Backlight control | 321 | - Backlight control |
314 | - Contrast control | 322 | - Contrast control |
315 | - General purpose outputs | 323 | - General purpose outputs |
316 | Features that are not (yet) supported: | 324 | Features that are not (yet) supported: |
317 | - IR | 325 | - IR |
318 | 326 | ||
319 | config HID_PICOLCD_FB | 327 | config HID_PICOLCD_FB |
320 | bool "Framebuffer support" if EMBEDDED | 328 | bool "Framebuffer support" if EMBEDDED |
321 | default !EMBEDDED | 329 | default !EMBEDDED |
322 | depends on HID_PICOLCD | 330 | depends on HID_PICOLCD |
323 | depends on HID_PICOLCD=FB || FB=y | 331 | depends on HID_PICOLCD=FB || FB=y |
324 | select FB_DEFERRED_IO | 332 | select FB_DEFERRED_IO |
325 | select FB_SYS_FILLRECT | 333 | select FB_SYS_FILLRECT |
326 | select FB_SYS_COPYAREA | 334 | select FB_SYS_COPYAREA |
327 | select FB_SYS_IMAGEBLIT | 335 | select FB_SYS_IMAGEBLIT |
328 | select FB_SYS_FOPS | 336 | select FB_SYS_FOPS |
329 | ---help--- | 337 | ---help--- |
330 | Provide access to PicoLCD's 256x64 monochrome display via a | 338 | Provide access to PicoLCD's 256x64 monochrome display via a |
331 | frambuffer device. | 339 | frambuffer device. |
332 | 340 | ||
333 | config HID_PICOLCD_BACKLIGHT | 341 | config HID_PICOLCD_BACKLIGHT |
334 | bool "Backlight control" if EMBEDDED | 342 | bool "Backlight control" if EMBEDDED |
335 | default !EMBEDDED | 343 | default !EMBEDDED |
336 | depends on HID_PICOLCD | 344 | depends on HID_PICOLCD |
337 | depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y | 345 | depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y |
338 | ---help--- | 346 | ---help--- |
339 | Provide access to PicoLCD's backlight control via backlight | 347 | Provide access to PicoLCD's backlight control via backlight |
340 | class. | 348 | class. |
341 | 349 | ||
342 | config HID_PICOLCD_LCD | 350 | config HID_PICOLCD_LCD |
343 | bool "Contrast control" if EMBEDDED | 351 | bool "Contrast control" if EMBEDDED |
344 | default !EMBEDDED | 352 | default !EMBEDDED |
345 | depends on HID_PICOLCD | 353 | depends on HID_PICOLCD |
346 | depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y | 354 | depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y |
347 | ---help--- | 355 | ---help--- |
348 | Provide access to PicoLCD's LCD contrast via lcd class. | 356 | Provide access to PicoLCD's LCD contrast via lcd class. |
349 | 357 | ||
350 | config HID_PICOLCD_LEDS | 358 | config HID_PICOLCD_LEDS |
351 | bool "GPO via leds class" if EMBEDDED | 359 | bool "GPO via leds class" if EMBEDDED |
352 | default !EMBEDDED | 360 | default !EMBEDDED |
353 | depends on HID_PICOLCD | 361 | depends on HID_PICOLCD |
354 | depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y | 362 | depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y |
355 | ---help--- | 363 | ---help--- |
356 | Provide access to PicoLCD's GPO pins via leds class. | 364 | Provide access to PicoLCD's GPO pins via leds class. |
357 | 365 | ||
358 | config HID_QUANTA | 366 | config HID_QUANTA |
359 | tristate "Quanta Optical Touch panels" | 367 | tristate "Quanta Optical Touch panels" |
360 | depends on USB_HID | 368 | depends on USB_HID |
361 | ---help--- | 369 | ---help--- |
362 | Support for Quanta Optical Touch dual-touch panels. | 370 | Support for Quanta Optical Touch dual-touch panels. |
363 | 371 | ||
364 | config HID_ROCCAT | 372 | config HID_ROCCAT |
365 | tristate "Roccat special event support" | 373 | tristate "Roccat special event support" |
366 | depends on USB_HID | 374 | depends on USB_HID |
367 | ---help--- | 375 | ---help--- |
368 | Support for Roccat special events. | 376 | Support for Roccat special events. |
369 | Say Y here if you have a Roccat mouse or keyboard and want OSD or | 377 | Say Y here if you have a Roccat mouse or keyboard and want OSD or |
370 | macro execution support. | 378 | macro execution support. |
371 | 379 | ||
372 | config HID_ROCCAT_KONE | 380 | config HID_ROCCAT_KONE |
373 | tristate "Roccat Kone Mouse support" | 381 | tristate "Roccat Kone Mouse support" |
374 | depends on USB_HID | 382 | depends on USB_HID |
375 | select HID_ROCCAT | 383 | select HID_ROCCAT |
376 | ---help--- | 384 | ---help--- |
377 | Support for Roccat Kone mouse. | 385 | Support for Roccat Kone mouse. |
386 | |||
387 | config HID_ROCCAT_PYRA | ||
388 | tristate "Roccat Pyra mouse support" | ||
389 | depends on USB_HID | ||
390 | select HID_ROCCAT | ||
391 | ---help--- | ||
392 | Support for Roccat Pyra mouse. | ||
378 | 393 | ||
379 | config HID_SAMSUNG | 394 | config HID_SAMSUNG |
380 | tristate "Samsung InfraRed remote control or keyboards" | 395 | tristate "Samsung InfraRed remote control or keyboards" |
381 | depends on USB_HID | 396 | depends on USB_HID |
382 | ---help--- | 397 | ---help--- |
383 | Support for Samsung InfraRed remote control or keyboards. | 398 | Support for Samsung InfraRed remote control or keyboards. |
384 | 399 | ||
385 | config HID_SONY | 400 | config HID_SONY |
386 | tristate "Sony PS3 controller" | 401 | tristate "Sony PS3 controller" |
387 | depends on USB_HID | 402 | depends on USB_HID |
388 | ---help--- | 403 | ---help--- |
389 | Support for Sony PS3 controller. | 404 | Support for Sony PS3 controller. |
390 | 405 | ||
391 | config HID_STANTUM | 406 | config HID_STANTUM |
392 | tristate "Stantum multitouch panel" | 407 | tristate "Stantum multitouch panel" |
393 | depends on USB_HID | 408 | depends on USB_HID |
394 | ---help--- | 409 | ---help--- |
395 | Support for Stantum multitouch panel. | 410 | Support for Stantum multitouch panel. |
396 | 411 | ||
397 | config HID_SUNPLUS | 412 | config HID_SUNPLUS |
398 | tristate "Sunplus wireless desktop" | 413 | tristate "Sunplus wireless desktop" |
399 | depends on USB_HID | 414 | depends on USB_HID |
400 | ---help--- | 415 | ---help--- |
401 | Support for Sunplus wireless desktop. | 416 | Support for Sunplus wireless desktop. |
402 | 417 | ||
403 | config HID_GREENASIA | 418 | config HID_GREENASIA |
404 | tristate "GreenAsia (Product ID 0x12) game controller support" | 419 | tristate "GreenAsia (Product ID 0x12) game controller support" |
405 | depends on USB_HID | 420 | depends on USB_HID |
406 | ---help--- | 421 | ---help--- |
407 | Say Y here if you have a GreenAsia (Product ID 0x12) based game | 422 | Say Y here if you have a GreenAsia (Product ID 0x12) based game |
408 | controller or adapter. | 423 | controller or adapter. |
409 | 424 | ||
410 | config GREENASIA_FF | 425 | config GREENASIA_FF |
411 | bool "GreenAsia (Product ID 0x12) force feedback support" | 426 | bool "GreenAsia (Product ID 0x12) force feedback support" |
412 | depends on HID_GREENASIA | 427 | depends on HID_GREENASIA |
413 | select INPUT_FF_MEMLESS | 428 | select INPUT_FF_MEMLESS |
414 | ---help--- | 429 | ---help--- |
415 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller | 430 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller |
416 | (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter | 431 | (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter |
417 | and want to enable force feedback support for it. | 432 | and want to enable force feedback support for it. |
418 | 433 | ||
419 | config HID_SMARTJOYPLUS | 434 | config HID_SMARTJOYPLUS |
420 | tristate "SmartJoy PLUS PS2/USB adapter support" | 435 | tristate "SmartJoy PLUS PS2/USB adapter support" |
421 | depends on USB_HID | 436 | depends on USB_HID |
422 | ---help--- | 437 | ---help--- |
423 | Support for SmartJoy PLUS PS2/USB adapter. | 438 | Support for SmartJoy PLUS PS2/USB adapter. |
424 | 439 | ||
425 | config SMARTJOYPLUS_FF | 440 | config SMARTJOYPLUS_FF |
426 | bool "SmartJoy PLUS PS2/USB adapter force feedback support" | 441 | bool "SmartJoy PLUS PS2/USB adapter force feedback support" |
427 | depends on HID_SMARTJOYPLUS | 442 | depends on HID_SMARTJOYPLUS |
428 | select INPUT_FF_MEMLESS | 443 | select INPUT_FF_MEMLESS |
429 | ---help--- | 444 | ---help--- |
430 | Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to | 445 | Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to |
431 | enable force feedback support for it. | 446 | enable force feedback support for it. |
432 | 447 | ||
433 | config HID_TOPSEED | 448 | config HID_TOPSEED |
434 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" | 449 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" |
435 | depends on USB_HID | 450 | depends on USB_HID |
436 | ---help--- | 451 | ---help--- |
437 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic | 452 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic |
438 | CLLRCMCE remote control. | 453 | CLLRCMCE remote control. |
439 | 454 | ||
440 | config HID_THRUSTMASTER | 455 | config HID_THRUSTMASTER |
441 | tristate "ThrustMaster devices support" | 456 | tristate "ThrustMaster devices support" |
442 | depends on USB_HID | 457 | depends on USB_HID |
443 | ---help--- | 458 | ---help--- |
444 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or | 459 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or |
445 | a THRUSTMASTER Ferrari GT Rumble Wheel. | 460 | a THRUSTMASTER Ferrari GT Rumble Wheel. |
446 | 461 | ||
447 | config THRUSTMASTER_FF | 462 | config THRUSTMASTER_FF |
448 | bool "ThrustMaster devices force feedback support" | 463 | bool "ThrustMaster devices force feedback support" |
449 | depends on HID_THRUSTMASTER | 464 | depends on HID_THRUSTMASTER |
450 | select INPUT_FF_MEMLESS | 465 | select INPUT_FF_MEMLESS |
451 | ---help--- | 466 | ---help--- |
452 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3, | 467 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3, |
453 | a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT | 468 | a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT |
454 | Rumble Force or Force Feedback Wheel. | 469 | Rumble Force or Force Feedback Wheel. |
455 | 470 | ||
456 | config HID_WACOM | 471 | config HID_WACOM |
457 | tristate "Wacom Bluetooth devices support" | 472 | tristate "Wacom Bluetooth devices support" |
458 | depends on BT_HIDP | 473 | depends on BT_HIDP |
459 | ---help--- | 474 | ---help--- |
460 | Support for Wacom Graphire Bluetooth tablet. | 475 | Support for Wacom Graphire Bluetooth tablet. |
461 | 476 | ||
462 | config HID_WACOM_POWER_SUPPLY | 477 | config HID_WACOM_POWER_SUPPLY |
463 | bool "Wacom Bluetooth devices power supply status support" | 478 | bool "Wacom Bluetooth devices power supply status support" |
464 | depends on HID_WACOM | 479 | depends on HID_WACOM |
465 | select POWER_SUPPLY | 480 | select POWER_SUPPLY |
466 | ---help--- | 481 | ---help--- |
467 | Say Y here if you want to enable power supply status monitoring for | 482 | Say Y here if you want to enable power supply status monitoring for |
468 | Wacom Bluetooth devices. | 483 | Wacom Bluetooth devices. |
469 | 484 | ||
470 | config HID_ZEROPLUS | 485 | config HID_ZEROPLUS |
471 | tristate "Zeroplus based game controller support" | 486 | tristate "Zeroplus based game controller support" |
472 | depends on USB_HID | 487 | depends on USB_HID |
473 | ---help--- | 488 | ---help--- |
474 | Say Y here if you have a Zeroplus based game controller. | 489 | Say Y here if you have a Zeroplus based game controller. |
475 | 490 | ||
476 | config ZEROPLUS_FF | 491 | config ZEROPLUS_FF |
477 | bool "Zeroplus based game controller force feedback support" | 492 | bool "Zeroplus based game controller force feedback support" |
478 | depends on HID_ZEROPLUS | 493 | depends on HID_ZEROPLUS |
479 | select INPUT_FF_MEMLESS | 494 | select INPUT_FF_MEMLESS |
480 | ---help--- | 495 | ---help--- |
481 | Say Y here if you have a Zeroplus based game controller and want | 496 | Say Y here if you have a Zeroplus based game controller and want |
482 | to have force feedback support for it. | 497 | to have force feedback support for it. |
483 | 498 | ||
484 | config HID_ZYDACRON | 499 | config HID_ZYDACRON |
485 | tristate "Zydacron remote control support" | 500 | tristate "Zydacron remote control support" |
486 | depends on USB_HID | 501 | depends on USB_HID |
487 | ---help--- | 502 | ---help--- |
488 | Support for Zydacron remote control. | 503 | Support for Zydacron remote control. |
489 | 504 | ||
490 | endmenu | 505 | endmenu |
491 | 506 | ||
492 | endif # HID_SUPPORT | 507 | endif # HID_SUPPORT |
493 | 508 |
drivers/hid/Makefile
1 | # | 1 | # |
2 | # Makefile for the HID driver | 2 | # Makefile for the HID driver |
3 | # | 3 | # |
4 | hid-objs := hid-core.o hid-input.o | 4 | hid-objs := hid-core.o hid-input.o |
5 | 5 | ||
6 | ifdef CONFIG_DEBUG_FS | 6 | ifdef CONFIG_DEBUG_FS |
7 | hid-objs += hid-debug.o | 7 | hid-objs += hid-debug.o |
8 | endif | 8 | endif |
9 | 9 | ||
10 | obj-$(CONFIG_HID) += hid.o | 10 | obj-$(CONFIG_HID) += hid.o |
11 | 11 | ||
12 | hid-$(CONFIG_HIDRAW) += hidraw.o | 12 | hid-$(CONFIG_HIDRAW) += hidraw.o |
13 | 13 | ||
14 | hid-logitech-objs := hid-lg.o | 14 | hid-logitech-objs := hid-lg.o |
15 | ifdef CONFIG_LOGITECH_FF | 15 | ifdef CONFIG_LOGITECH_FF |
16 | hid-logitech-objs += hid-lgff.o | 16 | hid-logitech-objs += hid-lgff.o |
17 | endif | 17 | endif |
18 | ifdef CONFIG_LOGIRUMBLEPAD2_FF | 18 | ifdef CONFIG_LOGIRUMBLEPAD2_FF |
19 | hid-logitech-objs += hid-lg2ff.o | 19 | hid-logitech-objs += hid-lg2ff.o |
20 | endif | 20 | endif |
21 | ifdef CONFIG_LOGIG940_FF | 21 | ifdef CONFIG_LOGIG940_FF |
22 | hid-logitech-objs += hid-lg3ff.o | 22 | hid-logitech-objs += hid-lg3ff.o |
23 | endif | 23 | endif |
24 | ifdef CONFIG_LOGIWII_FF | ||
25 | hid-logitech-objs += hid-lg4ff.o | ||
26 | endif | ||
24 | 27 | ||
25 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o | 28 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o |
26 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 29 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
27 | obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o | 30 | obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o |
28 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 31 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
29 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 32 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
30 | obj-$(CONFIG_HID_CANDO) += hid-cando.o | 33 | obj-$(CONFIG_HID_CANDO) += hid-cando.o |
31 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 34 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
32 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 35 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
33 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 36 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
34 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o | 37 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o |
35 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o | 38 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o |
36 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o | 39 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o |
37 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 40 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
38 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 41 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
39 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 42 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
40 | obj-$(CONFIG_HID_KYE) += hid-kye.o | 43 | obj-$(CONFIG_HID_KYE) += hid-kye.o |
41 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | 44 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o |
42 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o | 45 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o |
43 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 46 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
44 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 47 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
45 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o | 48 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o |
46 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 49 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
47 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 50 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
48 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o | 51 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o |
49 | obj-$(CONFIG_HID_QUANTA) += hid-quanta.o | 52 | obj-$(CONFIG_HID_QUANTA) += hid-quanta.o |
50 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o | 53 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o |
51 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 54 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
52 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o | 55 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o |
53 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o | 56 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o |
54 | obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o | 57 | obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o |
58 | obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o | ||
55 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 59 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
56 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 60 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
57 | obj-$(CONFIG_HID_SONY) += hid-sony.o | 61 | obj-$(CONFIG_HID_SONY) += hid-sony.o |
58 | obj-$(CONFIG_HID_STANTUM) += hid-stantum.o | 62 | obj-$(CONFIG_HID_STANTUM) += hid-stantum.o |
59 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 63 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
60 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o | 64 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o |
61 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o | 65 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o |
62 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o | 66 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o |
63 | obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o | 67 | obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o |
64 | obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o | 68 | obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o |
65 | obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o | 69 | obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o |
66 | obj-$(CONFIG_HID_WACOM) += hid-wacom.o | 70 | obj-$(CONFIG_HID_WACOM) += hid-wacom.o |
67 | 71 | ||
68 | obj-$(CONFIG_USB_HID) += usbhid/ | 72 | obj-$(CONFIG_USB_HID) += usbhid/ |
69 | obj-$(CONFIG_USB_MOUSE) += usbhid/ | 73 | obj-$(CONFIG_USB_MOUSE) += usbhid/ |
70 | obj-$(CONFIG_USB_KBD) += usbhid/ | 74 | obj-$(CONFIG_USB_KBD) += usbhid/ |
71 | 75 | ||
72 | 76 |
drivers/hid/hid-3m-pct.c
1 | /* | 1 | /* |
2 | * HID driver for 3M PCT multitouch panels | 2 | * HID driver for 3M PCT multitouch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> |
5 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
6 | * Copyright (c) 2010 Canonical, Ltd. | ||
5 | * | 7 | * |
6 | */ | 8 | */ |
7 | 9 | ||
8 | /* | 10 | /* |
9 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the Free | 12 | * under the terms of the GNU General Public License as published by the Free |
11 | * Software Foundation; either version 2 of the License, or (at your option) | 13 | * Software Foundation; either version 2 of the License, or (at your option) |
12 | * any later version. | 14 | * any later version. |
13 | */ | 15 | */ |
14 | 16 | ||
15 | #include <linux/device.h> | 17 | #include <linux/device.h> |
16 | #include <linux/hid.h> | 18 | #include <linux/hid.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
19 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
20 | 22 | ||
21 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | 23 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); |
22 | MODULE_DESCRIPTION("3M PCT multitouch panels"); | 24 | MODULE_DESCRIPTION("3M PCT multitouch panels"); |
23 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
24 | 26 | ||
25 | #include "hid-ids.h" | 27 | #include "hid-ids.h" |
26 | 28 | ||
29 | #define MAX_SLOTS 60 | ||
30 | #define MAX_TRKID USHRT_MAX | ||
31 | #define MAX_EVENTS 360 | ||
32 | |||
33 | /* estimated signal-to-noise ratios */ | ||
34 | #define SN_MOVE 2048 | ||
35 | #define SN_WIDTH 128 | ||
36 | |||
27 | struct mmm_finger { | 37 | struct mmm_finger { |
28 | __s32 x, y, w, h; | 38 | __s32 x, y, w, h; |
29 | __u8 rank; | 39 | __u16 id; |
40 | bool prev_touch; | ||
30 | bool touch, valid; | 41 | bool touch, valid; |
31 | }; | 42 | }; |
32 | 43 | ||
33 | struct mmm_data { | 44 | struct mmm_data { |
34 | struct mmm_finger f[10]; | 45 | struct mmm_finger f[MAX_SLOTS]; |
35 | __u8 curid, num; | 46 | __u16 id; |
47 | __u8 curid; | ||
48 | __u8 nexp, nreal; | ||
36 | bool touch, valid; | 49 | bool touch, valid; |
37 | }; | 50 | }; |
38 | 51 | ||
39 | static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 52 | static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
40 | struct hid_field *field, struct hid_usage *usage, | 53 | struct hid_field *field, struct hid_usage *usage, |
41 | unsigned long **bit, int *max) | 54 | unsigned long **bit, int *max) |
42 | { | 55 | { |
56 | int f1 = field->logical_minimum; | ||
57 | int f2 = field->logical_maximum; | ||
58 | int df = f2 - f1; | ||
59 | |||
43 | switch (usage->hid & HID_USAGE_PAGE) { | 60 | switch (usage->hid & HID_USAGE_PAGE) { |
44 | 61 | ||
45 | case HID_UP_BUTTON: | 62 | case HID_UP_BUTTON: |
46 | return -1; | 63 | return -1; |
47 | 64 | ||
48 | case HID_UP_GENDESK: | 65 | case HID_UP_GENDESK: |
49 | switch (usage->hid) { | 66 | switch (usage->hid) { |
50 | case HID_GD_X: | 67 | case HID_GD_X: |
51 | hid_map_usage(hi, usage, bit, max, | 68 | hid_map_usage(hi, usage, bit, max, |
52 | EV_ABS, ABS_MT_POSITION_X); | 69 | EV_ABS, ABS_MT_POSITION_X); |
70 | input_set_abs_params(hi->input, ABS_MT_POSITION_X, | ||
71 | f1, f2, df / SN_MOVE, 0); | ||
53 | /* touchscreen emulation */ | 72 | /* touchscreen emulation */ |
54 | input_set_abs_params(hi->input, ABS_X, | 73 | input_set_abs_params(hi->input, ABS_X, |
55 | field->logical_minimum, | 74 | f1, f2, df / SN_MOVE, 0); |
56 | field->logical_maximum, 0, 0); | ||
57 | return 1; | 75 | return 1; |
58 | case HID_GD_Y: | 76 | case HID_GD_Y: |
59 | hid_map_usage(hi, usage, bit, max, | 77 | hid_map_usage(hi, usage, bit, max, |
60 | EV_ABS, ABS_MT_POSITION_Y); | 78 | EV_ABS, ABS_MT_POSITION_Y); |
79 | input_set_abs_params(hi->input, ABS_MT_POSITION_Y, | ||
80 | f1, f2, df / SN_MOVE, 0); | ||
61 | /* touchscreen emulation */ | 81 | /* touchscreen emulation */ |
62 | input_set_abs_params(hi->input, ABS_Y, | 82 | input_set_abs_params(hi->input, ABS_Y, |
63 | field->logical_minimum, | 83 | f1, f2, df / SN_MOVE, 0); |
64 | field->logical_maximum, 0, 0); | ||
65 | return 1; | 84 | return 1; |
66 | } | 85 | } |
67 | return 0; | 86 | return 0; |
68 | 87 | ||
69 | case HID_UP_DIGITIZER: | 88 | case HID_UP_DIGITIZER: |
70 | switch (usage->hid) { | 89 | switch (usage->hid) { |
71 | /* we do not want to map these: no input-oriented meaning */ | 90 | /* we do not want to map these: no input-oriented meaning */ |
72 | case 0x14: | 91 | case 0x14: |
73 | case 0x23: | 92 | case 0x23: |
74 | case HID_DG_INPUTMODE: | 93 | case HID_DG_INPUTMODE: |
75 | case HID_DG_DEVICEINDEX: | 94 | case HID_DG_DEVICEINDEX: |
76 | case HID_DG_CONTACTCOUNT: | 95 | case HID_DG_CONTACTCOUNT: |
77 | case HID_DG_CONTACTMAX: | 96 | case HID_DG_CONTACTMAX: |
78 | case HID_DG_INRANGE: | 97 | case HID_DG_INRANGE: |
79 | case HID_DG_CONFIDENCE: | 98 | case HID_DG_CONFIDENCE: |
80 | return -1; | 99 | return -1; |
81 | case HID_DG_TIPSWITCH: | 100 | case HID_DG_TIPSWITCH: |
82 | /* touchscreen emulation */ | 101 | /* touchscreen emulation */ |
83 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 102 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
103 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | ||
84 | return 1; | 104 | return 1; |
85 | case HID_DG_WIDTH: | 105 | case HID_DG_WIDTH: |
86 | hid_map_usage(hi, usage, bit, max, | 106 | hid_map_usage(hi, usage, bit, max, |
87 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 107 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
108 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, | ||
109 | f1, f2, df / SN_WIDTH, 0); | ||
88 | return 1; | 110 | return 1; |
89 | case HID_DG_HEIGHT: | 111 | case HID_DG_HEIGHT: |
90 | hid_map_usage(hi, usage, bit, max, | 112 | hid_map_usage(hi, usage, bit, max, |
91 | EV_ABS, ABS_MT_TOUCH_MINOR); | 113 | EV_ABS, ABS_MT_TOUCH_MINOR); |
114 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, | ||
115 | f1, f2, df / SN_WIDTH, 0); | ||
92 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | 116 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, |
93 | 1, 1, 0, 0); | 117 | 0, 1, 0, 0); |
94 | return 1; | 118 | return 1; |
95 | case HID_DG_CONTACTID: | 119 | case HID_DG_CONTACTID: |
96 | field->logical_maximum = 59; | 120 | field->logical_maximum = MAX_TRKID; |
97 | hid_map_usage(hi, usage, bit, max, | 121 | hid_map_usage(hi, usage, bit, max, |
98 | EV_ABS, ABS_MT_TRACKING_ID); | 122 | EV_ABS, ABS_MT_TRACKING_ID); |
123 | input_set_abs_params(hi->input, ABS_MT_TRACKING_ID, | ||
124 | 0, MAX_TRKID, 0, 0); | ||
125 | if (!hi->input->mt) | ||
126 | input_mt_create_slots(hi->input, MAX_SLOTS); | ||
127 | input_set_events_per_packet(hi->input, MAX_EVENTS); | ||
99 | return 1; | 128 | return 1; |
100 | } | 129 | } |
101 | /* let hid-input decide for the others */ | 130 | /* let hid-input decide for the others */ |
102 | return 0; | 131 | return 0; |
103 | 132 | ||
104 | case 0xff000000: | 133 | case 0xff000000: |
105 | /* we do not want to map these: no input-oriented meaning */ | 134 | /* we do not want to map these: no input-oriented meaning */ |
106 | return -1; | 135 | return -1; |
107 | } | 136 | } |
108 | 137 | ||
109 | return 0; | 138 | return 0; |
110 | } | 139 | } |
111 | 140 | ||
112 | static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 141 | static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
113 | struct hid_field *field, struct hid_usage *usage, | 142 | struct hid_field *field, struct hid_usage *usage, |
114 | unsigned long **bit, int *max) | 143 | unsigned long **bit, int *max) |
115 | { | 144 | { |
145 | /* tell hid-input to skip setup of these event types */ | ||
116 | if (usage->type == EV_KEY || usage->type == EV_ABS) | 146 | if (usage->type == EV_KEY || usage->type == EV_ABS) |
117 | clear_bit(usage->code, *bit); | 147 | set_bit(usage->type, hi->input->evbit); |
118 | 148 | return -1; | |
119 | return 0; | ||
120 | } | 149 | } |
121 | 150 | ||
122 | /* | 151 | /* |
123 | * this function is called when a whole packet has been received and processed, | 152 | * this function is called when a whole packet has been received and processed, |
124 | * so that it can decide what to send to the input layer. | 153 | * so that it can decide what to send to the input layer. |
125 | */ | 154 | */ |
126 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | 155 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) |
127 | { | 156 | { |
128 | struct mmm_finger *oldest = 0; | 157 | struct mmm_finger *oldest = 0; |
129 | bool pressed = false, released = false; | ||
130 | int i; | 158 | int i; |
131 | 159 | for (i = 0; i < MAX_SLOTS; ++i) { | |
132 | /* | ||
133 | * we need to iterate on all fingers to decide if we have a press | ||
134 | * or a release event in our touchscreen emulation. | ||
135 | */ | ||
136 | for (i = 0; i < 10; ++i) { | ||
137 | struct mmm_finger *f = &md->f[i]; | 160 | struct mmm_finger *f = &md->f[i]; |
138 | if (!f->valid) { | 161 | if (!f->valid) { |
139 | /* this finger is just placeholder data, ignore */ | 162 | /* this finger is just placeholder data, ignore */ |
140 | } else if (f->touch) { | 163 | continue; |
164 | } | ||
165 | input_mt_slot(input, i); | ||
166 | if (f->touch) { | ||
141 | /* this finger is on the screen */ | 167 | /* this finger is on the screen */ |
142 | int wide = (f->w > f->h); | 168 | int wide = (f->w > f->h); |
143 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i); | 169 | /* divided by two to match visual scale of touch */ |
170 | int major = max(f->w, f->h) >> 1; | ||
171 | int minor = min(f->w, f->h) >> 1; | ||
172 | |||
173 | if (!f->prev_touch) | ||
174 | f->id = md->id++; | ||
175 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id); | ||
144 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); | 176 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); |
145 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); | 177 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); |
146 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | 178 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); |
147 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, | 179 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
148 | wide ? f->w : f->h); | 180 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
149 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, | 181 | /* touchscreen emulation: pick the oldest contact */ |
150 | wide ? f->h : f->w); | 182 | if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1))) |
151 | input_mt_sync(input); | ||
152 | /* | ||
153 | * touchscreen emulation: maintain the age rank | ||
154 | * of this finger, decide if we have a press | ||
155 | */ | ||
156 | if (f->rank == 0) { | ||
157 | f->rank = ++(md->num); | ||
158 | if (f->rank == 1) | ||
159 | pressed = true; | ||
160 | } | ||
161 | if (f->rank == 1) | ||
162 | oldest = f; | 183 | oldest = f; |
163 | } else { | 184 | } else { |
164 | /* this finger took off the screen */ | 185 | /* this finger took off the screen */ |
165 | /* touchscreen emulation: maintain age rank of others */ | 186 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1); |
166 | int j; | ||
167 | |||
168 | for (j = 0; j < 10; ++j) { | ||
169 | struct mmm_finger *g = &md->f[j]; | ||
170 | if (g->rank > f->rank) { | ||
171 | g->rank--; | ||
172 | if (g->rank == 1) | ||
173 | oldest = g; | ||
174 | } | ||
175 | } | ||
176 | f->rank = 0; | ||
177 | --(md->num); | ||
178 | if (md->num == 0) | ||
179 | released = true; | ||
180 | } | 187 | } |
188 | f->prev_touch = f->touch; | ||
181 | f->valid = 0; | 189 | f->valid = 0; |
182 | } | 190 | } |
183 | 191 | ||
184 | /* touchscreen emulation */ | 192 | /* touchscreen emulation */ |
185 | if (oldest) { | 193 | if (oldest) { |
186 | if (pressed) | 194 | input_event(input, EV_KEY, BTN_TOUCH, 1); |
187 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
188 | input_event(input, EV_ABS, ABS_X, oldest->x); | 195 | input_event(input, EV_ABS, ABS_X, oldest->x); |
189 | input_event(input, EV_ABS, ABS_Y, oldest->y); | 196 | input_event(input, EV_ABS, ABS_Y, oldest->y); |
190 | } else if (released) { | 197 | } else { |
191 | input_event(input, EV_KEY, BTN_TOUCH, 0); | 198 | input_event(input, EV_KEY, BTN_TOUCH, 0); |
192 | } | 199 | } |
200 | input_sync(input); | ||
193 | } | 201 | } |
194 | 202 | ||
195 | /* | 203 | /* |
196 | * this function is called upon all reports | 204 | * this function is called upon all reports |
197 | * so that we can accumulate contact point information, | 205 | * so that we can accumulate contact point information, |
198 | * and call input_mt_sync after each point. | 206 | * and call input_mt_sync after each point. |
199 | */ | 207 | */ |
200 | static int mmm_event(struct hid_device *hid, struct hid_field *field, | 208 | static int mmm_event(struct hid_device *hid, struct hid_field *field, |
201 | struct hid_usage *usage, __s32 value) | 209 | struct hid_usage *usage, __s32 value) |
202 | { | 210 | { |
203 | struct mmm_data *md = hid_get_drvdata(hid); | 211 | struct mmm_data *md = hid_get_drvdata(hid); |
204 | /* | 212 | /* |
205 | * strangely, this function can be called before | 213 | * strangely, this function can be called before |
206 | * field->hidinput is initialized! | 214 | * field->hidinput is initialized! |
207 | */ | 215 | */ |
208 | if (hid->claimed & HID_CLAIMED_INPUT) { | 216 | if (hid->claimed & HID_CLAIMED_INPUT) { |
209 | struct input_dev *input = field->hidinput->input; | 217 | struct input_dev *input = field->hidinput->input; |
210 | switch (usage->hid) { | 218 | switch (usage->hid) { |
211 | case HID_DG_TIPSWITCH: | 219 | case HID_DG_TIPSWITCH: |
212 | md->touch = value; | 220 | md->touch = value; |
213 | break; | 221 | break; |
214 | case HID_DG_CONFIDENCE: | 222 | case HID_DG_CONFIDENCE: |
215 | md->valid = value; | 223 | md->valid = value; |
216 | break; | 224 | break; |
217 | case HID_DG_WIDTH: | 225 | case HID_DG_WIDTH: |
218 | if (md->valid) | 226 | if (md->valid) |
219 | md->f[md->curid].w = value; | 227 | md->f[md->curid].w = value; |
220 | break; | 228 | break; |
221 | case HID_DG_HEIGHT: | 229 | case HID_DG_HEIGHT: |
222 | if (md->valid) | 230 | if (md->valid) |
223 | md->f[md->curid].h = value; | 231 | md->f[md->curid].h = value; |
224 | break; | 232 | break; |
225 | case HID_DG_CONTACTID: | 233 | case HID_DG_CONTACTID: |
234 | value = clamp_val(value, 0, MAX_SLOTS - 1); | ||
226 | if (md->valid) { | 235 | if (md->valid) { |
227 | md->curid = value; | 236 | md->curid = value; |
228 | md->f[value].touch = md->touch; | 237 | md->f[value].touch = md->touch; |
229 | md->f[value].valid = 1; | 238 | md->f[value].valid = 1; |
239 | md->nreal++; | ||
230 | } | 240 | } |
231 | break; | 241 | break; |
232 | case HID_GD_X: | 242 | case HID_GD_X: |
233 | if (md->valid) | 243 | if (md->valid) |
234 | md->f[md->curid].x = value; | 244 | md->f[md->curid].x = value; |
235 | break; | 245 | break; |
236 | case HID_GD_Y: | 246 | case HID_GD_Y: |
237 | if (md->valid) | 247 | if (md->valid) |
238 | md->f[md->curid].y = value; | 248 | md->f[md->curid].y = value; |
239 | break; | 249 | break; |
240 | case HID_DG_CONTACTCOUNT: | 250 | case HID_DG_CONTACTCOUNT: |
241 | mmm_filter_event(md, input); | 251 | if (value) |
252 | md->nexp = value; | ||
253 | if (md->nreal >= md->nexp) { | ||
254 | mmm_filter_event(md, input); | ||
255 | md->nreal = 0; | ||
256 | } | ||
242 | break; | 257 | break; |
243 | } | 258 | } |
244 | } | 259 | } |
245 | 260 | ||
246 | /* we have handled the hidinput part, now remains hiddev */ | 261 | /* we have handled the hidinput part, now remains hiddev */ |
247 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | 262 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) |
248 | hid->hiddev_hid_event(hid, field, usage, value); | 263 | hid->hiddev_hid_event(hid, field, usage, value); |
249 | 264 | ||
250 | return 1; | 265 | return 1; |
251 | } | 266 | } |
252 | 267 | ||
253 | static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) | 268 | static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) |
254 | { | 269 | { |
255 | int ret; | 270 | int ret; |
256 | struct mmm_data *md; | 271 | struct mmm_data *md; |
272 | |||
273 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | ||
257 | 274 | ||
258 | md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); | 275 | md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); |
259 | if (!md) { | 276 | if (!md) { |
260 | dev_err(&hdev->dev, "cannot allocate 3M data\n"); | 277 | dev_err(&hdev->dev, "cannot allocate 3M data\n"); |
261 | return -ENOMEM; | 278 | return -ENOMEM; |
262 | } | 279 | } |
263 | hid_set_drvdata(hdev, md); | 280 | hid_set_drvdata(hdev, md); |
264 | 281 | ||
265 | ret = hid_parse(hdev); | 282 | ret = hid_parse(hdev); |
266 | if (!ret) | 283 | if (!ret) |
267 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 284 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
268 | 285 | ||
269 | if (ret) | 286 | if (ret) |
270 | kfree(md); | 287 | kfree(md); |
271 | return ret; | 288 | return ret; |
272 | } | 289 | } |
273 | 290 | ||
274 | static void mmm_remove(struct hid_device *hdev) | 291 | static void mmm_remove(struct hid_device *hdev) |
275 | { | 292 | { |
276 | hid_hw_stop(hdev); | 293 | hid_hw_stop(hdev); |
277 | kfree(hid_get_drvdata(hdev)); | 294 | kfree(hid_get_drvdata(hdev)); |
278 | hid_set_drvdata(hdev, NULL); | 295 | hid_set_drvdata(hdev, NULL); |
279 | } | 296 | } |
280 | 297 | ||
281 | static const struct hid_device_id mmm_devices[] = { | 298 | static const struct hid_device_id mmm_devices[] = { |
282 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, | 299 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, |
drivers/hid/hid-core.c
1 | /* | 1 | /* |
2 | * HID support for Linux | 2 | * HID support for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006-2010 Jiri Kosina | 7 | * Copyright (c) 2006-2010 Jiri Kosina |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the Free | 12 | * under the terms of the GNU General Public License as published by the Free |
13 | * Software Foundation; either version 2 of the License, or (at your option) | 13 | * Software Foundation; either version 2 of the License, or (at your option) |
14 | * any later version. | 14 | * any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <asm/unaligned.h> | 24 | #include <asm/unaligned.h> |
25 | #include <asm/byteorder.h> | 25 | #include <asm/byteorder.h> |
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | 30 | ||
31 | #include <linux/hid.h> | 31 | #include <linux/hid.h> |
32 | #include <linux/hiddev.h> | 32 | #include <linux/hiddev.h> |
33 | #include <linux/hid-debug.h> | 33 | #include <linux/hid-debug.h> |
34 | #include <linux/hidraw.h> | 34 | #include <linux/hidraw.h> |
35 | 35 | ||
36 | #include "hid-ids.h" | 36 | #include "hid-ids.h" |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Version Information | 39 | * Version Information |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #define DRIVER_DESC "HID core driver" | 42 | #define DRIVER_DESC "HID core driver" |
43 | #define DRIVER_LICENSE "GPL" | 43 | #define DRIVER_LICENSE "GPL" |
44 | 44 | ||
45 | int hid_debug = 0; | 45 | int hid_debug = 0; |
46 | module_param_named(debug, hid_debug, int, 0600); | 46 | module_param_named(debug, hid_debug, int, 0600); |
47 | MODULE_PARM_DESC(debug, "toggle HID debugging messages"); | 47 | MODULE_PARM_DESC(debug, "toggle HID debugging messages"); |
48 | EXPORT_SYMBOL_GPL(hid_debug); | 48 | EXPORT_SYMBOL_GPL(hid_debug); |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Register a new report for a device. | 51 | * Register a new report for a device. |
52 | */ | 52 | */ |
53 | 53 | ||
54 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) | 54 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) |
55 | { | 55 | { |
56 | struct hid_report_enum *report_enum = device->report_enum + type; | 56 | struct hid_report_enum *report_enum = device->report_enum + type; |
57 | struct hid_report *report; | 57 | struct hid_report *report; |
58 | 58 | ||
59 | if (report_enum->report_id_hash[id]) | 59 | if (report_enum->report_id_hash[id]) |
60 | return report_enum->report_id_hash[id]; | 60 | return report_enum->report_id_hash[id]; |
61 | 61 | ||
62 | if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) | 62 | if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) |
63 | return NULL; | 63 | return NULL; |
64 | 64 | ||
65 | if (id != 0) | 65 | if (id != 0) |
66 | report_enum->numbered = 1; | 66 | report_enum->numbered = 1; |
67 | 67 | ||
68 | report->id = id; | 68 | report->id = id; |
69 | report->type = type; | 69 | report->type = type; |
70 | report->size = 0; | 70 | report->size = 0; |
71 | report->device = device; | 71 | report->device = device; |
72 | report_enum->report_id_hash[id] = report; | 72 | report_enum->report_id_hash[id] = report; |
73 | 73 | ||
74 | list_add_tail(&report->list, &report_enum->report_list); | 74 | list_add_tail(&report->list, &report_enum->report_list); |
75 | 75 | ||
76 | return report; | 76 | return report; |
77 | } | 77 | } |
78 | EXPORT_SYMBOL_GPL(hid_register_report); | 78 | EXPORT_SYMBOL_GPL(hid_register_report); |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * Register a new field for this report. | 81 | * Register a new field for this report. |
82 | */ | 82 | */ |
83 | 83 | ||
84 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) | 84 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) |
85 | { | 85 | { |
86 | struct hid_field *field; | 86 | struct hid_field *field; |
87 | 87 | ||
88 | if (report->maxfield == HID_MAX_FIELDS) { | 88 | if (report->maxfield == HID_MAX_FIELDS) { |
89 | dbg_hid("too many fields in report\n"); | 89 | dbg_hid("too many fields in report\n"); |
90 | return NULL; | 90 | return NULL; |
91 | } | 91 | } |
92 | 92 | ||
93 | if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) | 93 | if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) |
94 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; | 94 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; |
95 | 95 | ||
96 | field->index = report->maxfield++; | 96 | field->index = report->maxfield++; |
97 | report->field[field->index] = field; | 97 | report->field[field->index] = field; |
98 | field->usage = (struct hid_usage *)(field + 1); | 98 | field->usage = (struct hid_usage *)(field + 1); |
99 | field->value = (s32 *)(field->usage + usages); | 99 | field->value = (s32 *)(field->usage + usages); |
100 | field->report = report; | 100 | field->report = report; |
101 | 101 | ||
102 | return field; | 102 | return field; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * Open a collection. The type/usage is pushed on the stack. | 106 | * Open a collection. The type/usage is pushed on the stack. |
107 | */ | 107 | */ |
108 | 108 | ||
109 | static int open_collection(struct hid_parser *parser, unsigned type) | 109 | static int open_collection(struct hid_parser *parser, unsigned type) |
110 | { | 110 | { |
111 | struct hid_collection *collection; | 111 | struct hid_collection *collection; |
112 | unsigned usage; | 112 | unsigned usage; |
113 | 113 | ||
114 | usage = parser->local.usage[0]; | 114 | usage = parser->local.usage[0]; |
115 | 115 | ||
116 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { | 116 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { |
117 | dbg_hid("collection stack overflow\n"); | 117 | dbg_hid("collection stack overflow\n"); |
118 | return -1; | 118 | return -1; |
119 | } | 119 | } |
120 | 120 | ||
121 | if (parser->device->maxcollection == parser->device->collection_size) { | 121 | if (parser->device->maxcollection == parser->device->collection_size) { |
122 | collection = kmalloc(sizeof(struct hid_collection) * | 122 | collection = kmalloc(sizeof(struct hid_collection) * |
123 | parser->device->collection_size * 2, GFP_KERNEL); | 123 | parser->device->collection_size * 2, GFP_KERNEL); |
124 | if (collection == NULL) { | 124 | if (collection == NULL) { |
125 | dbg_hid("failed to reallocate collection array\n"); | 125 | dbg_hid("failed to reallocate collection array\n"); |
126 | return -1; | 126 | return -1; |
127 | } | 127 | } |
128 | memcpy(collection, parser->device->collection, | 128 | memcpy(collection, parser->device->collection, |
129 | sizeof(struct hid_collection) * | 129 | sizeof(struct hid_collection) * |
130 | parser->device->collection_size); | 130 | parser->device->collection_size); |
131 | memset(collection + parser->device->collection_size, 0, | 131 | memset(collection + parser->device->collection_size, 0, |
132 | sizeof(struct hid_collection) * | 132 | sizeof(struct hid_collection) * |
133 | parser->device->collection_size); | 133 | parser->device->collection_size); |
134 | kfree(parser->device->collection); | 134 | kfree(parser->device->collection); |
135 | parser->device->collection = collection; | 135 | parser->device->collection = collection; |
136 | parser->device->collection_size *= 2; | 136 | parser->device->collection_size *= 2; |
137 | } | 137 | } |
138 | 138 | ||
139 | parser->collection_stack[parser->collection_stack_ptr++] = | 139 | parser->collection_stack[parser->collection_stack_ptr++] = |
140 | parser->device->maxcollection; | 140 | parser->device->maxcollection; |
141 | 141 | ||
142 | collection = parser->device->collection + | 142 | collection = parser->device->collection + |
143 | parser->device->maxcollection++; | 143 | parser->device->maxcollection++; |
144 | collection->type = type; | 144 | collection->type = type; |
145 | collection->usage = usage; | 145 | collection->usage = usage; |
146 | collection->level = parser->collection_stack_ptr - 1; | 146 | collection->level = parser->collection_stack_ptr - 1; |
147 | 147 | ||
148 | if (type == HID_COLLECTION_APPLICATION) | 148 | if (type == HID_COLLECTION_APPLICATION) |
149 | parser->device->maxapplication++; | 149 | parser->device->maxapplication++; |
150 | 150 | ||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * Close a collection. | 155 | * Close a collection. |
156 | */ | 156 | */ |
157 | 157 | ||
158 | static int close_collection(struct hid_parser *parser) | 158 | static int close_collection(struct hid_parser *parser) |
159 | { | 159 | { |
160 | if (!parser->collection_stack_ptr) { | 160 | if (!parser->collection_stack_ptr) { |
161 | dbg_hid("collection stack underflow\n"); | 161 | dbg_hid("collection stack underflow\n"); |
162 | return -1; | 162 | return -1; |
163 | } | 163 | } |
164 | parser->collection_stack_ptr--; | 164 | parser->collection_stack_ptr--; |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * Climb up the stack, search for the specified collection type | 169 | * Climb up the stack, search for the specified collection type |
170 | * and return the usage. | 170 | * and return the usage. |
171 | */ | 171 | */ |
172 | 172 | ||
173 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) | 173 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) |
174 | { | 174 | { |
175 | int n; | 175 | int n; |
176 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) | 176 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) |
177 | if (parser->device->collection[parser->collection_stack[n]].type == type) | 177 | if (parser->device->collection[parser->collection_stack[n]].type == type) |
178 | return parser->device->collection[parser->collection_stack[n]].usage; | 178 | return parser->device->collection[parser->collection_stack[n]].usage; |
179 | return 0; /* we know nothing about this usage type */ | 179 | return 0; /* we know nothing about this usage type */ |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | 182 | /* |
183 | * Add a usage to the temporary parser table. | 183 | * Add a usage to the temporary parser table. |
184 | */ | 184 | */ |
185 | 185 | ||
186 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) | 186 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) |
187 | { | 187 | { |
188 | if (parser->local.usage_index >= HID_MAX_USAGES) { | 188 | if (parser->local.usage_index >= HID_MAX_USAGES) { |
189 | dbg_hid("usage index exceeded\n"); | 189 | dbg_hid("usage index exceeded\n"); |
190 | return -1; | 190 | return -1; |
191 | } | 191 | } |
192 | parser->local.usage[parser->local.usage_index] = usage; | 192 | parser->local.usage[parser->local.usage_index] = usage; |
193 | parser->local.collection_index[parser->local.usage_index] = | 193 | parser->local.collection_index[parser->local.usage_index] = |
194 | parser->collection_stack_ptr ? | 194 | parser->collection_stack_ptr ? |
195 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; | 195 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; |
196 | parser->local.usage_index++; | 196 | parser->local.usage_index++; |
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | /* | 200 | /* |
201 | * Register a new field for this report. | 201 | * Register a new field for this report. |
202 | */ | 202 | */ |
203 | 203 | ||
204 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) | 204 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) |
205 | { | 205 | { |
206 | struct hid_report *report; | 206 | struct hid_report *report; |
207 | struct hid_field *field; | 207 | struct hid_field *field; |
208 | int usages; | 208 | int usages; |
209 | unsigned offset; | 209 | unsigned offset; |
210 | int i; | 210 | int i; |
211 | 211 | ||
212 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { | 212 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { |
213 | dbg_hid("hid_register_report failed\n"); | 213 | dbg_hid("hid_register_report failed\n"); |
214 | return -1; | 214 | return -1; |
215 | } | 215 | } |
216 | 216 | ||
217 | if (parser->global.logical_maximum < parser->global.logical_minimum) { | 217 | if (parser->global.logical_maximum < parser->global.logical_minimum) { |
218 | dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum); | 218 | dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum); |
219 | return -1; | 219 | return -1; |
220 | } | 220 | } |
221 | 221 | ||
222 | offset = report->size; | 222 | offset = report->size; |
223 | report->size += parser->global.report_size * parser->global.report_count; | 223 | report->size += parser->global.report_size * parser->global.report_count; |
224 | 224 | ||
225 | if (!parser->local.usage_index) /* Ignore padding fields */ | 225 | if (!parser->local.usage_index) /* Ignore padding fields */ |
226 | return 0; | 226 | return 0; |
227 | 227 | ||
228 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); | 228 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); |
229 | 229 | ||
230 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) | 230 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) |
231 | return 0; | 231 | return 0; |
232 | 232 | ||
233 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); | 233 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); |
234 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); | 234 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); |
235 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); | 235 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); |
236 | 236 | ||
237 | for (i = 0; i < usages; i++) { | 237 | for (i = 0; i < usages; i++) { |
238 | int j = i; | 238 | int j = i; |
239 | /* Duplicate the last usage we parsed if we have excess values */ | 239 | /* Duplicate the last usage we parsed if we have excess values */ |
240 | if (i >= parser->local.usage_index) | 240 | if (i >= parser->local.usage_index) |
241 | j = parser->local.usage_index - 1; | 241 | j = parser->local.usage_index - 1; |
242 | field->usage[i].hid = parser->local.usage[j]; | 242 | field->usage[i].hid = parser->local.usage[j]; |
243 | field->usage[i].collection_index = | 243 | field->usage[i].collection_index = |
244 | parser->local.collection_index[j]; | 244 | parser->local.collection_index[j]; |
245 | } | 245 | } |
246 | 246 | ||
247 | field->maxusage = usages; | 247 | field->maxusage = usages; |
248 | field->flags = flags; | 248 | field->flags = flags; |
249 | field->report_offset = offset; | 249 | field->report_offset = offset; |
250 | field->report_type = report_type; | 250 | field->report_type = report_type; |
251 | field->report_size = parser->global.report_size; | 251 | field->report_size = parser->global.report_size; |
252 | field->report_count = parser->global.report_count; | 252 | field->report_count = parser->global.report_count; |
253 | field->logical_minimum = parser->global.logical_minimum; | 253 | field->logical_minimum = parser->global.logical_minimum; |
254 | field->logical_maximum = parser->global.logical_maximum; | 254 | field->logical_maximum = parser->global.logical_maximum; |
255 | field->physical_minimum = parser->global.physical_minimum; | 255 | field->physical_minimum = parser->global.physical_minimum; |
256 | field->physical_maximum = parser->global.physical_maximum; | 256 | field->physical_maximum = parser->global.physical_maximum; |
257 | field->unit_exponent = parser->global.unit_exponent; | 257 | field->unit_exponent = parser->global.unit_exponent; |
258 | field->unit = parser->global.unit; | 258 | field->unit = parser->global.unit; |
259 | 259 | ||
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * Read data value from item. | 264 | * Read data value from item. |
265 | */ | 265 | */ |
266 | 266 | ||
267 | static u32 item_udata(struct hid_item *item) | 267 | static u32 item_udata(struct hid_item *item) |
268 | { | 268 | { |
269 | switch (item->size) { | 269 | switch (item->size) { |
270 | case 1: return item->data.u8; | 270 | case 1: return item->data.u8; |
271 | case 2: return item->data.u16; | 271 | case 2: return item->data.u16; |
272 | case 4: return item->data.u32; | 272 | case 4: return item->data.u32; |
273 | } | 273 | } |
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
277 | static s32 item_sdata(struct hid_item *item) | 277 | static s32 item_sdata(struct hid_item *item) |
278 | { | 278 | { |
279 | switch (item->size) { | 279 | switch (item->size) { |
280 | case 1: return item->data.s8; | 280 | case 1: return item->data.s8; |
281 | case 2: return item->data.s16; | 281 | case 2: return item->data.s16; |
282 | case 4: return item->data.s32; | 282 | case 4: return item->data.s32; |
283 | } | 283 | } |
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * Process a global item. | 288 | * Process a global item. |
289 | */ | 289 | */ |
290 | 290 | ||
291 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) | 291 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) |
292 | { | 292 | { |
293 | switch (item->tag) { | 293 | switch (item->tag) { |
294 | case HID_GLOBAL_ITEM_TAG_PUSH: | 294 | case HID_GLOBAL_ITEM_TAG_PUSH: |
295 | 295 | ||
296 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { | 296 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { |
297 | dbg_hid("global enviroment stack overflow\n"); | 297 | dbg_hid("global enviroment stack overflow\n"); |
298 | return -1; | 298 | return -1; |
299 | } | 299 | } |
300 | 300 | ||
301 | memcpy(parser->global_stack + parser->global_stack_ptr++, | 301 | memcpy(parser->global_stack + parser->global_stack_ptr++, |
302 | &parser->global, sizeof(struct hid_global)); | 302 | &parser->global, sizeof(struct hid_global)); |
303 | return 0; | 303 | return 0; |
304 | 304 | ||
305 | case HID_GLOBAL_ITEM_TAG_POP: | 305 | case HID_GLOBAL_ITEM_TAG_POP: |
306 | 306 | ||
307 | if (!parser->global_stack_ptr) { | 307 | if (!parser->global_stack_ptr) { |
308 | dbg_hid("global enviroment stack underflow\n"); | 308 | dbg_hid("global enviroment stack underflow\n"); |
309 | return -1; | 309 | return -1; |
310 | } | 310 | } |
311 | 311 | ||
312 | memcpy(&parser->global, parser->global_stack + | 312 | memcpy(&parser->global, parser->global_stack + |
313 | --parser->global_stack_ptr, sizeof(struct hid_global)); | 313 | --parser->global_stack_ptr, sizeof(struct hid_global)); |
314 | return 0; | 314 | return 0; |
315 | 315 | ||
316 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: | 316 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: |
317 | parser->global.usage_page = item_udata(item); | 317 | parser->global.usage_page = item_udata(item); |
318 | return 0; | 318 | return 0; |
319 | 319 | ||
320 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: | 320 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: |
321 | parser->global.logical_minimum = item_sdata(item); | 321 | parser->global.logical_minimum = item_sdata(item); |
322 | return 0; | 322 | return 0; |
323 | 323 | ||
324 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: | 324 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: |
325 | if (parser->global.logical_minimum < 0) | 325 | if (parser->global.logical_minimum < 0) |
326 | parser->global.logical_maximum = item_sdata(item); | 326 | parser->global.logical_maximum = item_sdata(item); |
327 | else | 327 | else |
328 | parser->global.logical_maximum = item_udata(item); | 328 | parser->global.logical_maximum = item_udata(item); |
329 | return 0; | 329 | return 0; |
330 | 330 | ||
331 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: | 331 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: |
332 | parser->global.physical_minimum = item_sdata(item); | 332 | parser->global.physical_minimum = item_sdata(item); |
333 | return 0; | 333 | return 0; |
334 | 334 | ||
335 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: | 335 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: |
336 | if (parser->global.physical_minimum < 0) | 336 | if (parser->global.physical_minimum < 0) |
337 | parser->global.physical_maximum = item_sdata(item); | 337 | parser->global.physical_maximum = item_sdata(item); |
338 | else | 338 | else |
339 | parser->global.physical_maximum = item_udata(item); | 339 | parser->global.physical_maximum = item_udata(item); |
340 | return 0; | 340 | return 0; |
341 | 341 | ||
342 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: | 342 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: |
343 | parser->global.unit_exponent = item_sdata(item); | 343 | parser->global.unit_exponent = item_sdata(item); |
344 | return 0; | 344 | return 0; |
345 | 345 | ||
346 | case HID_GLOBAL_ITEM_TAG_UNIT: | 346 | case HID_GLOBAL_ITEM_TAG_UNIT: |
347 | parser->global.unit = item_udata(item); | 347 | parser->global.unit = item_udata(item); |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: | 350 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: |
351 | parser->global.report_size = item_udata(item); | 351 | parser->global.report_size = item_udata(item); |
352 | if (parser->global.report_size > 32) { | 352 | if (parser->global.report_size > 32) { |
353 | dbg_hid("invalid report_size %d\n", | 353 | dbg_hid("invalid report_size %d\n", |
354 | parser->global.report_size); | 354 | parser->global.report_size); |
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | return 0; | 357 | return 0; |
358 | 358 | ||
359 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: | 359 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: |
360 | parser->global.report_count = item_udata(item); | 360 | parser->global.report_count = item_udata(item); |
361 | if (parser->global.report_count > HID_MAX_USAGES) { | 361 | if (parser->global.report_count > HID_MAX_USAGES) { |
362 | dbg_hid("invalid report_count %d\n", | 362 | dbg_hid("invalid report_count %d\n", |
363 | parser->global.report_count); | 363 | parser->global.report_count); |
364 | return -1; | 364 | return -1; |
365 | } | 365 | } |
366 | return 0; | 366 | return 0; |
367 | 367 | ||
368 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: | 368 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: |
369 | parser->global.report_id = item_udata(item); | 369 | parser->global.report_id = item_udata(item); |
370 | if (parser->global.report_id == 0) { | 370 | if (parser->global.report_id == 0) { |
371 | dbg_hid("report_id 0 is invalid\n"); | 371 | dbg_hid("report_id 0 is invalid\n"); |
372 | return -1; | 372 | return -1; |
373 | } | 373 | } |
374 | return 0; | 374 | return 0; |
375 | 375 | ||
376 | default: | 376 | default: |
377 | dbg_hid("unknown global tag 0x%x\n", item->tag); | 377 | dbg_hid("unknown global tag 0x%x\n", item->tag); |
378 | return -1; | 378 | return -1; |
379 | } | 379 | } |
380 | } | 380 | } |
381 | 381 | ||
382 | /* | 382 | /* |
383 | * Process a local item. | 383 | * Process a local item. |
384 | */ | 384 | */ |
385 | 385 | ||
386 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) | 386 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) |
387 | { | 387 | { |
388 | __u32 data; | 388 | __u32 data; |
389 | unsigned n; | 389 | unsigned n; |
390 | 390 | ||
391 | /* Local delimiter could have value 0, which allows size to be 0 */ | 391 | /* Local delimiter could have value 0, which allows size to be 0 */ |
392 | if (item->size == 0 && item->tag != HID_LOCAL_ITEM_TAG_DELIMITER) { | 392 | if (item->size == 0 && item->tag != HID_LOCAL_ITEM_TAG_DELIMITER) { |
393 | dbg_hid("item data expected for local item\n"); | 393 | dbg_hid("item data expected for local item\n"); |
394 | return -1; | 394 | return -1; |
395 | } | 395 | } |
396 | 396 | ||
397 | data = item_udata(item); | 397 | data = item_udata(item); |
398 | 398 | ||
399 | switch (item->tag) { | 399 | switch (item->tag) { |
400 | case HID_LOCAL_ITEM_TAG_DELIMITER: | 400 | case HID_LOCAL_ITEM_TAG_DELIMITER: |
401 | 401 | ||
402 | if (data) { | 402 | if (data) { |
403 | /* | 403 | /* |
404 | * We treat items before the first delimiter | 404 | * We treat items before the first delimiter |
405 | * as global to all usage sets (branch 0). | 405 | * as global to all usage sets (branch 0). |
406 | * In the moment we process only these global | 406 | * In the moment we process only these global |
407 | * items and the first delimiter set. | 407 | * items and the first delimiter set. |
408 | */ | 408 | */ |
409 | if (parser->local.delimiter_depth != 0) { | 409 | if (parser->local.delimiter_depth != 0) { |
410 | dbg_hid("nested delimiters\n"); | 410 | dbg_hid("nested delimiters\n"); |
411 | return -1; | 411 | return -1; |
412 | } | 412 | } |
413 | parser->local.delimiter_depth++; | 413 | parser->local.delimiter_depth++; |
414 | parser->local.delimiter_branch++; | 414 | parser->local.delimiter_branch++; |
415 | } else { | 415 | } else { |
416 | if (parser->local.delimiter_depth < 1) { | 416 | if (parser->local.delimiter_depth < 1) { |
417 | dbg_hid("bogus close delimiter\n"); | 417 | dbg_hid("bogus close delimiter\n"); |
418 | return -1; | 418 | return -1; |
419 | } | 419 | } |
420 | parser->local.delimiter_depth--; | 420 | parser->local.delimiter_depth--; |
421 | } | 421 | } |
422 | return 1; | 422 | return 1; |
423 | 423 | ||
424 | case HID_LOCAL_ITEM_TAG_USAGE: | 424 | case HID_LOCAL_ITEM_TAG_USAGE: |
425 | 425 | ||
426 | if (parser->local.delimiter_branch > 1) { | 426 | if (parser->local.delimiter_branch > 1) { |
427 | dbg_hid("alternative usage ignored\n"); | 427 | dbg_hid("alternative usage ignored\n"); |
428 | return 0; | 428 | return 0; |
429 | } | 429 | } |
430 | 430 | ||
431 | if (item->size <= 2) | 431 | if (item->size <= 2) |
432 | data = (parser->global.usage_page << 16) + data; | 432 | data = (parser->global.usage_page << 16) + data; |
433 | 433 | ||
434 | return hid_add_usage(parser, data); | 434 | return hid_add_usage(parser, data); |
435 | 435 | ||
436 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: | 436 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: |
437 | 437 | ||
438 | if (parser->local.delimiter_branch > 1) { | 438 | if (parser->local.delimiter_branch > 1) { |
439 | dbg_hid("alternative usage ignored\n"); | 439 | dbg_hid("alternative usage ignored\n"); |
440 | return 0; | 440 | return 0; |
441 | } | 441 | } |
442 | 442 | ||
443 | if (item->size <= 2) | 443 | if (item->size <= 2) |
444 | data = (parser->global.usage_page << 16) + data; | 444 | data = (parser->global.usage_page << 16) + data; |
445 | 445 | ||
446 | parser->local.usage_minimum = data; | 446 | parser->local.usage_minimum = data; |
447 | return 0; | 447 | return 0; |
448 | 448 | ||
449 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: | 449 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: |
450 | 450 | ||
451 | if (parser->local.delimiter_branch > 1) { | 451 | if (parser->local.delimiter_branch > 1) { |
452 | dbg_hid("alternative usage ignored\n"); | 452 | dbg_hid("alternative usage ignored\n"); |
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
455 | 455 | ||
456 | if (item->size <= 2) | 456 | if (item->size <= 2) |
457 | data = (parser->global.usage_page << 16) + data; | 457 | data = (parser->global.usage_page << 16) + data; |
458 | 458 | ||
459 | for (n = parser->local.usage_minimum; n <= data; n++) | 459 | for (n = parser->local.usage_minimum; n <= data; n++) |
460 | if (hid_add_usage(parser, n)) { | 460 | if (hid_add_usage(parser, n)) { |
461 | dbg_hid("hid_add_usage failed\n"); | 461 | dbg_hid("hid_add_usage failed\n"); |
462 | return -1; | 462 | return -1; |
463 | } | 463 | } |
464 | return 0; | 464 | return 0; |
465 | 465 | ||
466 | default: | 466 | default: |
467 | 467 | ||
468 | dbg_hid("unknown local item tag 0x%x\n", item->tag); | 468 | dbg_hid("unknown local item tag 0x%x\n", item->tag); |
469 | return 0; | 469 | return 0; |
470 | } | 470 | } |
471 | return 0; | 471 | return 0; |
472 | } | 472 | } |
473 | 473 | ||
474 | /* | 474 | /* |
475 | * Process a main item. | 475 | * Process a main item. |
476 | */ | 476 | */ |
477 | 477 | ||
478 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) | 478 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) |
479 | { | 479 | { |
480 | __u32 data; | 480 | __u32 data; |
481 | int ret; | 481 | int ret; |
482 | 482 | ||
483 | data = item_udata(item); | 483 | data = item_udata(item); |
484 | 484 | ||
485 | switch (item->tag) { | 485 | switch (item->tag) { |
486 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: | 486 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: |
487 | ret = open_collection(parser, data & 0xff); | 487 | ret = open_collection(parser, data & 0xff); |
488 | break; | 488 | break; |
489 | case HID_MAIN_ITEM_TAG_END_COLLECTION: | 489 | case HID_MAIN_ITEM_TAG_END_COLLECTION: |
490 | ret = close_collection(parser); | 490 | ret = close_collection(parser); |
491 | break; | 491 | break; |
492 | case HID_MAIN_ITEM_TAG_INPUT: | 492 | case HID_MAIN_ITEM_TAG_INPUT: |
493 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); | 493 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); |
494 | break; | 494 | break; |
495 | case HID_MAIN_ITEM_TAG_OUTPUT: | 495 | case HID_MAIN_ITEM_TAG_OUTPUT: |
496 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); | 496 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); |
497 | break; | 497 | break; |
498 | case HID_MAIN_ITEM_TAG_FEATURE: | 498 | case HID_MAIN_ITEM_TAG_FEATURE: |
499 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); | 499 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); |
500 | break; | 500 | break; |
501 | default: | 501 | default: |
502 | dbg_hid("unknown main item tag 0x%x\n", item->tag); | 502 | dbg_hid("unknown main item tag 0x%x\n", item->tag); |
503 | ret = 0; | 503 | ret = 0; |
504 | } | 504 | } |
505 | 505 | ||
506 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ | 506 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ |
507 | 507 | ||
508 | return ret; | 508 | return ret; |
509 | } | 509 | } |
510 | 510 | ||
511 | /* | 511 | /* |
512 | * Process a reserved item. | 512 | * Process a reserved item. |
513 | */ | 513 | */ |
514 | 514 | ||
515 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) | 515 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) |
516 | { | 516 | { |
517 | dbg_hid("reserved item type, tag 0x%x\n", item->tag); | 517 | dbg_hid("reserved item type, tag 0x%x\n", item->tag); |
518 | return 0; | 518 | return 0; |
519 | } | 519 | } |
520 | 520 | ||
521 | /* | 521 | /* |
522 | * Free a report and all registered fields. The field->usage and | 522 | * Free a report and all registered fields. The field->usage and |
523 | * field->value table's are allocated behind the field, so we need | 523 | * field->value table's are allocated behind the field, so we need |
524 | * only to free(field) itself. | 524 | * only to free(field) itself. |
525 | */ | 525 | */ |
526 | 526 | ||
527 | static void hid_free_report(struct hid_report *report) | 527 | static void hid_free_report(struct hid_report *report) |
528 | { | 528 | { |
529 | unsigned n; | 529 | unsigned n; |
530 | 530 | ||
531 | for (n = 0; n < report->maxfield; n++) | 531 | for (n = 0; n < report->maxfield; n++) |
532 | kfree(report->field[n]); | 532 | kfree(report->field[n]); |
533 | kfree(report); | 533 | kfree(report); |
534 | } | 534 | } |
535 | 535 | ||
536 | /* | 536 | /* |
537 | * Free a device structure, all reports, and all fields. | 537 | * Free a device structure, all reports, and all fields. |
538 | */ | 538 | */ |
539 | 539 | ||
540 | static void hid_device_release(struct device *dev) | 540 | static void hid_device_release(struct device *dev) |
541 | { | 541 | { |
542 | struct hid_device *device = container_of(dev, struct hid_device, dev); | 542 | struct hid_device *device = container_of(dev, struct hid_device, dev); |
543 | unsigned i, j; | 543 | unsigned i, j; |
544 | 544 | ||
545 | for (i = 0; i < HID_REPORT_TYPES; i++) { | 545 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
546 | struct hid_report_enum *report_enum = device->report_enum + i; | 546 | struct hid_report_enum *report_enum = device->report_enum + i; |
547 | 547 | ||
548 | for (j = 0; j < 256; j++) { | 548 | for (j = 0; j < 256; j++) { |
549 | struct hid_report *report = report_enum->report_id_hash[j]; | 549 | struct hid_report *report = report_enum->report_id_hash[j]; |
550 | if (report) | 550 | if (report) |
551 | hid_free_report(report); | 551 | hid_free_report(report); |
552 | } | 552 | } |
553 | } | 553 | } |
554 | 554 | ||
555 | kfree(device->rdesc); | 555 | kfree(device->rdesc); |
556 | kfree(device->collection); | 556 | kfree(device->collection); |
557 | kfree(device); | 557 | kfree(device); |
558 | } | 558 | } |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * Fetch a report description item from the data stream. We support long | 561 | * Fetch a report description item from the data stream. We support long |
562 | * items, though they are not used yet. | 562 | * items, though they are not used yet. |
563 | */ | 563 | */ |
564 | 564 | ||
565 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | 565 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) |
566 | { | 566 | { |
567 | u8 b; | 567 | u8 b; |
568 | 568 | ||
569 | if ((end - start) <= 0) | 569 | if ((end - start) <= 0) |
570 | return NULL; | 570 | return NULL; |
571 | 571 | ||
572 | b = *start++; | 572 | b = *start++; |
573 | 573 | ||
574 | item->type = (b >> 2) & 3; | 574 | item->type = (b >> 2) & 3; |
575 | item->tag = (b >> 4) & 15; | 575 | item->tag = (b >> 4) & 15; |
576 | 576 | ||
577 | if (item->tag == HID_ITEM_TAG_LONG) { | 577 | if (item->tag == HID_ITEM_TAG_LONG) { |
578 | 578 | ||
579 | item->format = HID_ITEM_FORMAT_LONG; | 579 | item->format = HID_ITEM_FORMAT_LONG; |
580 | 580 | ||
581 | if ((end - start) < 2) | 581 | if ((end - start) < 2) |
582 | return NULL; | 582 | return NULL; |
583 | 583 | ||
584 | item->size = *start++; | 584 | item->size = *start++; |
585 | item->tag = *start++; | 585 | item->tag = *start++; |
586 | 586 | ||
587 | if ((end - start) < item->size) | 587 | if ((end - start) < item->size) |
588 | return NULL; | 588 | return NULL; |
589 | 589 | ||
590 | item->data.longdata = start; | 590 | item->data.longdata = start; |
591 | start += item->size; | 591 | start += item->size; |
592 | return start; | 592 | return start; |
593 | } | 593 | } |
594 | 594 | ||
595 | item->format = HID_ITEM_FORMAT_SHORT; | 595 | item->format = HID_ITEM_FORMAT_SHORT; |
596 | item->size = b & 3; | 596 | item->size = b & 3; |
597 | 597 | ||
598 | switch (item->size) { | 598 | switch (item->size) { |
599 | case 0: | 599 | case 0: |
600 | return start; | 600 | return start; |
601 | 601 | ||
602 | case 1: | 602 | case 1: |
603 | if ((end - start) < 1) | 603 | if ((end - start) < 1) |
604 | return NULL; | 604 | return NULL; |
605 | item->data.u8 = *start++; | 605 | item->data.u8 = *start++; |
606 | return start; | 606 | return start; |
607 | 607 | ||
608 | case 2: | 608 | case 2: |
609 | if ((end - start) < 2) | 609 | if ((end - start) < 2) |
610 | return NULL; | 610 | return NULL; |
611 | item->data.u16 = get_unaligned_le16(start); | 611 | item->data.u16 = get_unaligned_le16(start); |
612 | start = (__u8 *)((__le16 *)start + 1); | 612 | start = (__u8 *)((__le16 *)start + 1); |
613 | return start; | 613 | return start; |
614 | 614 | ||
615 | case 3: | 615 | case 3: |
616 | item->size++; | 616 | item->size++; |
617 | if ((end - start) < 4) | 617 | if ((end - start) < 4) |
618 | return NULL; | 618 | return NULL; |
619 | item->data.u32 = get_unaligned_le32(start); | 619 | item->data.u32 = get_unaligned_le32(start); |
620 | start = (__u8 *)((__le32 *)start + 1); | 620 | start = (__u8 *)((__le32 *)start + 1); |
621 | return start; | 621 | return start; |
622 | } | 622 | } |
623 | 623 | ||
624 | return NULL; | 624 | return NULL; |
625 | } | 625 | } |
626 | 626 | ||
627 | /** | 627 | /** |
628 | * hid_parse_report - parse device report | 628 | * hid_parse_report - parse device report |
629 | * | 629 | * |
630 | * @device: hid device | 630 | * @device: hid device |
631 | * @start: report start | 631 | * @start: report start |
632 | * @size: report size | 632 | * @size: report size |
633 | * | 633 | * |
634 | * Parse a report description into a hid_device structure. Reports are | 634 | * Parse a report description into a hid_device structure. Reports are |
635 | * enumerated, fields are attached to these reports. | 635 | * enumerated, fields are attached to these reports. |
636 | * 0 returned on success, otherwise nonzero error value. | 636 | * 0 returned on success, otherwise nonzero error value. |
637 | */ | 637 | */ |
638 | int hid_parse_report(struct hid_device *device, __u8 *start, | 638 | int hid_parse_report(struct hid_device *device, __u8 *start, |
639 | unsigned size) | 639 | unsigned size) |
640 | { | 640 | { |
641 | struct hid_parser *parser; | 641 | struct hid_parser *parser; |
642 | struct hid_item item; | 642 | struct hid_item item; |
643 | __u8 *end; | 643 | __u8 *end; |
644 | int ret; | 644 | int ret; |
645 | static int (*dispatch_type[])(struct hid_parser *parser, | 645 | static int (*dispatch_type[])(struct hid_parser *parser, |
646 | struct hid_item *item) = { | 646 | struct hid_item *item) = { |
647 | hid_parser_main, | 647 | hid_parser_main, |
648 | hid_parser_global, | 648 | hid_parser_global, |
649 | hid_parser_local, | 649 | hid_parser_local, |
650 | hid_parser_reserved | 650 | hid_parser_reserved |
651 | }; | 651 | }; |
652 | 652 | ||
653 | if (device->driver->report_fixup) | 653 | if (device->driver->report_fixup) |
654 | device->driver->report_fixup(device, start, size); | 654 | device->driver->report_fixup(device, start, size); |
655 | 655 | ||
656 | device->rdesc = kmemdup(start, size, GFP_KERNEL); | 656 | device->rdesc = kmemdup(start, size, GFP_KERNEL); |
657 | if (device->rdesc == NULL) | 657 | if (device->rdesc == NULL) |
658 | return -ENOMEM; | 658 | return -ENOMEM; |
659 | device->rsize = size; | 659 | device->rsize = size; |
660 | 660 | ||
661 | parser = vmalloc(sizeof(struct hid_parser)); | 661 | parser = vmalloc(sizeof(struct hid_parser)); |
662 | if (!parser) { | 662 | if (!parser) { |
663 | ret = -ENOMEM; | 663 | ret = -ENOMEM; |
664 | goto err; | 664 | goto err; |
665 | } | 665 | } |
666 | 666 | ||
667 | memset(parser, 0, sizeof(struct hid_parser)); | 667 | memset(parser, 0, sizeof(struct hid_parser)); |
668 | parser->device = device; | 668 | parser->device = device; |
669 | 669 | ||
670 | end = start + size; | 670 | end = start + size; |
671 | ret = -EINVAL; | 671 | ret = -EINVAL; |
672 | while ((start = fetch_item(start, end, &item)) != NULL) { | 672 | while ((start = fetch_item(start, end, &item)) != NULL) { |
673 | 673 | ||
674 | if (item.format != HID_ITEM_FORMAT_SHORT) { | 674 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
675 | dbg_hid("unexpected long global item\n"); | 675 | dbg_hid("unexpected long global item\n"); |
676 | goto err; | 676 | goto err; |
677 | } | 677 | } |
678 | 678 | ||
679 | if (dispatch_type[item.type](parser, &item)) { | 679 | if (dispatch_type[item.type](parser, &item)) { |
680 | dbg_hid("item %u %u %u %u parsing failed\n", | 680 | dbg_hid("item %u %u %u %u parsing failed\n", |
681 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); | 681 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); |
682 | goto err; | 682 | goto err; |
683 | } | 683 | } |
684 | 684 | ||
685 | if (start == end) { | 685 | if (start == end) { |
686 | if (parser->collection_stack_ptr) { | 686 | if (parser->collection_stack_ptr) { |
687 | dbg_hid("unbalanced collection at end of report description\n"); | 687 | dbg_hid("unbalanced collection at end of report description\n"); |
688 | goto err; | 688 | goto err; |
689 | } | 689 | } |
690 | if (parser->local.delimiter_depth) { | 690 | if (parser->local.delimiter_depth) { |
691 | dbg_hid("unbalanced delimiter at end of report description\n"); | 691 | dbg_hid("unbalanced delimiter at end of report description\n"); |
692 | goto err; | 692 | goto err; |
693 | } | 693 | } |
694 | vfree(parser); | 694 | vfree(parser); |
695 | return 0; | 695 | return 0; |
696 | } | 696 | } |
697 | } | 697 | } |
698 | 698 | ||
699 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); | 699 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); |
700 | err: | 700 | err: |
701 | vfree(parser); | 701 | vfree(parser); |
702 | return ret; | 702 | return ret; |
703 | } | 703 | } |
704 | EXPORT_SYMBOL_GPL(hid_parse_report); | 704 | EXPORT_SYMBOL_GPL(hid_parse_report); |
705 | 705 | ||
706 | /* | 706 | /* |
707 | * Convert a signed n-bit integer to signed 32-bit integer. Common | 707 | * Convert a signed n-bit integer to signed 32-bit integer. Common |
708 | * cases are done through the compiler, the screwed things has to be | 708 | * cases are done through the compiler, the screwed things has to be |
709 | * done by hand. | 709 | * done by hand. |
710 | */ | 710 | */ |
711 | 711 | ||
712 | static s32 snto32(__u32 value, unsigned n) | 712 | static s32 snto32(__u32 value, unsigned n) |
713 | { | 713 | { |
714 | switch (n) { | 714 | switch (n) { |
715 | case 8: return ((__s8)value); | 715 | case 8: return ((__s8)value); |
716 | case 16: return ((__s16)value); | 716 | case 16: return ((__s16)value); |
717 | case 32: return ((__s32)value); | 717 | case 32: return ((__s32)value); |
718 | } | 718 | } |
719 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; | 719 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; |
720 | } | 720 | } |
721 | 721 | ||
722 | /* | 722 | /* |
723 | * Convert a signed 32-bit integer to a signed n-bit integer. | 723 | * Convert a signed 32-bit integer to a signed n-bit integer. |
724 | */ | 724 | */ |
725 | 725 | ||
726 | static u32 s32ton(__s32 value, unsigned n) | 726 | static u32 s32ton(__s32 value, unsigned n) |
727 | { | 727 | { |
728 | s32 a = value >> (n - 1); | 728 | s32 a = value >> (n - 1); |
729 | if (a && a != -1) | 729 | if (a && a != -1) |
730 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; | 730 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; |
731 | return value & ((1 << n) - 1); | 731 | return value & ((1 << n) - 1); |
732 | } | 732 | } |
733 | 733 | ||
734 | /* | 734 | /* |
735 | * Extract/implement a data field from/to a little endian report (bit array). | 735 | * Extract/implement a data field from/to a little endian report (bit array). |
736 | * | 736 | * |
737 | * Code sort-of follows HID spec: | 737 | * Code sort-of follows HID spec: |
738 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf | 738 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf |
739 | * | 739 | * |
740 | * While the USB HID spec allows unlimited length bit fields in "report | 740 | * While the USB HID spec allows unlimited length bit fields in "report |
741 | * descriptors", most devices never use more than 16 bits. | 741 | * descriptors", most devices never use more than 16 bits. |
742 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. | 742 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. |
743 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". | 743 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". |
744 | */ | 744 | */ |
745 | 745 | ||
746 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | 746 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) |
747 | { | 747 | { |
748 | u64 x; | 748 | u64 x; |
749 | 749 | ||
750 | if (n > 32) | 750 | if (n > 32) |
751 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", | 751 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", |
752 | n, current->comm); | 752 | n, current->comm); |
753 | 753 | ||
754 | report += offset >> 3; /* adjust byte index */ | 754 | report += offset >> 3; /* adjust byte index */ |
755 | offset &= 7; /* now only need bit offset into one byte */ | 755 | offset &= 7; /* now only need bit offset into one byte */ |
756 | x = get_unaligned_le64(report); | 756 | x = get_unaligned_le64(report); |
757 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ | 757 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ |
758 | return (u32) x; | 758 | return (u32) x; |
759 | } | 759 | } |
760 | 760 | ||
761 | /* | 761 | /* |
762 | * "implement" : set bits in a little endian bit stream. | 762 | * "implement" : set bits in a little endian bit stream. |
763 | * Same concepts as "extract" (see comments above). | 763 | * Same concepts as "extract" (see comments above). |
764 | * The data mangled in the bit stream remains in little endian | 764 | * The data mangled in the bit stream remains in little endian |
765 | * order the whole time. It make more sense to talk about | 765 | * order the whole time. It make more sense to talk about |
766 | * endianness of register values by considering a register | 766 | * endianness of register values by considering a register |
767 | * a "cached" copy of the little endiad bit stream. | 767 | * a "cached" copy of the little endiad bit stream. |
768 | */ | 768 | */ |
769 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | 769 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
770 | { | 770 | { |
771 | u64 x; | 771 | u64 x; |
772 | u64 m = (1ULL << n) - 1; | 772 | u64 m = (1ULL << n) - 1; |
773 | 773 | ||
774 | if (n > 32) | 774 | if (n > 32) |
775 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", | 775 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", |
776 | n, current->comm); | 776 | n, current->comm); |
777 | 777 | ||
778 | if (value > m) | 778 | if (value > m) |
779 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", | 779 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", |
780 | value, current->comm); | 780 | value, current->comm); |
781 | WARN_ON(value > m); | 781 | WARN_ON(value > m); |
782 | value &= m; | 782 | value &= m; |
783 | 783 | ||
784 | report += offset >> 3; | 784 | report += offset >> 3; |
785 | offset &= 7; | 785 | offset &= 7; |
786 | 786 | ||
787 | x = get_unaligned_le64(report); | 787 | x = get_unaligned_le64(report); |
788 | x &= ~(m << offset); | 788 | x &= ~(m << offset); |
789 | x |= ((u64)value) << offset; | 789 | x |= ((u64)value) << offset; |
790 | put_unaligned_le64(x, report); | 790 | put_unaligned_le64(x, report); |
791 | } | 791 | } |
792 | 792 | ||
793 | /* | 793 | /* |
794 | * Search an array for a value. | 794 | * Search an array for a value. |
795 | */ | 795 | */ |
796 | 796 | ||
797 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) | 797 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) |
798 | { | 798 | { |
799 | while (n--) { | 799 | while (n--) { |
800 | if (*array++ == value) | 800 | if (*array++ == value) |
801 | return 0; | 801 | return 0; |
802 | } | 802 | } |
803 | return -1; | 803 | return -1; |
804 | } | 804 | } |
805 | 805 | ||
806 | /** | 806 | /** |
807 | * hid_match_report - check if driver's raw_event should be called | 807 | * hid_match_report - check if driver's raw_event should be called |
808 | * | 808 | * |
809 | * @hid: hid device | 809 | * @hid: hid device |
810 | * @report_type: type to match against | 810 | * @report_type: type to match against |
811 | * | 811 | * |
812 | * compare hid->driver->report_table->report_type to report->type | 812 | * compare hid->driver->report_table->report_type to report->type |
813 | */ | 813 | */ |
814 | static int hid_match_report(struct hid_device *hid, struct hid_report *report) | 814 | static int hid_match_report(struct hid_device *hid, struct hid_report *report) |
815 | { | 815 | { |
816 | const struct hid_report_id *id = hid->driver->report_table; | 816 | const struct hid_report_id *id = hid->driver->report_table; |
817 | 817 | ||
818 | if (!id) /* NULL means all */ | 818 | if (!id) /* NULL means all */ |
819 | return 1; | 819 | return 1; |
820 | 820 | ||
821 | for (; id->report_type != HID_TERMINATOR; id++) | 821 | for (; id->report_type != HID_TERMINATOR; id++) |
822 | if (id->report_type == HID_ANY_ID || | 822 | if (id->report_type == HID_ANY_ID || |
823 | id->report_type == report->type) | 823 | id->report_type == report->type) |
824 | return 1; | 824 | return 1; |
825 | return 0; | 825 | return 0; |
826 | } | 826 | } |
827 | 827 | ||
828 | /** | 828 | /** |
829 | * hid_match_usage - check if driver's event should be called | 829 | * hid_match_usage - check if driver's event should be called |
830 | * | 830 | * |
831 | * @hid: hid device | 831 | * @hid: hid device |
832 | * @usage: usage to match against | 832 | * @usage: usage to match against |
833 | * | 833 | * |
834 | * compare hid->driver->usage_table->usage_{type,code} to | 834 | * compare hid->driver->usage_table->usage_{type,code} to |
835 | * usage->usage_{type,code} | 835 | * usage->usage_{type,code} |
836 | */ | 836 | */ |
837 | static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) | 837 | static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) |
838 | { | 838 | { |
839 | const struct hid_usage_id *id = hid->driver->usage_table; | 839 | const struct hid_usage_id *id = hid->driver->usage_table; |
840 | 840 | ||
841 | if (!id) /* NULL means all */ | 841 | if (!id) /* NULL means all */ |
842 | return 1; | 842 | return 1; |
843 | 843 | ||
844 | for (; id->usage_type != HID_ANY_ID - 1; id++) | 844 | for (; id->usage_type != HID_ANY_ID - 1; id++) |
845 | if ((id->usage_hid == HID_ANY_ID || | 845 | if ((id->usage_hid == HID_ANY_ID || |
846 | id->usage_hid == usage->hid) && | 846 | id->usage_hid == usage->hid) && |
847 | (id->usage_type == HID_ANY_ID || | 847 | (id->usage_type == HID_ANY_ID || |
848 | id->usage_type == usage->type) && | 848 | id->usage_type == usage->type) && |
849 | (id->usage_code == HID_ANY_ID || | 849 | (id->usage_code == HID_ANY_ID || |
850 | id->usage_code == usage->code)) | 850 | id->usage_code == usage->code)) |
851 | return 1; | 851 | return 1; |
852 | return 0; | 852 | return 0; |
853 | } | 853 | } |
854 | 854 | ||
855 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, | 855 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, |
856 | struct hid_usage *usage, __s32 value, int interrupt) | 856 | struct hid_usage *usage, __s32 value, int interrupt) |
857 | { | 857 | { |
858 | struct hid_driver *hdrv = hid->driver; | 858 | struct hid_driver *hdrv = hid->driver; |
859 | int ret; | 859 | int ret; |
860 | 860 | ||
861 | hid_dump_input(hid, usage, value); | 861 | hid_dump_input(hid, usage, value); |
862 | 862 | ||
863 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { | 863 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { |
864 | ret = hdrv->event(hid, field, usage, value); | 864 | ret = hdrv->event(hid, field, usage, value); |
865 | if (ret != 0) { | 865 | if (ret != 0) { |
866 | if (ret < 0) | 866 | if (ret < 0) |
867 | dbg_hid("%s's event failed with %d\n", | 867 | dbg_hid("%s's event failed with %d\n", |
868 | hdrv->name, ret); | 868 | hdrv->name, ret); |
869 | return; | 869 | return; |
870 | } | 870 | } |
871 | } | 871 | } |
872 | 872 | ||
873 | if (hid->claimed & HID_CLAIMED_INPUT) | 873 | if (hid->claimed & HID_CLAIMED_INPUT) |
874 | hidinput_hid_event(hid, field, usage, value); | 874 | hidinput_hid_event(hid, field, usage, value); |
875 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) | 875 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) |
876 | hid->hiddev_hid_event(hid, field, usage, value); | 876 | hid->hiddev_hid_event(hid, field, usage, value); |
877 | } | 877 | } |
878 | 878 | ||
879 | /* | 879 | /* |
880 | * Analyse a received field, and fetch the data from it. The field | 880 | * Analyse a received field, and fetch the data from it. The field |
881 | * content is stored for next report processing (we do differential | 881 | * content is stored for next report processing (we do differential |
882 | * reporting to the layer). | 882 | * reporting to the layer). |
883 | */ | 883 | */ |
884 | 884 | ||
885 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, | 885 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, |
886 | __u8 *data, int interrupt) | 886 | __u8 *data, int interrupt) |
887 | { | 887 | { |
888 | unsigned n; | 888 | unsigned n; |
889 | unsigned count = field->report_count; | 889 | unsigned count = field->report_count; |
890 | unsigned offset = field->report_offset; | 890 | unsigned offset = field->report_offset; |
891 | unsigned size = field->report_size; | 891 | unsigned size = field->report_size; |
892 | __s32 min = field->logical_minimum; | 892 | __s32 min = field->logical_minimum; |
893 | __s32 max = field->logical_maximum; | 893 | __s32 max = field->logical_maximum; |
894 | __s32 *value; | 894 | __s32 *value; |
895 | 895 | ||
896 | if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) | 896 | if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) |
897 | return; | 897 | return; |
898 | 898 | ||
899 | for (n = 0; n < count; n++) { | 899 | for (n = 0; n < count; n++) { |
900 | 900 | ||
901 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : | 901 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : |
902 | extract(data, offset + n * size, size); | 902 | extract(data, offset + n * size, size); |
903 | 903 | ||
904 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ | 904 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ |
905 | && value[n] >= min && value[n] <= max | 905 | && value[n] >= min && value[n] <= max |
906 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) | 906 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) |
907 | goto exit; | 907 | goto exit; |
908 | } | 908 | } |
909 | 909 | ||
910 | for (n = 0; n < count; n++) { | 910 | for (n = 0; n < count; n++) { |
911 | 911 | ||
912 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { | 912 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { |
913 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt); | 913 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt); |
914 | continue; | 914 | continue; |
915 | } | 915 | } |
916 | 916 | ||
917 | if (field->value[n] >= min && field->value[n] <= max | 917 | if (field->value[n] >= min && field->value[n] <= max |
918 | && field->usage[field->value[n] - min].hid | 918 | && field->usage[field->value[n] - min].hid |
919 | && search(value, field->value[n], count)) | 919 | && search(value, field->value[n], count)) |
920 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); | 920 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); |
921 | 921 | ||
922 | if (value[n] >= min && value[n] <= max | 922 | if (value[n] >= min && value[n] <= max |
923 | && field->usage[value[n] - min].hid | 923 | && field->usage[value[n] - min].hid |
924 | && search(field->value, value[n], count)) | 924 | && search(field->value, value[n], count)) |
925 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); | 925 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); |
926 | } | 926 | } |
927 | 927 | ||
928 | memcpy(field->value, value, count * sizeof(__s32)); | 928 | memcpy(field->value, value, count * sizeof(__s32)); |
929 | exit: | 929 | exit: |
930 | kfree(value); | 930 | kfree(value); |
931 | } | 931 | } |
932 | 932 | ||
933 | /* | 933 | /* |
934 | * Output the field into the report. | 934 | * Output the field into the report. |
935 | */ | 935 | */ |
936 | 936 | ||
937 | static void hid_output_field(struct hid_field *field, __u8 *data) | 937 | static void hid_output_field(struct hid_field *field, __u8 *data) |
938 | { | 938 | { |
939 | unsigned count = field->report_count; | 939 | unsigned count = field->report_count; |
940 | unsigned offset = field->report_offset; | 940 | unsigned offset = field->report_offset; |
941 | unsigned size = field->report_size; | 941 | unsigned size = field->report_size; |
942 | unsigned n; | 942 | unsigned n; |
943 | 943 | ||
944 | for (n = 0; n < count; n++) { | 944 | for (n = 0; n < count; n++) { |
945 | if (field->logical_minimum < 0) /* signed values */ | 945 | if (field->logical_minimum < 0) /* signed values */ |
946 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); | 946 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); |
947 | else /* unsigned values */ | 947 | else /* unsigned values */ |
948 | implement(data, offset + n * size, size, field->value[n]); | 948 | implement(data, offset + n * size, size, field->value[n]); |
949 | } | 949 | } |
950 | } | 950 | } |
951 | 951 | ||
952 | /* | 952 | /* |
953 | * Create a report. | 953 | * Create a report. |
954 | */ | 954 | */ |
955 | 955 | ||
956 | void hid_output_report(struct hid_report *report, __u8 *data) | 956 | void hid_output_report(struct hid_report *report, __u8 *data) |
957 | { | 957 | { |
958 | unsigned n; | 958 | unsigned n; |
959 | 959 | ||
960 | if (report->id > 0) | 960 | if (report->id > 0) |
961 | *data++ = report->id; | 961 | *data++ = report->id; |
962 | 962 | ||
963 | memset(data, 0, ((report->size - 1) >> 3) + 1); | 963 | memset(data, 0, ((report->size - 1) >> 3) + 1); |
964 | for (n = 0; n < report->maxfield; n++) | 964 | for (n = 0; n < report->maxfield; n++) |
965 | hid_output_field(report->field[n], data); | 965 | hid_output_field(report->field[n], data); |
966 | } | 966 | } |
967 | EXPORT_SYMBOL_GPL(hid_output_report); | 967 | EXPORT_SYMBOL_GPL(hid_output_report); |
968 | 968 | ||
969 | /* | 969 | /* |
970 | * Set a field value. The report this field belongs to has to be | 970 | * Set a field value. The report this field belongs to has to be |
971 | * created and transferred to the device, to set this value in the | 971 | * created and transferred to the device, to set this value in the |
972 | * device. | 972 | * device. |
973 | */ | 973 | */ |
974 | 974 | ||
975 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) | 975 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) |
976 | { | 976 | { |
977 | unsigned size = field->report_size; | 977 | unsigned size = field->report_size; |
978 | 978 | ||
979 | hid_dump_input(field->report->device, field->usage + offset, value); | 979 | hid_dump_input(field->report->device, field->usage + offset, value); |
980 | 980 | ||
981 | if (offset >= field->report_count) { | 981 | if (offset >= field->report_count) { |
982 | dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); | 982 | dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); |
983 | return -1; | 983 | return -1; |
984 | } | 984 | } |
985 | if (field->logical_minimum < 0) { | 985 | if (field->logical_minimum < 0) { |
986 | if (value != snto32(s32ton(value, size), size)) { | 986 | if (value != snto32(s32ton(value, size), size)) { |
987 | dbg_hid("value %d is out of range\n", value); | 987 | dbg_hid("value %d is out of range\n", value); |
988 | return -1; | 988 | return -1; |
989 | } | 989 | } |
990 | } | 990 | } |
991 | field->value[offset] = value; | 991 | field->value[offset] = value; |
992 | return 0; | 992 | return 0; |
993 | } | 993 | } |
994 | EXPORT_SYMBOL_GPL(hid_set_field); | 994 | EXPORT_SYMBOL_GPL(hid_set_field); |
995 | 995 | ||
996 | static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, | 996 | static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, |
997 | const u8 *data) | 997 | const u8 *data) |
998 | { | 998 | { |
999 | struct hid_report *report; | 999 | struct hid_report *report; |
1000 | unsigned int n = 0; /* Normally report number is 0 */ | 1000 | unsigned int n = 0; /* Normally report number is 0 */ |
1001 | 1001 | ||
1002 | /* Device uses numbered reports, data[0] is report number */ | 1002 | /* Device uses numbered reports, data[0] is report number */ |
1003 | if (report_enum->numbered) | 1003 | if (report_enum->numbered) |
1004 | n = *data; | 1004 | n = *data; |
1005 | 1005 | ||
1006 | report = report_enum->report_id_hash[n]; | 1006 | report = report_enum->report_id_hash[n]; |
1007 | if (report == NULL) | 1007 | if (report == NULL) |
1008 | dbg_hid("undefined report_id %u received\n", n); | 1008 | dbg_hid("undefined report_id %u received\n", n); |
1009 | 1009 | ||
1010 | return report; | 1010 | return report; |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 1013 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
1014 | int interrupt) | 1014 | int interrupt) |
1015 | { | 1015 | { |
1016 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1016 | struct hid_report_enum *report_enum = hid->report_enum + type; |
1017 | struct hid_report *report; | 1017 | struct hid_report *report; |
1018 | unsigned int a; | 1018 | unsigned int a; |
1019 | int rsize, csize = size; | 1019 | int rsize, csize = size; |
1020 | u8 *cdata = data; | 1020 | u8 *cdata = data; |
1021 | 1021 | ||
1022 | report = hid_get_report(report_enum, data); | 1022 | report = hid_get_report(report_enum, data); |
1023 | if (!report) | 1023 | if (!report) |
1024 | return; | 1024 | return; |
1025 | 1025 | ||
1026 | if (report_enum->numbered) { | 1026 | if (report_enum->numbered) { |
1027 | cdata++; | 1027 | cdata++; |
1028 | csize--; | 1028 | csize--; |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | rsize = ((report->size - 1) >> 3) + 1; | 1031 | rsize = ((report->size - 1) >> 3) + 1; |
1032 | 1032 | ||
1033 | if (csize < rsize) { | 1033 | if (csize < rsize) { |
1034 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, | 1034 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, |
1035 | csize, rsize); | 1035 | csize, rsize); |
1036 | memset(cdata + csize, 0, rsize - csize); | 1036 | memset(cdata + csize, 0, rsize - csize); |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) | 1039 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) |
1040 | hid->hiddev_report_event(hid, report); | 1040 | hid->hiddev_report_event(hid, report); |
1041 | if (hid->claimed & HID_CLAIMED_HIDRAW) | 1041 | if (hid->claimed & HID_CLAIMED_HIDRAW) |
1042 | hidraw_report_event(hid, data, size); | 1042 | hidraw_report_event(hid, data, size); |
1043 | 1043 | ||
1044 | for (a = 0; a < report->maxfield; a++) | 1044 | for (a = 0; a < report->maxfield; a++) |
1045 | hid_input_field(hid, report->field[a], cdata, interrupt); | 1045 | hid_input_field(hid, report->field[a], cdata, interrupt); |
1046 | 1046 | ||
1047 | if (hid->claimed & HID_CLAIMED_INPUT) | 1047 | if (hid->claimed & HID_CLAIMED_INPUT) |
1048 | hidinput_report_event(hid, report); | 1048 | hidinput_report_event(hid, report); |
1049 | } | 1049 | } |
1050 | EXPORT_SYMBOL_GPL(hid_report_raw_event); | 1050 | EXPORT_SYMBOL_GPL(hid_report_raw_event); |
1051 | 1051 | ||
1052 | /** | 1052 | /** |
1053 | * hid_input_report - report data from lower layer (usb, bt...) | 1053 | * hid_input_report - report data from lower layer (usb, bt...) |
1054 | * | 1054 | * |
1055 | * @hid: hid device | 1055 | * @hid: hid device |
1056 | * @type: HID report type (HID_*_REPORT) | 1056 | * @type: HID report type (HID_*_REPORT) |
1057 | * @data: report contents | 1057 | * @data: report contents |
1058 | * @size: size of data parameter | 1058 | * @size: size of data parameter |
1059 | * @interrupt: distinguish between interrupt and control transfers | 1059 | * @interrupt: distinguish between interrupt and control transfers |
1060 | * | 1060 | * |
1061 | * This is data entry for lower layers. | 1061 | * This is data entry for lower layers. |
1062 | */ | 1062 | */ |
1063 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | 1063 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) |
1064 | { | 1064 | { |
1065 | struct hid_report_enum *report_enum; | 1065 | struct hid_report_enum *report_enum; |
1066 | struct hid_driver *hdrv; | 1066 | struct hid_driver *hdrv; |
1067 | struct hid_report *report; | 1067 | struct hid_report *report; |
1068 | char *buf; | 1068 | char *buf; |
1069 | unsigned int i; | 1069 | unsigned int i; |
1070 | int ret; | 1070 | int ret; |
1071 | 1071 | ||
1072 | if (!hid || !hid->driver) | 1072 | if (!hid || !hid->driver) |
1073 | return -ENODEV; | 1073 | return -ENODEV; |
1074 | report_enum = hid->report_enum + type; | 1074 | report_enum = hid->report_enum + type; |
1075 | hdrv = hid->driver; | 1075 | hdrv = hid->driver; |
1076 | 1076 | ||
1077 | if (!size) { | 1077 | if (!size) { |
1078 | dbg_hid("empty report\n"); | 1078 | dbg_hid("empty report\n"); |
1079 | return -1; | 1079 | return -1; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); | 1082 | buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); |
1083 | 1083 | ||
1084 | if (!buf) | 1084 | if (!buf) |
1085 | goto nomem; | 1085 | goto nomem; |
1086 | 1086 | ||
1087 | /* dump the report */ | 1087 | /* dump the report */ |
1088 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | 1088 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, |
1089 | "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un"); | 1089 | "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un"); |
1090 | hid_debug_event(hid, buf); | 1090 | hid_debug_event(hid, buf); |
1091 | 1091 | ||
1092 | for (i = 0; i < size; i++) { | 1092 | for (i = 0; i < size; i++) { |
1093 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | 1093 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, |
1094 | " %02x", data[i]); | 1094 | " %02x", data[i]); |
1095 | hid_debug_event(hid, buf); | 1095 | hid_debug_event(hid, buf); |
1096 | } | 1096 | } |
1097 | hid_debug_event(hid, "\n"); | 1097 | hid_debug_event(hid, "\n"); |
1098 | kfree(buf); | 1098 | kfree(buf); |
1099 | 1099 | ||
1100 | nomem: | 1100 | nomem: |
1101 | report = hid_get_report(report_enum, data); | 1101 | report = hid_get_report(report_enum, data); |
1102 | 1102 | ||
1103 | if (!report) | 1103 | if (!report) |
1104 | return -1; | 1104 | return -1; |
1105 | 1105 | ||
1106 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { | 1106 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { |
1107 | ret = hdrv->raw_event(hid, report, data, size); | 1107 | ret = hdrv->raw_event(hid, report, data, size); |
1108 | if (ret != 0) | 1108 | if (ret != 0) |
1109 | return ret < 0 ? ret : 0; | 1109 | return ret < 0 ? ret : 0; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | hid_report_raw_event(hid, type, data, size, interrupt); | 1112 | hid_report_raw_event(hid, type, data, size, interrupt); |
1113 | 1113 | ||
1114 | return 0; | 1114 | return 0; |
1115 | } | 1115 | } |
1116 | EXPORT_SYMBOL_GPL(hid_input_report); | 1116 | EXPORT_SYMBOL_GPL(hid_input_report); |
1117 | 1117 | ||
1118 | static bool hid_match_one_id(struct hid_device *hdev, | 1118 | static bool hid_match_one_id(struct hid_device *hdev, |
1119 | const struct hid_device_id *id) | 1119 | const struct hid_device_id *id) |
1120 | { | 1120 | { |
1121 | return id->bus == hdev->bus && | 1121 | return id->bus == hdev->bus && |
1122 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && | 1122 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && |
1123 | (id->product == HID_ANY_ID || id->product == hdev->product); | 1123 | (id->product == HID_ANY_ID || id->product == hdev->product); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, | 1126 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, |
1127 | const struct hid_device_id *id) | 1127 | const struct hid_device_id *id) |
1128 | { | 1128 | { |
1129 | for (; id->bus; id++) | 1129 | for (; id->bus; id++) |
1130 | if (hid_match_one_id(hdev, id)) | 1130 | if (hid_match_one_id(hdev, id)) |
1131 | return id; | 1131 | return id; |
1132 | 1132 | ||
1133 | return NULL; | 1133 | return NULL; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static const struct hid_device_id hid_hiddev_list[] = { | 1136 | static const struct hid_device_id hid_hiddev_list[] = { |
1137 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) }, | 1137 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) }, |
1138 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) }, | 1138 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) }, |
1139 | { } | 1139 | { } |
1140 | }; | 1140 | }; |
1141 | 1141 | ||
1142 | static bool hid_hiddev(struct hid_device *hdev) | 1142 | static bool hid_hiddev(struct hid_device *hdev) |
1143 | { | 1143 | { |
1144 | return !!hid_match_id(hdev, hid_hiddev_list); | 1144 | return !!hid_match_id(hdev, hid_hiddev_list); |
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | 1147 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) |
1148 | { | 1148 | { |
1149 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", | 1149 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", |
1150 | "Joystick", "Gamepad", "Keyboard", "Keypad", | 1150 | "Joystick", "Gamepad", "Keyboard", "Keypad", |
1151 | "Multi-Axis Controller" | 1151 | "Multi-Axis Controller" |
1152 | }; | 1152 | }; |
1153 | const char *type, *bus; | 1153 | const char *type, *bus; |
1154 | char buf[64]; | 1154 | char buf[64]; |
1155 | unsigned int i; | 1155 | unsigned int i; |
1156 | int len; | 1156 | int len; |
1157 | 1157 | ||
1158 | if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) | 1158 | if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) |
1159 | connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); | 1159 | connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); |
1160 | if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE) | 1160 | if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE) |
1161 | connect_mask |= HID_CONNECT_HIDINPUT_FORCE; | 1161 | connect_mask |= HID_CONNECT_HIDINPUT_FORCE; |
1162 | if (hdev->bus != BUS_USB) | 1162 | if (hdev->bus != BUS_USB) |
1163 | connect_mask &= ~HID_CONNECT_HIDDEV; | 1163 | connect_mask &= ~HID_CONNECT_HIDDEV; |
1164 | if (hid_hiddev(hdev)) | 1164 | if (hid_hiddev(hdev)) |
1165 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | 1165 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; |
1166 | 1166 | ||
1167 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, | 1167 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, |
1168 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) | 1168 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) |
1169 | hdev->claimed |= HID_CLAIMED_INPUT; | 1169 | hdev->claimed |= HID_CLAIMED_INPUT; |
1170 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && | 1170 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && |
1171 | !hdev->hiddev_connect(hdev, | 1171 | !hdev->hiddev_connect(hdev, |
1172 | connect_mask & HID_CONNECT_HIDDEV_FORCE)) | 1172 | connect_mask & HID_CONNECT_HIDDEV_FORCE)) |
1173 | hdev->claimed |= HID_CLAIMED_HIDDEV; | 1173 | hdev->claimed |= HID_CLAIMED_HIDDEV; |
1174 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) | 1174 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) |
1175 | hdev->claimed |= HID_CLAIMED_HIDRAW; | 1175 | hdev->claimed |= HID_CLAIMED_HIDRAW; |
1176 | 1176 | ||
1177 | if (!hdev->claimed) { | 1177 | if (!hdev->claimed) { |
1178 | dev_err(&hdev->dev, "claimed by neither input, hiddev nor " | 1178 | dev_err(&hdev->dev, "claimed by neither input, hiddev nor " |
1179 | "hidraw\n"); | 1179 | "hidraw\n"); |
1180 | return -ENODEV; | 1180 | return -ENODEV; |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | if ((hdev->claimed & HID_CLAIMED_INPUT) && | 1183 | if ((hdev->claimed & HID_CLAIMED_INPUT) && |
1184 | (connect_mask & HID_CONNECT_FF) && hdev->ff_init) | 1184 | (connect_mask & HID_CONNECT_FF) && hdev->ff_init) |
1185 | hdev->ff_init(hdev); | 1185 | hdev->ff_init(hdev); |
1186 | 1186 | ||
1187 | len = 0; | 1187 | len = 0; |
1188 | if (hdev->claimed & HID_CLAIMED_INPUT) | 1188 | if (hdev->claimed & HID_CLAIMED_INPUT) |
1189 | len += sprintf(buf + len, "input"); | 1189 | len += sprintf(buf + len, "input"); |
1190 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | 1190 | if (hdev->claimed & HID_CLAIMED_HIDDEV) |
1191 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", | 1191 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", |
1192 | hdev->minor); | 1192 | hdev->minor); |
1193 | if (hdev->claimed & HID_CLAIMED_HIDRAW) | 1193 | if (hdev->claimed & HID_CLAIMED_HIDRAW) |
1194 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", | 1194 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", |
1195 | ((struct hidraw *)hdev->hidraw)->minor); | 1195 | ((struct hidraw *)hdev->hidraw)->minor); |
1196 | 1196 | ||
1197 | type = "Device"; | 1197 | type = "Device"; |
1198 | for (i = 0; i < hdev->maxcollection; i++) { | 1198 | for (i = 0; i < hdev->maxcollection; i++) { |
1199 | struct hid_collection *col = &hdev->collection[i]; | 1199 | struct hid_collection *col = &hdev->collection[i]; |
1200 | if (col->type == HID_COLLECTION_APPLICATION && | 1200 | if (col->type == HID_COLLECTION_APPLICATION && |
1201 | (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && | 1201 | (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && |
1202 | (col->usage & 0xffff) < ARRAY_SIZE(types)) { | 1202 | (col->usage & 0xffff) < ARRAY_SIZE(types)) { |
1203 | type = types[col->usage & 0xffff]; | 1203 | type = types[col->usage & 0xffff]; |
1204 | break; | 1204 | break; |
1205 | } | 1205 | } |
1206 | } | 1206 | } |
1207 | 1207 | ||
1208 | switch (hdev->bus) { | 1208 | switch (hdev->bus) { |
1209 | case BUS_USB: | 1209 | case BUS_USB: |
1210 | bus = "USB"; | 1210 | bus = "USB"; |
1211 | break; | 1211 | break; |
1212 | case BUS_BLUETOOTH: | 1212 | case BUS_BLUETOOTH: |
1213 | bus = "BLUETOOTH"; | 1213 | bus = "BLUETOOTH"; |
1214 | break; | 1214 | break; |
1215 | default: | 1215 | default: |
1216 | bus = "<UNKNOWN>"; | 1216 | bus = "<UNKNOWN>"; |
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", | 1219 | dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", |
1220 | buf, bus, hdev->version >> 8, hdev->version & 0xff, | 1220 | buf, bus, hdev->version >> 8, hdev->version & 0xff, |
1221 | type, hdev->name, hdev->phys); | 1221 | type, hdev->name, hdev->phys); |
1222 | 1222 | ||
1223 | return 0; | 1223 | return 0; |
1224 | } | 1224 | } |
1225 | EXPORT_SYMBOL_GPL(hid_connect); | 1225 | EXPORT_SYMBOL_GPL(hid_connect); |
1226 | 1226 | ||
1227 | void hid_disconnect(struct hid_device *hdev) | 1227 | void hid_disconnect(struct hid_device *hdev) |
1228 | { | 1228 | { |
1229 | if (hdev->claimed & HID_CLAIMED_INPUT) | 1229 | if (hdev->claimed & HID_CLAIMED_INPUT) |
1230 | hidinput_disconnect(hdev); | 1230 | hidinput_disconnect(hdev); |
1231 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | 1231 | if (hdev->claimed & HID_CLAIMED_HIDDEV) |
1232 | hdev->hiddev_disconnect(hdev); | 1232 | hdev->hiddev_disconnect(hdev); |
1233 | if (hdev->claimed & HID_CLAIMED_HIDRAW) | 1233 | if (hdev->claimed & HID_CLAIMED_HIDRAW) |
1234 | hidraw_disconnect(hdev); | 1234 | hidraw_disconnect(hdev); |
1235 | } | 1235 | } |
1236 | EXPORT_SYMBOL_GPL(hid_disconnect); | 1236 | EXPORT_SYMBOL_GPL(hid_disconnect); |
1237 | 1237 | ||
1238 | /* a list of devices for which there is a specialized driver on HID bus */ | 1238 | /* a list of devices for which there is a specialized driver on HID bus */ |
1239 | static const struct hid_device_id hid_blacklist[] = { | 1239 | static const struct hid_device_id hid_blacklist[] = { |
1240 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, | 1240 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, |
1241 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, | 1241 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, |
1242 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1242 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
1243 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1243 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
1244 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, | 1244 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, |
1245 | #if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE) | 1245 | #if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE) |
1246 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, | 1246 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, |
1247 | #endif | 1247 | #endif |
1248 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | 1248 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, |
1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
1251 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, | 1251 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, |
1252 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, | ||
1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, | 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, |
1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, | 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, |
1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, | 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, |
1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, | 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, |
1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, | 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, |
1258 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, | 1259 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, |
1259 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, | 1260 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, |
1260 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, | 1261 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, |
1261 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, | 1262 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, |
1262 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, | 1263 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, |
1263 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) }, | 1264 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) }, |
1264 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) }, | 1265 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) }, |
1265 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) }, | 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) }, |
1266 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) }, | 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) }, |
1267 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) }, | 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) }, |
1268 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) }, | 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) }, |
1269 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
1270 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
1271 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1272 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
1272 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, | 1273 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, |
1273 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, | 1274 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, |
1274 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, | 1275 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, |
1275 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, | 1276 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, |
1276 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, | 1277 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, |
1277 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, | 1278 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, |
1278 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1279 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
1279 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1280 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
1280 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1281 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
1281 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | 1282 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, |
1282 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | 1283 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, |
1283 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | 1284 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, |
1284 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, | 1285 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, |
1285 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, | 1286 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, |
1286 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1287 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1288 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1289 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | 1290 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, |
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | 1291 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, |
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1292 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1293 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | 1294 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, |
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
1295 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 1296 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
1296 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 1297 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
1297 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1298 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
1298 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, |
1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
1300 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, | 1301 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, |
1301 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, | 1302 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, |
1302 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, | 1303 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, |
1303 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, | 1304 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, |
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1305 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1305 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1306 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1306 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1307 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1307 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 1308 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, |
1308 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1309 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1309 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1310 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1310 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1311 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1311 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1312 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1312 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1313 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1313 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1314 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1314 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1315 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1315 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1316 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1316 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1317 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
1317 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1318 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1318 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1319 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
1319 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1320 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1320 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1321 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
1321 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, | 1322 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, |
1322 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1323 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
1323 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, | 1324 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, |
1324 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, | 1325 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, |
1325 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, | 1326 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, |
1326 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, | 1327 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, |
1327 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, | 1328 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, |
1328 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, | 1329 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, |
1329 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, | 1330 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, |
1330 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, | 1331 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, |
1332 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, | ||
1331 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, | 1333 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, |
1332 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, | 1334 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, |
1333 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, | 1335 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, |
1334 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, | 1336 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, |
1335 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, | 1337 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, |
1336 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) }, | 1338 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) }, |
1337 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, | 1339 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, |
1338 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, | 1340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, |
1339 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, | 1341 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, |
1342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, | ||
1340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, | 1343 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, |
1341 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, | 1344 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, |
1342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, | 1345 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, |
1343 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, | 1346 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, |
1344 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, | 1347 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, |
1345 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1348 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
1346 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, | 1349 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, |
1347 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, | 1350 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, |
1348 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1351 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
1349 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1352 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1350 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1353 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1351 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1354 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
1352 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, | 1355 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, |
1353 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, | 1356 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, |
1354 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3) }, | 1357 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3) }, |
1355 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4) }, | 1358 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4) }, |
1356 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5) }, | 1359 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5) }, |
1357 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6) }, | 1360 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6) }, |
1358 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7) }, | 1361 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7) }, |
1359 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8) }, | 1362 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8) }, |
1360 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9) }, | 1363 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9) }, |
1361 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10) }, | 1364 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10) }, |
1362 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11) }, | 1365 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11) }, |
1363 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12) }, | 1366 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12) }, |
1364 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13) }, | 1367 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13) }, |
1365 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14) }, | 1368 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14) }, |
1366 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15) }, | 1369 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15) }, |
1367 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) }, | 1370 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) }, |
1368 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) }, | 1371 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) }, |
1369 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, | 1372 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, |
1370 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1373 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1371 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1374 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1372 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, | 1375 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, |
1373 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, | 1376 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, |
1374 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, | 1377 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, |
1378 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, | ||
1375 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 1379 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
1376 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, | 1380 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, |
1377 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1381 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1378 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1382 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1379 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1383 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
1380 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | 1384 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, |
1381 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, | 1385 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, |
1382 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, | 1386 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, |
1383 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1387 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1384 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1388 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
1385 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1389 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
1386 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, | 1390 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, |
1387 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) }, | 1391 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) }, |
1388 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, | 1392 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, |
1389 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, | 1393 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, |
1390 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, | 1394 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, |
1391 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1395 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1392 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 1396 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
1393 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, | 1397 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
1394 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, | 1398 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, |
1395 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, | 1399 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, |
1396 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, | 1400 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, |
1397 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, | 1401 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, |
1398 | { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, | 1402 | { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, |
1399 | 1403 | ||
1400 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, | 1404 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, |
1401 | { } | 1405 | { } |
1402 | }; | 1406 | }; |
1403 | 1407 | ||
1404 | struct hid_dynid { | 1408 | struct hid_dynid { |
1405 | struct list_head list; | 1409 | struct list_head list; |
1406 | struct hid_device_id id; | 1410 | struct hid_device_id id; |
1407 | }; | 1411 | }; |
1408 | 1412 | ||
1409 | /** | 1413 | /** |
1410 | * store_new_id - add a new HID device ID to this driver and re-probe devices | 1414 | * store_new_id - add a new HID device ID to this driver and re-probe devices |
1411 | * @driver: target device driver | 1415 | * @driver: target device driver |
1412 | * @buf: buffer for scanning device ID data | 1416 | * @buf: buffer for scanning device ID data |
1413 | * @count: input size | 1417 | * @count: input size |
1414 | * | 1418 | * |
1415 | * Adds a new dynamic hid device ID to this driver, | 1419 | * Adds a new dynamic hid device ID to this driver, |
1416 | * and causes the driver to probe for all devices again. | 1420 | * and causes the driver to probe for all devices again. |
1417 | */ | 1421 | */ |
1418 | static ssize_t store_new_id(struct device_driver *drv, const char *buf, | 1422 | static ssize_t store_new_id(struct device_driver *drv, const char *buf, |
1419 | size_t count) | 1423 | size_t count) |
1420 | { | 1424 | { |
1421 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1425 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1422 | struct hid_dynid *dynid; | 1426 | struct hid_dynid *dynid; |
1423 | __u32 bus, vendor, product; | 1427 | __u32 bus, vendor, product; |
1424 | unsigned long driver_data = 0; | 1428 | unsigned long driver_data = 0; |
1425 | int ret; | 1429 | int ret; |
1426 | 1430 | ||
1427 | ret = sscanf(buf, "%x %x %x %lx", | 1431 | ret = sscanf(buf, "%x %x %x %lx", |
1428 | &bus, &vendor, &product, &driver_data); | 1432 | &bus, &vendor, &product, &driver_data); |
1429 | if (ret < 3) | 1433 | if (ret < 3) |
1430 | return -EINVAL; | 1434 | return -EINVAL; |
1431 | 1435 | ||
1432 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | 1436 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); |
1433 | if (!dynid) | 1437 | if (!dynid) |
1434 | return -ENOMEM; | 1438 | return -ENOMEM; |
1435 | 1439 | ||
1436 | dynid->id.bus = bus; | 1440 | dynid->id.bus = bus; |
1437 | dynid->id.vendor = vendor; | 1441 | dynid->id.vendor = vendor; |
1438 | dynid->id.product = product; | 1442 | dynid->id.product = product; |
1439 | dynid->id.driver_data = driver_data; | 1443 | dynid->id.driver_data = driver_data; |
1440 | 1444 | ||
1441 | spin_lock(&hdrv->dyn_lock); | 1445 | spin_lock(&hdrv->dyn_lock); |
1442 | list_add_tail(&dynid->list, &hdrv->dyn_list); | 1446 | list_add_tail(&dynid->list, &hdrv->dyn_list); |
1443 | spin_unlock(&hdrv->dyn_lock); | 1447 | spin_unlock(&hdrv->dyn_lock); |
1444 | 1448 | ||
1445 | ret = 0; | 1449 | ret = 0; |
1446 | if (get_driver(&hdrv->driver)) { | 1450 | if (get_driver(&hdrv->driver)) { |
1447 | ret = driver_attach(&hdrv->driver); | 1451 | ret = driver_attach(&hdrv->driver); |
1448 | put_driver(&hdrv->driver); | 1452 | put_driver(&hdrv->driver); |
1449 | } | 1453 | } |
1450 | 1454 | ||
1451 | return ret ? : count; | 1455 | return ret ? : count; |
1452 | } | 1456 | } |
1453 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | 1457 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); |
1454 | 1458 | ||
1455 | static void hid_free_dynids(struct hid_driver *hdrv) | 1459 | static void hid_free_dynids(struct hid_driver *hdrv) |
1456 | { | 1460 | { |
1457 | struct hid_dynid *dynid, *n; | 1461 | struct hid_dynid *dynid, *n; |
1458 | 1462 | ||
1459 | spin_lock(&hdrv->dyn_lock); | 1463 | spin_lock(&hdrv->dyn_lock); |
1460 | list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) { | 1464 | list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) { |
1461 | list_del(&dynid->list); | 1465 | list_del(&dynid->list); |
1462 | kfree(dynid); | 1466 | kfree(dynid); |
1463 | } | 1467 | } |
1464 | spin_unlock(&hdrv->dyn_lock); | 1468 | spin_unlock(&hdrv->dyn_lock); |
1465 | } | 1469 | } |
1466 | 1470 | ||
1467 | static const struct hid_device_id *hid_match_device(struct hid_device *hdev, | 1471 | static const struct hid_device_id *hid_match_device(struct hid_device *hdev, |
1468 | struct hid_driver *hdrv) | 1472 | struct hid_driver *hdrv) |
1469 | { | 1473 | { |
1470 | struct hid_dynid *dynid; | 1474 | struct hid_dynid *dynid; |
1471 | 1475 | ||
1472 | spin_lock(&hdrv->dyn_lock); | 1476 | spin_lock(&hdrv->dyn_lock); |
1473 | list_for_each_entry(dynid, &hdrv->dyn_list, list) { | 1477 | list_for_each_entry(dynid, &hdrv->dyn_list, list) { |
1474 | if (hid_match_one_id(hdev, &dynid->id)) { | 1478 | if (hid_match_one_id(hdev, &dynid->id)) { |
1475 | spin_unlock(&hdrv->dyn_lock); | 1479 | spin_unlock(&hdrv->dyn_lock); |
1476 | return &dynid->id; | 1480 | return &dynid->id; |
1477 | } | 1481 | } |
1478 | } | 1482 | } |
1479 | spin_unlock(&hdrv->dyn_lock); | 1483 | spin_unlock(&hdrv->dyn_lock); |
1480 | 1484 | ||
1481 | return hid_match_id(hdev, hdrv->id_table); | 1485 | return hid_match_id(hdev, hdrv->id_table); |
1482 | } | 1486 | } |
1483 | 1487 | ||
1484 | static int hid_bus_match(struct device *dev, struct device_driver *drv) | 1488 | static int hid_bus_match(struct device *dev, struct device_driver *drv) |
1485 | { | 1489 | { |
1486 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1490 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1487 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1491 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1488 | 1492 | ||
1489 | if (!hid_match_device(hdev, hdrv)) | 1493 | if (!hid_match_device(hdev, hdrv)) |
1490 | return 0; | 1494 | return 0; |
1491 | 1495 | ||
1492 | /* generic wants all non-blacklisted */ | 1496 | /* generic wants all non-blacklisted */ |
1493 | if (!strncmp(hdrv->name, "generic-", 8)) | 1497 | if (!strncmp(hdrv->name, "generic-", 8)) |
1494 | return !hid_match_id(hdev, hid_blacklist); | 1498 | return !hid_match_id(hdev, hid_blacklist); |
1495 | 1499 | ||
1496 | return 1; | 1500 | return 1; |
1497 | } | 1501 | } |
1498 | 1502 | ||
1499 | static int hid_device_probe(struct device *dev) | 1503 | static int hid_device_probe(struct device *dev) |
1500 | { | 1504 | { |
1501 | struct hid_driver *hdrv = container_of(dev->driver, | 1505 | struct hid_driver *hdrv = container_of(dev->driver, |
1502 | struct hid_driver, driver); | 1506 | struct hid_driver, driver); |
1503 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1507 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1504 | const struct hid_device_id *id; | 1508 | const struct hid_device_id *id; |
1505 | int ret = 0; | 1509 | int ret = 0; |
1506 | 1510 | ||
1507 | if (!hdev->driver) { | 1511 | if (!hdev->driver) { |
1508 | id = hid_match_device(hdev, hdrv); | 1512 | id = hid_match_device(hdev, hdrv); |
1509 | if (id == NULL) | 1513 | if (id == NULL) |
1510 | return -ENODEV; | 1514 | return -ENODEV; |
1511 | 1515 | ||
1512 | hdev->driver = hdrv; | 1516 | hdev->driver = hdrv; |
1513 | if (hdrv->probe) { | 1517 | if (hdrv->probe) { |
1514 | ret = hdrv->probe(hdev, id); | 1518 | ret = hdrv->probe(hdev, id); |
1515 | } else { /* default probe */ | 1519 | } else { /* default probe */ |
1516 | ret = hid_parse(hdev); | 1520 | ret = hid_parse(hdev); |
1517 | if (!ret) | 1521 | if (!ret) |
1518 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 1522 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
1519 | } | 1523 | } |
1520 | if (ret) | 1524 | if (ret) |
1521 | hdev->driver = NULL; | 1525 | hdev->driver = NULL; |
1522 | } | 1526 | } |
1523 | return ret; | 1527 | return ret; |
1524 | } | 1528 | } |
1525 | 1529 | ||
1526 | static int hid_device_remove(struct device *dev) | 1530 | static int hid_device_remove(struct device *dev) |
1527 | { | 1531 | { |
1528 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1532 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1529 | struct hid_driver *hdrv = hdev->driver; | 1533 | struct hid_driver *hdrv = hdev->driver; |
1530 | 1534 | ||
1531 | if (hdrv) { | 1535 | if (hdrv) { |
1532 | if (hdrv->remove) | 1536 | if (hdrv->remove) |
1533 | hdrv->remove(hdev); | 1537 | hdrv->remove(hdev); |
1534 | else /* default remove */ | 1538 | else /* default remove */ |
1535 | hid_hw_stop(hdev); | 1539 | hid_hw_stop(hdev); |
1536 | hdev->driver = NULL; | 1540 | hdev->driver = NULL; |
1537 | } | 1541 | } |
1538 | 1542 | ||
1539 | return 0; | 1543 | return 0; |
1540 | } | 1544 | } |
1541 | 1545 | ||
1542 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | 1546 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) |
1543 | { | 1547 | { |
1544 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1548 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1545 | 1549 | ||
1546 | if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", | 1550 | if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", |
1547 | hdev->bus, hdev->vendor, hdev->product)) | 1551 | hdev->bus, hdev->vendor, hdev->product)) |
1548 | return -ENOMEM; | 1552 | return -ENOMEM; |
1549 | 1553 | ||
1550 | if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) | 1554 | if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) |
1551 | return -ENOMEM; | 1555 | return -ENOMEM; |
1552 | 1556 | ||
1553 | if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) | 1557 | if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) |
1554 | return -ENOMEM; | 1558 | return -ENOMEM; |
1555 | 1559 | ||
1556 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) | 1560 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) |
1557 | return -ENOMEM; | 1561 | return -ENOMEM; |
1558 | 1562 | ||
1559 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", | 1563 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", |
1560 | hdev->bus, hdev->vendor, hdev->product)) | 1564 | hdev->bus, hdev->vendor, hdev->product)) |
1561 | return -ENOMEM; | 1565 | return -ENOMEM; |
1562 | 1566 | ||
1563 | return 0; | 1567 | return 0; |
1564 | } | 1568 | } |
1565 | 1569 | ||
1566 | static struct bus_type hid_bus_type = { | 1570 | static struct bus_type hid_bus_type = { |
1567 | .name = "hid", | 1571 | .name = "hid", |
1568 | .match = hid_bus_match, | 1572 | .match = hid_bus_match, |
1569 | .probe = hid_device_probe, | 1573 | .probe = hid_device_probe, |
1570 | .remove = hid_device_remove, | 1574 | .remove = hid_device_remove, |
1571 | .uevent = hid_uevent, | 1575 | .uevent = hid_uevent, |
1572 | }; | 1576 | }; |
1573 | 1577 | ||
1574 | /* a list of devices that shouldn't be handled by HID core at all */ | 1578 | /* a list of devices that shouldn't be handled by HID core at all */ |
1575 | static const struct hid_device_id hid_ignore_list[] = { | 1579 | static const struct hid_device_id hid_ignore_list[] = { |
1576 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, | 1580 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, |
1577 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, | 1581 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, |
1578 | { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, | 1582 | { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, |
1579 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, | 1583 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, |
1580 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, | 1584 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, |
1581 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, | 1585 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, |
1582 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, | 1586 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, |
1583 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, | 1587 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, |
1584 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, | 1588 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, |
1585 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, | 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, |
1586 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, | 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, |
1587 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
1588 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, | 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, |
1589 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, | 1593 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, |
1590 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | 1594 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, |
1591 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, | 1595 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, |
1592 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, | 1596 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, |
1593 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, | 1597 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, |
1594 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, | 1598 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, |
1595 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, | 1599 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, |
1596 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, | 1600 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, |
1597 | { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, | 1601 | { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, |
1598 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, | 1602 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, |
1599 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, | 1603 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, |
1600 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1604 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
1601 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, | 1605 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, |
1602 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, | 1606 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, |
1603 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | 1607 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, |
1604 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1608 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
1605 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | 1609 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, |
1606 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, | 1610 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, |
1607 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, | 1611 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, |
1608 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, | 1612 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, |
1609 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, | 1613 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, |
1610 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, | 1614 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, |
1611 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, | 1615 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, |
1612 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, | 1616 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, |
1613 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, | 1617 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, |
1614 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, | 1618 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, |
1615 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, | 1619 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, |
1616 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, | 1620 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, |
1617 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, | 1621 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, |
1618 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, | 1622 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, |
1619 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, | 1623 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, |
1620 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, | 1624 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, |
1621 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, | 1625 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, |
1622 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, | 1626 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, |
1623 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, | 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, |
1624 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, | 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, |
1625 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, | 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, |
1626 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, | 1630 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, |
1627 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, | 1631 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, |
1628 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, | 1632 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, |
1629 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, | 1633 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, |
1630 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, | 1634 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, |
1631 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, | 1635 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, |
1632 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, | 1636 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, |
1633 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, | 1637 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, |
1634 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, | 1638 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, |
1635 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, | 1639 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, |
1636 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, | 1640 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, |
1637 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, | 1641 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, |
1638 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, | 1642 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, |
1639 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, | 1643 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, |
1640 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, | 1644 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, |
1641 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, | 1645 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, |
1642 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, | 1646 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, |
1643 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, | 1647 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, |
1644 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, | 1648 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, |
1645 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, | 1649 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, |
1646 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, | 1650 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, |
1647 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, | 1651 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, |
1648 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, | 1652 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, |
1649 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, | 1653 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, |
1650 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, | 1654 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, |
1651 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, | 1655 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, |
1652 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, | 1656 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, |
1653 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, | 1657 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, |
1654 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, | 1658 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, |
1655 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, | 1659 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, |
1656 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, | 1660 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, |
1657 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, | 1661 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, |
1658 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, | 1662 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, |
1659 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, | 1663 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, |
1660 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, | 1664 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, |
1661 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, | 1665 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, |
1662 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, | 1666 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, |
1663 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, | 1667 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, |
1664 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, | 1668 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, |
1665 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, | 1669 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, |
1666 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 1670 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
1667 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 1671 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
1668 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) }, | 1672 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) }, |
1669 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 1673 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
1670 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | 1674 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, |
1671 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 1675 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
1672 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) }, | 1676 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) }, |
1673 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, | 1677 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
1674 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, | 1678 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, |
1675 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, | 1679 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, |
1676 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, | 1680 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, |
1677 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, | 1681 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, |
1678 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, | 1682 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, |
1679 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, | 1683 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, |
1680 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, | 1684 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, |
1681 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, | 1685 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, |
1682 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, | 1686 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, |
1683 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, | 1687 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, |
1684 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, | 1688 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, |
1685 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, | 1689 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, |
1686 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, | 1690 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, |
1687 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, | 1691 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, |
1688 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, | 1692 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, |
1689 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, | 1693 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, |
1690 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, | 1694 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, |
1691 | { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, | 1695 | { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, |
1692 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, | 1696 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, |
1693 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, | 1697 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, |
1694 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, | 1698 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, |
1695 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, | 1699 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, |
1696 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, | 1700 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, |
1697 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, | 1701 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, |
1698 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, | 1702 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, |
1699 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, | 1703 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, |
1700 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, | 1704 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, |
1701 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, | 1705 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, |
1702 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, | 1706 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, |
1703 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, | 1707 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, |
1704 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, | 1708 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, |
1705 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, | 1709 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, |
1706 | { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, | 1710 | { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, |
1707 | { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, | 1711 | { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, |
1708 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | 1712 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, |
1709 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 1713 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
1710 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 1714 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
1711 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | 1715 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, |
1712 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, | 1716 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, |
1713 | { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, | 1717 | { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, |
1714 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, | 1718 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, |
1715 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, | 1719 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, |
1716 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, | 1720 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, |
1717 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, | 1721 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, |
1718 | { } | 1722 | { } |
1719 | }; | 1723 | }; |
1720 | 1724 | ||
1721 | /** | 1725 | /** |
1722 | * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer | 1726 | * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer |
1723 | * | 1727 | * |
1724 | * There are composite devices for which we want to ignore only a certain | 1728 | * There are composite devices for which we want to ignore only a certain |
1725 | * interface. This is a list of devices for which only the mouse interface will | 1729 | * interface. This is a list of devices for which only the mouse interface will |
1726 | * be ignored. This allows a dedicated driver to take care of the interface. | 1730 | * be ignored. This allows a dedicated driver to take care of the interface. |
1727 | */ | 1731 | */ |
1728 | static const struct hid_device_id hid_mouse_ignore_list[] = { | 1732 | static const struct hid_device_id hid_mouse_ignore_list[] = { |
1729 | /* appletouch driver */ | 1733 | /* appletouch driver */ |
1730 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1734 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
1731 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, | 1735 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, |
1732 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, | 1736 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, |
1733 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, | 1737 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, |
1734 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, | 1738 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, |
1735 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, | 1739 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, |
1736 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, | 1740 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, |
1737 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, | 1741 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, |
1738 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, | 1742 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, |
1739 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, | 1743 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, |
1740 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, | 1744 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, |
1741 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1745 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
1742 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1746 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
1743 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1747 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
1744 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, | 1748 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, |
1745 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, | 1749 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, |
1746 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, | 1750 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, |
1747 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1751 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
1748 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1752 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
1749 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1753 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
1750 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | 1754 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, |
1751 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | 1755 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, |
1752 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | 1756 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, |
1753 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1757 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1754 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1758 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1755 | { } | 1759 | { } |
1756 | }; | 1760 | }; |
1757 | 1761 | ||
1758 | static bool hid_ignore(struct hid_device *hdev) | 1762 | static bool hid_ignore(struct hid_device *hdev) |
1759 | { | 1763 | { |
1760 | switch (hdev->vendor) { | 1764 | switch (hdev->vendor) { |
1761 | case USB_VENDOR_ID_CODEMERCS: | 1765 | case USB_VENDOR_ID_CODEMERCS: |
1762 | /* ignore all Code Mercenaries IOWarrior devices */ | 1766 | /* ignore all Code Mercenaries IOWarrior devices */ |
1763 | if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && | 1767 | if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && |
1764 | hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) | 1768 | hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) |
1765 | return true; | 1769 | return true; |
1766 | break; | 1770 | break; |
1767 | case USB_VENDOR_ID_LOGITECH: | 1771 | case USB_VENDOR_ID_LOGITECH: |
1768 | if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && | 1772 | if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && |
1769 | hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) | 1773 | hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) |
1770 | return true; | 1774 | return true; |
1771 | break; | 1775 | break; |
1772 | case USB_VENDOR_ID_SOUNDGRAPH: | 1776 | case USB_VENDOR_ID_SOUNDGRAPH: |
1773 | if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST && | 1777 | if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST && |
1774 | hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) | 1778 | hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) |
1775 | return true; | 1779 | return true; |
1776 | break; | 1780 | break; |
1777 | } | 1781 | } |
1778 | 1782 | ||
1779 | if (hdev->type == HID_TYPE_USBMOUSE && | 1783 | if (hdev->type == HID_TYPE_USBMOUSE && |
1780 | hid_match_id(hdev, hid_mouse_ignore_list)) | 1784 | hid_match_id(hdev, hid_mouse_ignore_list)) |
1781 | return true; | 1785 | return true; |
1782 | 1786 | ||
1783 | return !!hid_match_id(hdev, hid_ignore_list); | 1787 | return !!hid_match_id(hdev, hid_ignore_list); |
1784 | } | 1788 | } |
1785 | 1789 | ||
1786 | int hid_add_device(struct hid_device *hdev) | 1790 | int hid_add_device(struct hid_device *hdev) |
1787 | { | 1791 | { |
1788 | static atomic_t id = ATOMIC_INIT(0); | 1792 | static atomic_t id = ATOMIC_INIT(0); |
1789 | int ret; | 1793 | int ret; |
1790 | 1794 | ||
1791 | if (WARN_ON(hdev->status & HID_STAT_ADDED)) | 1795 | if (WARN_ON(hdev->status & HID_STAT_ADDED)) |
1792 | return -EBUSY; | 1796 | return -EBUSY; |
1793 | 1797 | ||
1794 | /* we need to kill them here, otherwise they will stay allocated to | 1798 | /* we need to kill them here, otherwise they will stay allocated to |
1795 | * wait for coming driver */ | 1799 | * wait for coming driver */ |
1796 | if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) | 1800 | if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) |
1797 | && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) | 1801 | && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) |
1798 | return -ENODEV; | 1802 | return -ENODEV; |
1799 | 1803 | ||
1800 | /* XXX hack, any other cleaner solution after the driver core | 1804 | /* XXX hack, any other cleaner solution after the driver core |
1801 | * is converted to allow more than 20 bytes as the device name? */ | 1805 | * is converted to allow more than 20 bytes as the device name? */ |
1802 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, | 1806 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, |
1803 | hdev->vendor, hdev->product, atomic_inc_return(&id)); | 1807 | hdev->vendor, hdev->product, atomic_inc_return(&id)); |
1804 | 1808 | ||
1805 | hid_debug_register(hdev, dev_name(&hdev->dev)); | 1809 | hid_debug_register(hdev, dev_name(&hdev->dev)); |
1806 | ret = device_add(&hdev->dev); | 1810 | ret = device_add(&hdev->dev); |
1807 | if (!ret) | 1811 | if (!ret) |
1808 | hdev->status |= HID_STAT_ADDED; | 1812 | hdev->status |= HID_STAT_ADDED; |
1809 | else | 1813 | else |
1810 | hid_debug_unregister(hdev); | 1814 | hid_debug_unregister(hdev); |
1811 | 1815 | ||
1812 | return ret; | 1816 | return ret; |
1813 | } | 1817 | } |
1814 | EXPORT_SYMBOL_GPL(hid_add_device); | 1818 | EXPORT_SYMBOL_GPL(hid_add_device); |
1815 | 1819 | ||
1816 | /** | 1820 | /** |
1817 | * hid_allocate_device - allocate new hid device descriptor | 1821 | * hid_allocate_device - allocate new hid device descriptor |
1818 | * | 1822 | * |
1819 | * Allocate and initialize hid device, so that hid_destroy_device might be | 1823 | * Allocate and initialize hid device, so that hid_destroy_device might be |
1820 | * used to free it. | 1824 | * used to free it. |
1821 | * | 1825 | * |
1822 | * New hid_device pointer is returned on success, otherwise ERR_PTR encoded | 1826 | * New hid_device pointer is returned on success, otherwise ERR_PTR encoded |
1823 | * error value. | 1827 | * error value. |
1824 | */ | 1828 | */ |
1825 | struct hid_device *hid_allocate_device(void) | 1829 | struct hid_device *hid_allocate_device(void) |
1826 | { | 1830 | { |
1827 | struct hid_device *hdev; | 1831 | struct hid_device *hdev; |
1828 | unsigned int i; | 1832 | unsigned int i; |
1829 | int ret = -ENOMEM; | 1833 | int ret = -ENOMEM; |
1830 | 1834 | ||
1831 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); | 1835 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); |
1832 | if (hdev == NULL) | 1836 | if (hdev == NULL) |
1833 | return ERR_PTR(ret); | 1837 | return ERR_PTR(ret); |
1834 | 1838 | ||
1835 | device_initialize(&hdev->dev); | 1839 | device_initialize(&hdev->dev); |
1836 | hdev->dev.release = hid_device_release; | 1840 | hdev->dev.release = hid_device_release; |
1837 | hdev->dev.bus = &hid_bus_type; | 1841 | hdev->dev.bus = &hid_bus_type; |
1838 | 1842 | ||
1839 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, | 1843 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, |
1840 | sizeof(struct hid_collection), GFP_KERNEL); | 1844 | sizeof(struct hid_collection), GFP_KERNEL); |
1841 | if (hdev->collection == NULL) | 1845 | if (hdev->collection == NULL) |
1842 | goto err; | 1846 | goto err; |
1843 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | 1847 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; |
1844 | 1848 | ||
1845 | for (i = 0; i < HID_REPORT_TYPES; i++) | 1849 | for (i = 0; i < HID_REPORT_TYPES; i++) |
1846 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); | 1850 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); |
1847 | 1851 | ||
1848 | init_waitqueue_head(&hdev->debug_wait); | 1852 | init_waitqueue_head(&hdev->debug_wait); |
1849 | INIT_LIST_HEAD(&hdev->debug_list); | 1853 | INIT_LIST_HEAD(&hdev->debug_list); |
1850 | 1854 | ||
1851 | return hdev; | 1855 | return hdev; |
1852 | err: | 1856 | err: |
1853 | put_device(&hdev->dev); | 1857 | put_device(&hdev->dev); |
1854 | return ERR_PTR(ret); | 1858 | return ERR_PTR(ret); |
1855 | } | 1859 | } |
1856 | EXPORT_SYMBOL_GPL(hid_allocate_device); | 1860 | EXPORT_SYMBOL_GPL(hid_allocate_device); |
1857 | 1861 | ||
1858 | static void hid_remove_device(struct hid_device *hdev) | 1862 | static void hid_remove_device(struct hid_device *hdev) |
1859 | { | 1863 | { |
1860 | if (hdev->status & HID_STAT_ADDED) { | 1864 | if (hdev->status & HID_STAT_ADDED) { |
1861 | device_del(&hdev->dev); | 1865 | device_del(&hdev->dev); |
1862 | hid_debug_unregister(hdev); | 1866 | hid_debug_unregister(hdev); |
1863 | hdev->status &= ~HID_STAT_ADDED; | 1867 | hdev->status &= ~HID_STAT_ADDED; |
1864 | } | 1868 | } |
1865 | } | 1869 | } |
1866 | 1870 | ||
1867 | /** | 1871 | /** |
1868 | * hid_destroy_device - free previously allocated device | 1872 | * hid_destroy_device - free previously allocated device |
1869 | * | 1873 | * |
1870 | * @hdev: hid device | 1874 | * @hdev: hid device |
1871 | * | 1875 | * |
1872 | * If you allocate hid_device through hid_allocate_device, you should ever | 1876 | * If you allocate hid_device through hid_allocate_device, you should ever |
1873 | * free by this function. | 1877 | * free by this function. |
1874 | */ | 1878 | */ |
1875 | void hid_destroy_device(struct hid_device *hdev) | 1879 | void hid_destroy_device(struct hid_device *hdev) |
1876 | { | 1880 | { |
1877 | hid_remove_device(hdev); | 1881 | hid_remove_device(hdev); |
1878 | put_device(&hdev->dev); | 1882 | put_device(&hdev->dev); |
1879 | } | 1883 | } |
1880 | EXPORT_SYMBOL_GPL(hid_destroy_device); | 1884 | EXPORT_SYMBOL_GPL(hid_destroy_device); |
1881 | 1885 | ||
1882 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, | 1886 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, |
1883 | const char *mod_name) | 1887 | const char *mod_name) |
1884 | { | 1888 | { |
1885 | int ret; | 1889 | int ret; |
1886 | 1890 | ||
1887 | hdrv->driver.name = hdrv->name; | 1891 | hdrv->driver.name = hdrv->name; |
1888 | hdrv->driver.bus = &hid_bus_type; | 1892 | hdrv->driver.bus = &hid_bus_type; |
1889 | hdrv->driver.owner = owner; | 1893 | hdrv->driver.owner = owner; |
1890 | hdrv->driver.mod_name = mod_name; | 1894 | hdrv->driver.mod_name = mod_name; |
1891 | 1895 | ||
1892 | INIT_LIST_HEAD(&hdrv->dyn_list); | 1896 | INIT_LIST_HEAD(&hdrv->dyn_list); |
1893 | spin_lock_init(&hdrv->dyn_lock); | 1897 | spin_lock_init(&hdrv->dyn_lock); |
1894 | 1898 | ||
1895 | ret = driver_register(&hdrv->driver); | 1899 | ret = driver_register(&hdrv->driver); |
1896 | if (ret) | 1900 | if (ret) |
1897 | return ret; | 1901 | return ret; |
1898 | 1902 | ||
1899 | ret = driver_create_file(&hdrv->driver, &driver_attr_new_id); | 1903 | ret = driver_create_file(&hdrv->driver, &driver_attr_new_id); |
1900 | if (ret) | 1904 | if (ret) |
1901 | driver_unregister(&hdrv->driver); | 1905 | driver_unregister(&hdrv->driver); |
1902 | 1906 | ||
1903 | return ret; | 1907 | return ret; |
1904 | } | 1908 | } |
1905 | EXPORT_SYMBOL_GPL(__hid_register_driver); | 1909 | EXPORT_SYMBOL_GPL(__hid_register_driver); |
1906 | 1910 | ||
1907 | void hid_unregister_driver(struct hid_driver *hdrv) | 1911 | void hid_unregister_driver(struct hid_driver *hdrv) |
1908 | { | 1912 | { |
1909 | driver_remove_file(&hdrv->driver, &driver_attr_new_id); | 1913 | driver_remove_file(&hdrv->driver, &driver_attr_new_id); |
1910 | driver_unregister(&hdrv->driver); | 1914 | driver_unregister(&hdrv->driver); |
1911 | hid_free_dynids(hdrv); | 1915 | hid_free_dynids(hdrv); |
1912 | } | 1916 | } |
1913 | EXPORT_SYMBOL_GPL(hid_unregister_driver); | 1917 | EXPORT_SYMBOL_GPL(hid_unregister_driver); |
1914 | 1918 | ||
1915 | int hid_check_keys_pressed(struct hid_device *hid) | 1919 | int hid_check_keys_pressed(struct hid_device *hid) |
1916 | { | 1920 | { |
1917 | struct hid_input *hidinput; | 1921 | struct hid_input *hidinput; |
1918 | int i; | 1922 | int i; |
1919 | 1923 | ||
1920 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | 1924 | if (!(hid->claimed & HID_CLAIMED_INPUT)) |
1921 | return 0; | 1925 | return 0; |
1922 | 1926 | ||
1923 | list_for_each_entry(hidinput, &hid->inputs, list) { | 1927 | list_for_each_entry(hidinput, &hid->inputs, list) { |
1924 | for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++) | 1928 | for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++) |
1925 | if (hidinput->input->key[i]) | 1929 | if (hidinput->input->key[i]) |
1926 | return 1; | 1930 | return 1; |
1927 | } | 1931 | } |
1928 | 1932 | ||
1929 | return 0; | 1933 | return 0; |
1930 | } | 1934 | } |
1931 | 1935 | ||
1932 | EXPORT_SYMBOL_GPL(hid_check_keys_pressed); | 1936 | EXPORT_SYMBOL_GPL(hid_check_keys_pressed); |
1933 | 1937 | ||
1934 | static int __init hid_init(void) | 1938 | static int __init hid_init(void) |
1935 | { | 1939 | { |
1936 | int ret; | 1940 | int ret; |
1937 | 1941 | ||
1938 | if (hid_debug) | 1942 | if (hid_debug) |
1939 | printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n" | 1943 | printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n" |
1940 | "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n"); | 1944 | "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n"); |
1941 | 1945 | ||
1942 | ret = bus_register(&hid_bus_type); | 1946 | ret = bus_register(&hid_bus_type); |
1943 | if (ret) { | 1947 | if (ret) { |
1944 | printk(KERN_ERR "HID: can't register hid bus\n"); | 1948 | printk(KERN_ERR "HID: can't register hid bus\n"); |
1945 | goto err; | 1949 | goto err; |
1946 | } | 1950 | } |
1947 | 1951 | ||
1948 | ret = hidraw_init(); | 1952 | ret = hidraw_init(); |
1949 | if (ret) | 1953 | if (ret) |
1950 | goto err_bus; | 1954 | goto err_bus; |
1951 | 1955 | ||
1952 | hid_debug_init(); | 1956 | hid_debug_init(); |
1953 | 1957 | ||
1954 | return 0; | 1958 | return 0; |
1955 | err_bus: | 1959 | err_bus: |
1956 | bus_unregister(&hid_bus_type); | 1960 | bus_unregister(&hid_bus_type); |
1957 | err: | 1961 | err: |
1958 | return ret; | 1962 | return ret; |
1959 | } | 1963 | } |
1960 | 1964 | ||
1961 | static void __exit hid_exit(void) | 1965 | static void __exit hid_exit(void) |
1962 | { | 1966 | { |
1963 | hid_debug_exit(); | 1967 | hid_debug_exit(); |
1964 | hidraw_exit(); | 1968 | hidraw_exit(); |
1965 | bus_unregister(&hid_bus_type); | 1969 | bus_unregister(&hid_bus_type); |
1966 | } | 1970 | } |
1967 | 1971 | ||
1968 | module_init(hid_init); | 1972 | module_init(hid_init); |
1969 | module_exit(hid_exit); | 1973 | module_exit(hid_exit); |
1970 | 1974 | ||
1971 | MODULE_AUTHOR("Andreas Gal"); | 1975 | MODULE_AUTHOR("Andreas Gal"); |
1972 | MODULE_AUTHOR("Vojtech Pavlik"); | 1976 | MODULE_AUTHOR("Vojtech Pavlik"); |
1973 | MODULE_AUTHOR("Jiri Kosina"); | 1977 | MODULE_AUTHOR("Jiri Kosina"); |
1974 | MODULE_LICENSE(DRIVER_LICENSE); | 1978 | MODULE_LICENSE(DRIVER_LICENSE); |
1975 | 1979 | ||
1976 | 1980 |
drivers/hid/hid-egalax.c
1 | /* | 1 | /* |
2 | * HID driver for eGalax dual-touch panels | 2 | * HID driver for eGalax dual-touch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the Free | 10 | * under the terms of the GNU General Public License as published by the Free |
11 | * Software Foundation; either version 2 of the License, or (at your option) | 11 | * Software Foundation; either version 2 of the License, or (at your option) |
12 | * any later version. | 12 | * any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/hid.h> | 16 | #include <linux/hid.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/usb.h> | 18 | #include <linux/usb.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include "usbhid/usbhid.h" | 20 | #include "usbhid/usbhid.h" |
21 | 21 | ||
22 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | 22 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); |
23 | MODULE_DESCRIPTION("eGalax dual-touch panel"); | 23 | MODULE_DESCRIPTION("eGalax dual-touch panel"); |
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | 25 | ||
26 | #include "hid-ids.h" | 26 | #include "hid-ids.h" |
27 | 27 | ||
28 | struct egalax_data { | 28 | struct egalax_data { |
29 | __u16 x, y, z; | 29 | __u16 x, y, z; |
30 | __u8 id; | 30 | __u8 id; |
31 | bool first; /* is this the first finger in the frame? */ | 31 | bool first; /* is this the first finger in the frame? */ |
32 | bool valid; /* valid finger data, or just placeholder? */ | 32 | bool valid; /* valid finger data, or just placeholder? */ |
33 | bool activity; /* at least one active finger previously? */ | 33 | bool activity; /* at least one active finger previously? */ |
34 | __u16 lastx, lasty; /* latest valid (x, y) in the frame */ | 34 | __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */ |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
38 | struct hid_field *field, struct hid_usage *usage, | 38 | struct hid_field *field, struct hid_usage *usage, |
39 | unsigned long **bit, int *max) | 39 | unsigned long **bit, int *max) |
40 | { | 40 | { |
41 | switch (usage->hid & HID_USAGE_PAGE) { | 41 | switch (usage->hid & HID_USAGE_PAGE) { |
42 | 42 | ||
43 | case HID_UP_GENDESK: | 43 | case HID_UP_GENDESK: |
44 | switch (usage->hid) { | 44 | switch (usage->hid) { |
45 | case HID_GD_X: | 45 | case HID_GD_X: |
46 | hid_map_usage(hi, usage, bit, max, | 46 | hid_map_usage(hi, usage, bit, max, |
47 | EV_ABS, ABS_MT_POSITION_X); | 47 | EV_ABS, ABS_MT_POSITION_X); |
48 | /* touchscreen emulation */ | 48 | /* touchscreen emulation */ |
49 | input_set_abs_params(hi->input, ABS_X, | 49 | input_set_abs_params(hi->input, ABS_X, |
50 | field->logical_minimum, | 50 | field->logical_minimum, |
51 | field->logical_maximum, 0, 0); | 51 | field->logical_maximum, 0, 0); |
52 | return 1; | 52 | return 1; |
53 | case HID_GD_Y: | 53 | case HID_GD_Y: |
54 | hid_map_usage(hi, usage, bit, max, | 54 | hid_map_usage(hi, usage, bit, max, |
55 | EV_ABS, ABS_MT_POSITION_Y); | 55 | EV_ABS, ABS_MT_POSITION_Y); |
56 | /* touchscreen emulation */ | 56 | /* touchscreen emulation */ |
57 | input_set_abs_params(hi->input, ABS_Y, | 57 | input_set_abs_params(hi->input, ABS_Y, |
58 | field->logical_minimum, | 58 | field->logical_minimum, |
59 | field->logical_maximum, 0, 0); | 59 | field->logical_maximum, 0, 0); |
60 | return 1; | 60 | return 1; |
61 | } | 61 | } |
62 | return 0; | 62 | return 0; |
63 | 63 | ||
64 | case HID_UP_DIGITIZER: | 64 | case HID_UP_DIGITIZER: |
65 | switch (usage->hid) { | 65 | switch (usage->hid) { |
66 | case HID_DG_TIPSWITCH: | 66 | case HID_DG_TIPSWITCH: |
67 | /* touchscreen emulation */ | 67 | /* touchscreen emulation */ |
68 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 68 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
69 | return 1; | 69 | return 1; |
70 | case HID_DG_INRANGE: | 70 | case HID_DG_INRANGE: |
71 | case HID_DG_CONFIDENCE: | 71 | case HID_DG_CONFIDENCE: |
72 | case HID_DG_CONTACTCOUNT: | 72 | case HID_DG_CONTACTCOUNT: |
73 | case HID_DG_CONTACTMAX: | 73 | case HID_DG_CONTACTMAX: |
74 | return -1; | 74 | return -1; |
75 | case HID_DG_CONTACTID: | 75 | case HID_DG_CONTACTID: |
76 | hid_map_usage(hi, usage, bit, max, | 76 | hid_map_usage(hi, usage, bit, max, |
77 | EV_ABS, ABS_MT_TRACKING_ID); | 77 | EV_ABS, ABS_MT_TRACKING_ID); |
78 | return 1; | 78 | return 1; |
79 | case HID_DG_TIPPRESSURE: | 79 | case HID_DG_TIPPRESSURE: |
80 | hid_map_usage(hi, usage, bit, max, | 80 | hid_map_usage(hi, usage, bit, max, |
81 | EV_ABS, ABS_MT_PRESSURE); | 81 | EV_ABS, ABS_MT_PRESSURE); |
82 | /* touchscreen emulation */ | ||
83 | input_set_abs_params(hi->input, ABS_PRESSURE, | ||
84 | field->logical_minimum, | ||
85 | field->logical_maximum, 0, 0); | ||
82 | return 1; | 86 | return 1; |
83 | } | 87 | } |
84 | return 0; | 88 | return 0; |
85 | } | 89 | } |
86 | 90 | ||
87 | /* ignore others (from other reports we won't get anyway) */ | 91 | /* ignore others (from other reports we won't get anyway) */ |
88 | return -1; | 92 | return -1; |
89 | } | 93 | } |
90 | 94 | ||
91 | static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 95 | static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
92 | struct hid_field *field, struct hid_usage *usage, | 96 | struct hid_field *field, struct hid_usage *usage, |
93 | unsigned long **bit, int *max) | 97 | unsigned long **bit, int *max) |
94 | { | 98 | { |
95 | if (usage->type == EV_KEY || usage->type == EV_ABS) | 99 | if (usage->type == EV_KEY || usage->type == EV_ABS) |
96 | clear_bit(usage->code, *bit); | 100 | clear_bit(usage->code, *bit); |
97 | 101 | ||
98 | return 0; | 102 | return 0; |
99 | } | 103 | } |
100 | 104 | ||
101 | /* | 105 | /* |
102 | * this function is called when a whole finger has been parsed, | 106 | * this function is called when a whole finger has been parsed, |
103 | * so that it can decide what to send to the input layer. | 107 | * so that it can decide what to send to the input layer. |
104 | */ | 108 | */ |
105 | static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | 109 | static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) |
106 | { | 110 | { |
107 | td->first = !td->first; /* touchscreen emulation */ | 111 | td->first = !td->first; /* touchscreen emulation */ |
108 | 112 | ||
109 | if (td->valid) { | 113 | if (td->valid) { |
110 | /* emit multitouch events */ | 114 | /* emit multitouch events */ |
111 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | 115 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); |
112 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); | 116 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3); |
113 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); | 117 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3); |
114 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); | 118 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); |
115 | 119 | ||
116 | input_mt_sync(input); | 120 | input_mt_sync(input); |
117 | 121 | ||
118 | /* | 122 | /* |
119 | * touchscreen emulation: store (x, y) as | 123 | * touchscreen emulation: store (x, y) as |
120 | * the last valid values in this frame | 124 | * the last valid values in this frame |
121 | */ | 125 | */ |
122 | td->lastx = td->x; | 126 | td->lastx = td->x; |
123 | td->lasty = td->y; | 127 | td->lasty = td->y; |
128 | td->lastz = td->z; | ||
124 | } | 129 | } |
125 | 130 | ||
126 | /* | 131 | /* |
127 | * touchscreen emulation: if this is the second finger and at least | 132 | * touchscreen emulation: if this is the second finger and at least |
128 | * one in this frame is valid, the latest valid in the frame is | 133 | * one in this frame is valid, the latest valid in the frame is |
129 | * the oldest on the panel, the one we want for single touch | 134 | * the oldest on the panel, the one we want for single touch |
130 | */ | 135 | */ |
131 | if (!td->first && td->activity) { | 136 | if (!td->first && td->activity) { |
132 | input_event(input, EV_ABS, ABS_X, td->lastx); | 137 | input_event(input, EV_ABS, ABS_X, td->lastx >> 3); |
133 | input_event(input, EV_ABS, ABS_Y, td->lasty); | 138 | input_event(input, EV_ABS, ABS_Y, td->lasty >> 3); |
139 | input_event(input, EV_ABS, ABS_PRESSURE, td->lastz); | ||
134 | } | 140 | } |
135 | 141 | ||
136 | if (!td->valid) { | 142 | if (!td->valid) { |
137 | /* | 143 | /* |
138 | * touchscreen emulation: if the first finger is invalid | 144 | * touchscreen emulation: if the first finger is invalid |
139 | * and there previously was finger activity, this is a release | 145 | * and there previously was finger activity, this is a release |
140 | */ | 146 | */ |
141 | if (td->first && td->activity) { | 147 | if (td->first && td->activity) { |
142 | input_event(input, EV_KEY, BTN_TOUCH, 0); | 148 | input_event(input, EV_KEY, BTN_TOUCH, 0); |
143 | td->activity = false; | 149 | td->activity = false; |
144 | } | 150 | } |
145 | return; | 151 | return; |
146 | } | 152 | } |
147 | 153 | ||
148 | 154 | ||
149 | /* touchscreen emulation: if no previous activity, emit touch event */ | 155 | /* touchscreen emulation: if no previous activity, emit touch event */ |
150 | if (!td->activity) { | 156 | if (!td->activity) { |
151 | input_event(input, EV_KEY, BTN_TOUCH, 1); | 157 | input_event(input, EV_KEY, BTN_TOUCH, 1); |
152 | td->activity = true; | 158 | td->activity = true; |
153 | } | 159 | } |
154 | } | 160 | } |
155 | 161 | ||
156 | 162 | ||
157 | static int egalax_event(struct hid_device *hid, struct hid_field *field, | 163 | static int egalax_event(struct hid_device *hid, struct hid_field *field, |
158 | struct hid_usage *usage, __s32 value) | 164 | struct hid_usage *usage, __s32 value) |
159 | { | 165 | { |
160 | struct egalax_data *td = hid_get_drvdata(hid); | 166 | struct egalax_data *td = hid_get_drvdata(hid); |
161 | 167 | ||
162 | /* Note, eGalax has two product lines: the first is resistive and | 168 | /* Note, eGalax has two product lines: the first is resistive and |
163 | * uses a standard parallel multitouch protocol (product ID == | 169 | * uses a standard parallel multitouch protocol (product ID == |
164 | * 48xx). The second is capacitive and uses an unusual "serial" | 170 | * 48xx). The second is capacitive and uses an unusual "serial" |
165 | * protocol with a different message for each multitouch finger | 171 | * protocol with a different message for each multitouch finger |
166 | * (product ID == 72xx). We do not yet generate a correct event | 172 | * (product ID == 72xx). We do not yet generate a correct event |
167 | * sequence for the capacitive/serial protocol. | 173 | * sequence for the capacitive/serial protocol. |
168 | */ | 174 | */ |
169 | if (hid->claimed & HID_CLAIMED_INPUT) { | 175 | if (hid->claimed & HID_CLAIMED_INPUT) { |
170 | struct input_dev *input = field->hidinput->input; | 176 | struct input_dev *input = field->hidinput->input; |
171 | 177 | ||
172 | switch (usage->hid) { | 178 | switch (usage->hid) { |
173 | case HID_DG_INRANGE: | 179 | case HID_DG_INRANGE: |
174 | case HID_DG_CONFIDENCE: | 180 | case HID_DG_CONFIDENCE: |
175 | /* avoid interference from generic hidinput handling */ | 181 | /* avoid interference from generic hidinput handling */ |
176 | break; | 182 | break; |
177 | case HID_DG_TIPSWITCH: | 183 | case HID_DG_TIPSWITCH: |
178 | td->valid = value; | 184 | td->valid = value; |
179 | break; | 185 | break; |
180 | case HID_DG_TIPPRESSURE: | 186 | case HID_DG_TIPPRESSURE: |
181 | td->z = value; | 187 | td->z = value; |
182 | break; | 188 | break; |
183 | case HID_DG_CONTACTID: | 189 | case HID_DG_CONTACTID: |
184 | td->id = value; | 190 | td->id = value; |
185 | break; | 191 | break; |
186 | case HID_GD_X: | 192 | case HID_GD_X: |
187 | td->x = value; | 193 | td->x = value; |
188 | break; | 194 | break; |
189 | case HID_GD_Y: | 195 | case HID_GD_Y: |
190 | td->y = value; | 196 | td->y = value; |
191 | /* this is the last field in a finger */ | 197 | /* this is the last field in a finger */ |
192 | egalax_filter_event(td, input); | 198 | egalax_filter_event(td, input); |
193 | break; | 199 | break; |
194 | case HID_DG_CONTACTCOUNT: | 200 | case HID_DG_CONTACTCOUNT: |
195 | /* touch emulation: this is the last field in a frame */ | 201 | /* touch emulation: this is the last field in a frame */ |
196 | td->first = false; | 202 | td->first = false; |
197 | break; | 203 | break; |
198 | 204 | ||
199 | default: | 205 | default: |
200 | /* fallback to the generic hidinput handling */ | 206 | /* fallback to the generic hidinput handling */ |
201 | return 0; | 207 | return 0; |
202 | } | 208 | } |
203 | } | 209 | } |
204 | 210 | ||
205 | /* we have handled the hidinput part, now remains hiddev */ | 211 | /* we have handled the hidinput part, now remains hiddev */ |
206 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | 212 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) |
207 | hid->hiddev_hid_event(hid, field, usage, value); | 213 | hid->hiddev_hid_event(hid, field, usage, value); |
208 | 214 | ||
209 | return 1; | 215 | return 1; |
210 | } | 216 | } |
211 | 217 | ||
212 | static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id) | 218 | static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id) |
213 | { | 219 | { |
214 | int ret; | 220 | int ret; |
215 | struct egalax_data *td; | 221 | struct egalax_data *td; |
216 | struct hid_report *report; | 222 | struct hid_report *report; |
217 | 223 | ||
218 | td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL); | 224 | td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL); |
219 | if (!td) { | 225 | if (!td) { |
220 | dev_err(&hdev->dev, "cannot allocate eGalax data\n"); | 226 | dev_err(&hdev->dev, "cannot allocate eGalax data\n"); |
221 | return -ENOMEM; | 227 | return -ENOMEM; |
222 | } | 228 | } |
223 | hid_set_drvdata(hdev, td); | 229 | hid_set_drvdata(hdev, td); |
224 | 230 | ||
225 | ret = hid_parse(hdev); | 231 | ret = hid_parse(hdev); |
226 | if (ret) | 232 | if (ret) |
227 | goto end; | 233 | goto end; |
228 | 234 | ||
229 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 235 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
230 | if (ret) | 236 | if (ret) |
231 | goto end; | 237 | goto end; |
232 | 238 | ||
233 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[5]; | 239 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[5]; |
234 | if (report) { | 240 | if (report) { |
235 | report->field[0]->value[0] = 2; | 241 | report->field[0]->value[0] = 2; |
236 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 242 | usbhid_submit_report(hdev, report, USB_DIR_OUT); |
237 | } | 243 | } |
238 | 244 | ||
239 | end: | 245 | end: |
240 | if (ret) | 246 | if (ret) |
241 | kfree(td); | 247 | kfree(td); |
242 | 248 | ||
243 | return ret; | 249 | return ret; |
244 | } | 250 | } |
245 | 251 | ||
246 | static void egalax_remove(struct hid_device *hdev) | 252 | static void egalax_remove(struct hid_device *hdev) |
247 | { | 253 | { |
248 | hid_hw_stop(hdev); | 254 | hid_hw_stop(hdev); |
249 | kfree(hid_get_drvdata(hdev)); | 255 | kfree(hid_get_drvdata(hdev)); |
250 | hid_set_drvdata(hdev, NULL); | 256 | hid_set_drvdata(hdev, NULL); |
251 | } | 257 | } |
252 | 258 | ||
253 | static const struct hid_device_id egalax_devices[] = { | 259 | static const struct hid_device_id egalax_devices[] = { |
254 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 260 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
255 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 261 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
256 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 262 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
257 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 263 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, |
258 | { } | 264 | { } |
259 | }; | 265 | }; |
260 | MODULE_DEVICE_TABLE(hid, egalax_devices); | 266 | MODULE_DEVICE_TABLE(hid, egalax_devices); |
261 | 267 | ||
262 | static const struct hid_usage_id egalax_grabbed_usages[] = { | 268 | static const struct hid_usage_id egalax_grabbed_usages[] = { |
263 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | 269 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, |
264 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | 270 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} |
265 | }; | 271 | }; |
266 | 272 | ||
267 | static struct hid_driver egalax_driver = { | 273 | static struct hid_driver egalax_driver = { |
268 | .name = "egalax-touch", | 274 | .name = "egalax-touch", |
269 | .id_table = egalax_devices, | 275 | .id_table = egalax_devices, |
270 | .probe = egalax_probe, | 276 | .probe = egalax_probe, |
271 | .remove = egalax_remove, | 277 | .remove = egalax_remove, |
272 | .input_mapping = egalax_input_mapping, | 278 | .input_mapping = egalax_input_mapping, |
273 | .input_mapped = egalax_input_mapped, | 279 | .input_mapped = egalax_input_mapped, |
274 | .usage_table = egalax_grabbed_usages, | 280 | .usage_table = egalax_grabbed_usages, |
275 | .event = egalax_event, | 281 | .event = egalax_event, |
276 | }; | 282 | }; |
277 | 283 | ||
278 | static int __init egalax_init(void) | 284 | static int __init egalax_init(void) |
279 | { | 285 | { |
280 | return hid_register_driver(&egalax_driver); | 286 | return hid_register_driver(&egalax_driver); |
281 | } | 287 | } |
282 | 288 | ||
283 | static void __exit egalax_exit(void) | 289 | static void __exit egalax_exit(void) |
284 | { | 290 | { |
285 | hid_unregister_driver(&egalax_driver); | 291 | hid_unregister_driver(&egalax_driver); |
286 | } | 292 | } |
287 | 293 | ||
288 | module_init(egalax_init); | 294 | module_init(egalax_init); |
289 | module_exit(egalax_exit); | 295 | module_exit(egalax_exit); |
290 | 296 | ||
291 | 297 |
drivers/hid/hid-ids.h
1 | /* | 1 | /* |
2 | * USB HID quirks support for Linux | 2 | * USB HID quirks support for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006-2007 Jiri Kosina | 7 | * Copyright (c) 2006-2007 Jiri Kosina |
8 | * Copyright (c) 2007 Paul Walmsley | 8 | * Copyright (c) 2007 Paul Walmsley |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 14 | * Software Foundation; either version 2 of the License, or (at your option) |
15 | * any later version. | 15 | * any later version. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #ifndef HID_IDS_H_FILE | 18 | #ifndef HID_IDS_H_FILE |
19 | #define HID_IDS_H_FILE | 19 | #define HID_IDS_H_FILE |
20 | 20 | ||
21 | #define USB_VENDOR_ID_3M 0x0596 | 21 | #define USB_VENDOR_ID_3M 0x0596 |
22 | #define USB_DEVICE_ID_3M1968 0x0500 | 22 | #define USB_DEVICE_ID_3M1968 0x0500 |
23 | #define USB_DEVICE_ID_3M2256 0x0502 | 23 | #define USB_DEVICE_ID_3M2256 0x0502 |
24 | 24 | ||
25 | #define USB_VENDOR_ID_A4TECH 0x09da | 25 | #define USB_VENDOR_ID_A4TECH 0x09da |
26 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 26 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
27 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a | 27 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a |
28 | #define USB_DEVICE_ID_A4TECH_RP_649 0x001a | 28 | #define USB_DEVICE_ID_A4TECH_RP_649 0x001a |
29 | 29 | ||
30 | #define USB_VENDOR_ID_AASHIMA 0x06d6 | 30 | #define USB_VENDOR_ID_AASHIMA 0x06d6 |
31 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | 31 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 |
32 | #define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 | 32 | #define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 |
33 | 33 | ||
34 | #define USB_VENDOR_ID_ACECAD 0x0460 | 34 | #define USB_VENDOR_ID_ACECAD 0x0460 |
35 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | 35 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 |
36 | #define USB_DEVICE_ID_ACECAD_302 0x0008 | 36 | #define USB_DEVICE_ID_ACECAD_302 0x0008 |
37 | 37 | ||
38 | #define USB_VENDOR_ID_ACRUX 0x1a34 | 38 | #define USB_VENDOR_ID_ACRUX 0x1a34 |
39 | 39 | ||
40 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | 40 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 |
41 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | 41 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 |
42 | 42 | ||
43 | #define USB_VENDOR_ID_AFATECH 0x15a4 | 43 | #define USB_VENDOR_ID_AFATECH 0x15a4 |
44 | #define USB_DEVICE_ID_AFATECH_AF9016 0x9016 | 44 | #define USB_DEVICE_ID_AFATECH_AF9016 0x9016 |
45 | 45 | ||
46 | #define USB_VENDOR_ID_AIPTEK 0x08ca | 46 | #define USB_VENDOR_ID_AIPTEK 0x08ca |
47 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 | 47 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 |
48 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 | 48 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 |
49 | #define USB_DEVICE_ID_AIPTEK_20 0x0020 | 49 | #define USB_DEVICE_ID_AIPTEK_20 0x0020 |
50 | #define USB_DEVICE_ID_AIPTEK_21 0x0021 | 50 | #define USB_DEVICE_ID_AIPTEK_21 0x0021 |
51 | #define USB_DEVICE_ID_AIPTEK_22 0x0022 | 51 | #define USB_DEVICE_ID_AIPTEK_22 0x0022 |
52 | #define USB_DEVICE_ID_AIPTEK_23 0x0023 | 52 | #define USB_DEVICE_ID_AIPTEK_23 0x0023 |
53 | #define USB_DEVICE_ID_AIPTEK_24 0x0024 | 53 | #define USB_DEVICE_ID_AIPTEK_24 0x0024 |
54 | 54 | ||
55 | #define USB_VENDOR_ID_AIRCABLE 0x16CA | 55 | #define USB_VENDOR_ID_AIRCABLE 0x16CA |
56 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 | 56 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 |
57 | 57 | ||
58 | #define USB_VENDOR_ID_ALCOR 0x058f | 58 | #define USB_VENDOR_ID_ALCOR 0x058f |
59 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 | 59 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 |
60 | 60 | ||
61 | #define USB_VENDOR_ID_ALPS 0x0433 | 61 | #define USB_VENDOR_ID_ALPS 0x0433 |
62 | #define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 | 62 | #define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 |
63 | 63 | ||
64 | #define USB_VENDOR_ID_APPLE 0x05ac | 64 | #define USB_VENDOR_ID_APPLE 0x05ac |
65 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 | 65 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 |
66 | #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d | 66 | #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d |
67 | #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e | ||
67 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e | 68 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e |
68 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f | 69 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f |
69 | #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 | 70 | #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 |
70 | #define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 | 71 | #define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 |
71 | #define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 | 72 | #define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 |
72 | #define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 | 73 | #define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 |
73 | #define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 | 74 | #define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 |
74 | #define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 | 75 | #define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 |
75 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a | 76 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a |
76 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b | 77 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b |
77 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c | 78 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c |
78 | #define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d | 79 | #define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d |
79 | #define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e | 80 | #define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e |
80 | #define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f | 81 | #define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f |
81 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 | 82 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 |
82 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 | 83 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 |
83 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 | 84 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 |
84 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 | 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 |
85 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 | 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 |
86 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 | 87 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 |
87 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 | 88 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 |
88 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a | 89 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a |
89 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b | 90 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b |
90 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c | 91 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c |
91 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d | 92 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d |
92 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e | 93 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e |
93 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 94 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
94 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 95 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
95 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 96 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
96 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | 97 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 |
97 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | 98 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 |
98 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | 99 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 |
99 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 | 100 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 |
100 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a | 101 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a |
101 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b | 102 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b |
102 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 103 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
103 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 104 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
104 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 | 105 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 |
105 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 | 106 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 |
106 | 107 | ||
107 | #define USB_VENDOR_ID_ASUS 0x0486 | 108 | #define USB_VENDOR_ID_ASUS 0x0486 |
108 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 | 109 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 |
109 | #define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 | 110 | #define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 |
110 | 111 | ||
111 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 | 112 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 |
112 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 | 113 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 |
113 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b | 114 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b |
114 | 115 | ||
115 | #define USB_VENDOR_ID_ATEN 0x0557 | 116 | #define USB_VENDOR_ID_ATEN 0x0557 |
116 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 | 117 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 |
117 | #define USB_DEVICE_ID_ATEN_CS124U 0x2202 | 118 | #define USB_DEVICE_ID_ATEN_CS124U 0x2202 |
118 | #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 | 119 | #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 |
119 | #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 | 120 | #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 |
120 | #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 | 121 | #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 |
121 | 122 | ||
122 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca | 123 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca |
123 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 | 124 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 |
124 | 125 | ||
125 | #define USB_VENDOR_ID_BELKIN 0x050d | 126 | #define USB_VENDOR_ID_BELKIN 0x050d |
126 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 | 127 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 |
127 | 128 | ||
128 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 | 129 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 |
129 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 | 130 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 |
130 | 131 | ||
131 | #define USB_VENDOR_ID_BTC 0x046e | 132 | #define USB_VENDOR_ID_BTC 0x046e |
132 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 | 133 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 |
133 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 | 134 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 |
134 | 135 | ||
135 | #define USB_VENDOR_ID_CANDO 0x2087 | 136 | #define USB_VENDOR_ID_CANDO 0x2087 |
136 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 | 137 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 |
137 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 | 138 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 |
138 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 | 139 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 |
139 | 140 | ||
140 | #define USB_VENDOR_ID_CH 0x068e | 141 | #define USB_VENDOR_ID_CH 0x068e |
141 | #define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 | 142 | #define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 |
142 | #define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4 | 143 | #define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4 |
143 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 | 144 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 |
144 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff | 145 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff |
145 | #define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3 | 146 | #define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3 |
146 | #define USB_DEVICE_ID_CH_AXIS_295 0x001c | 147 | #define USB_DEVICE_ID_CH_AXIS_295 0x001c |
147 | 148 | ||
148 | #define USB_VENDOR_ID_CHERRY 0x046a | 149 | #define USB_VENDOR_ID_CHERRY 0x046a |
149 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 | 150 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 |
150 | #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 | 151 | #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 |
151 | 152 | ||
152 | #define USB_VENDOR_ID_CHIC 0x05fe | 153 | #define USB_VENDOR_ID_CHIC 0x05fe |
153 | #define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 | 154 | #define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 |
154 | 155 | ||
155 | #define USB_VENDOR_ID_CHICONY 0x04f2 | 156 | #define USB_VENDOR_ID_CHICONY 0x04f2 |
156 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 | 157 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 |
157 | #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d | 158 | #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d |
158 | 159 | ||
159 | #define USB_VENDOR_ID_CIDC 0x1677 | 160 | #define USB_VENDOR_ID_CIDC 0x1677 |
160 | 161 | ||
161 | #define USB_VENDOR_ID_CMEDIA 0x0d8c | 162 | #define USB_VENDOR_ID_CMEDIA 0x0d8c |
162 | #define USB_DEVICE_ID_CM109 0x000e | 163 | #define USB_DEVICE_ID_CM109 0x000e |
163 | 164 | ||
164 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 | 165 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 |
165 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 | 166 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 |
166 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff | 167 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff |
167 | 168 | ||
168 | #define USB_VENDOR_ID_CREATIVELABS 0x041e | 169 | #define USB_VENDOR_ID_CREATIVELABS 0x041e |
169 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 | 170 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 |
170 | 171 | ||
171 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | 172 | #define USB_VENDOR_ID_CYGNAL 0x10c4 |
172 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | 173 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a |
173 | 174 | ||
174 | #define USB_VENDOR_ID_CYPRESS 0x04b4 | 175 | #define USB_VENDOR_ID_CYPRESS 0x04b4 |
175 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 | 176 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 |
176 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 177 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
177 | #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 | 178 | #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 |
178 | #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 | 179 | #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 |
179 | #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 | 180 | #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 |
180 | #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 | 181 | #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 |
181 | 182 | ||
182 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 | 183 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 |
183 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a | 184 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a |
184 | 185 | ||
185 | #define USB_VENDOR_ID_DELORME 0x1163 | 186 | #define USB_VENDOR_ID_DELORME 0x1163 |
186 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 187 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
187 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | 188 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 |
188 | 189 | ||
189 | #define USB_VENDOR_ID_DMI 0x0c0b | 190 | #define USB_VENDOR_ID_DMI 0x0c0b |
190 | #define USB_DEVICE_ID_DMI_ENC 0x5fab | 191 | #define USB_DEVICE_ID_DMI_ENC 0x5fab |
191 | 192 | ||
192 | #define USB_VENDOR_ID_DRAGONRISE 0x0079 | 193 | #define USB_VENDOR_ID_DRAGONRISE 0x0079 |
193 | 194 | ||
194 | #define USB_VENDOR_ID_DWAV 0x0eef | 195 | #define USB_VENDOR_ID_DWAV 0x0eef |
195 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 196 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
196 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d | 197 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d |
197 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c | 198 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c |
198 | 199 | ||
199 | #define USB_VENDOR_ID_ELECOM 0x056e | 200 | #define USB_VENDOR_ID_ELECOM 0x056e |
200 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 201 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
201 | 202 | ||
202 | #define USB_VENDOR_ID_ELO 0x04E7 | 203 | #define USB_VENDOR_ID_ELO 0x04E7 |
203 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 | 204 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 |
204 | 205 | ||
205 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f | 206 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
206 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 | 207 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
207 | 208 | ||
208 | #define USB_VENDOR_ID_ETT 0x0664 | 209 | #define USB_VENDOR_ID_ETT 0x0664 |
209 | #define USB_DEVICE_ID_TC5UH 0x0309 | 210 | #define USB_DEVICE_ID_TC5UH 0x0309 |
210 | #define USB_DEVICE_ID_TC4UM 0x0306 | 211 | #define USB_DEVICE_ID_TC4UM 0x0306 |
211 | 212 | ||
212 | #define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 | 213 | #define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 |
213 | #define USB_DEVICE_ID_ETURBOTOUCH 0x0006 | 214 | #define USB_DEVICE_ID_ETURBOTOUCH 0x0006 |
214 | 215 | ||
215 | #define USB_VENDOR_ID_EZKEY 0x0518 | 216 | #define USB_VENDOR_ID_EZKEY 0x0518 |
216 | #define USB_DEVICE_ID_BTC_8193 0x0002 | 217 | #define USB_DEVICE_ID_BTC_8193 0x0002 |
217 | 218 | ||
218 | #define USB_VENDOR_ID_GAMERON 0x0810 | 219 | #define USB_VENDOR_ID_GAMERON 0x0810 |
219 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 220 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
220 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | 221 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 |
221 | 222 | ||
222 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc | 223 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc |
223 | 224 | ||
224 | #define USB_VENDOR_ID_GLAB 0x06c2 | 225 | #define USB_VENDOR_ID_GLAB 0x06c2 |
225 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 | 226 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 |
226 | #define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 | 227 | #define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 |
227 | #define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 | 228 | #define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 |
228 | #define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044 | 229 | #define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044 |
229 | #define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 | 230 | #define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 |
230 | #define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051 | 231 | #define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051 |
231 | #define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 | 232 | #define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 |
232 | #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 | 233 | #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 |
233 | 234 | ||
234 | #define USB_VENDOR_ID_GOTOP 0x08f2 | 235 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
235 | #define USB_DEVICE_ID_SUPER_Q2 0x007f | 236 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
236 | #define USB_DEVICE_ID_GOGOPEN 0x00ce | 237 | #define USB_DEVICE_ID_GOGOPEN 0x00ce |
237 | #define USB_DEVICE_ID_PENPOWER 0x00f4 | 238 | #define USB_DEVICE_ID_PENPOWER 0x00f4 |
238 | 239 | ||
239 | #define USB_VENDOR_ID_GREENASIA 0x0e8f | 240 | #define USB_VENDOR_ID_GREENASIA 0x0e8f |
240 | 241 | ||
241 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 | 242 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 |
242 | #define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 | 243 | #define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 |
243 | 244 | ||
244 | #define USB_VENDOR_ID_GRIFFIN 0x077d | 245 | #define USB_VENDOR_ID_GRIFFIN 0x077d |
245 | #define USB_DEVICE_ID_POWERMATE 0x0410 | 246 | #define USB_DEVICE_ID_POWERMATE 0x0410 |
246 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA | 247 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA |
247 | 248 | ||
248 | #define USB_VENDOR_ID_GTCO 0x078c | 249 | #define USB_VENDOR_ID_GTCO 0x078c |
249 | #define USB_DEVICE_ID_GTCO_90 0x0090 | 250 | #define USB_DEVICE_ID_GTCO_90 0x0090 |
250 | #define USB_DEVICE_ID_GTCO_100 0x0100 | 251 | #define USB_DEVICE_ID_GTCO_100 0x0100 |
251 | #define USB_DEVICE_ID_GTCO_101 0x0101 | 252 | #define USB_DEVICE_ID_GTCO_101 0x0101 |
252 | #define USB_DEVICE_ID_GTCO_103 0x0103 | 253 | #define USB_DEVICE_ID_GTCO_103 0x0103 |
253 | #define USB_DEVICE_ID_GTCO_104 0x0104 | 254 | #define USB_DEVICE_ID_GTCO_104 0x0104 |
254 | #define USB_DEVICE_ID_GTCO_105 0x0105 | 255 | #define USB_DEVICE_ID_GTCO_105 0x0105 |
255 | #define USB_DEVICE_ID_GTCO_106 0x0106 | 256 | #define USB_DEVICE_ID_GTCO_106 0x0106 |
256 | #define USB_DEVICE_ID_GTCO_107 0x0107 | 257 | #define USB_DEVICE_ID_GTCO_107 0x0107 |
257 | #define USB_DEVICE_ID_GTCO_108 0x0108 | 258 | #define USB_DEVICE_ID_GTCO_108 0x0108 |
258 | #define USB_DEVICE_ID_GTCO_200 0x0200 | 259 | #define USB_DEVICE_ID_GTCO_200 0x0200 |
259 | #define USB_DEVICE_ID_GTCO_201 0x0201 | 260 | #define USB_DEVICE_ID_GTCO_201 0x0201 |
260 | #define USB_DEVICE_ID_GTCO_202 0x0202 | 261 | #define USB_DEVICE_ID_GTCO_202 0x0202 |
261 | #define USB_DEVICE_ID_GTCO_203 0x0203 | 262 | #define USB_DEVICE_ID_GTCO_203 0x0203 |
262 | #define USB_DEVICE_ID_GTCO_204 0x0204 | 263 | #define USB_DEVICE_ID_GTCO_204 0x0204 |
263 | #define USB_DEVICE_ID_GTCO_205 0x0205 | 264 | #define USB_DEVICE_ID_GTCO_205 0x0205 |
264 | #define USB_DEVICE_ID_GTCO_206 0x0206 | 265 | #define USB_DEVICE_ID_GTCO_206 0x0206 |
265 | #define USB_DEVICE_ID_GTCO_207 0x0207 | 266 | #define USB_DEVICE_ID_GTCO_207 0x0207 |
266 | #define USB_DEVICE_ID_GTCO_300 0x0300 | 267 | #define USB_DEVICE_ID_GTCO_300 0x0300 |
267 | #define USB_DEVICE_ID_GTCO_301 0x0301 | 268 | #define USB_DEVICE_ID_GTCO_301 0x0301 |
268 | #define USB_DEVICE_ID_GTCO_302 0x0302 | 269 | #define USB_DEVICE_ID_GTCO_302 0x0302 |
269 | #define USB_DEVICE_ID_GTCO_303 0x0303 | 270 | #define USB_DEVICE_ID_GTCO_303 0x0303 |
270 | #define USB_DEVICE_ID_GTCO_304 0x0304 | 271 | #define USB_DEVICE_ID_GTCO_304 0x0304 |
271 | #define USB_DEVICE_ID_GTCO_305 0x0305 | 272 | #define USB_DEVICE_ID_GTCO_305 0x0305 |
272 | #define USB_DEVICE_ID_GTCO_306 0x0306 | 273 | #define USB_DEVICE_ID_GTCO_306 0x0306 |
273 | #define USB_DEVICE_ID_GTCO_307 0x0307 | 274 | #define USB_DEVICE_ID_GTCO_307 0x0307 |
274 | #define USB_DEVICE_ID_GTCO_308 0x0308 | 275 | #define USB_DEVICE_ID_GTCO_308 0x0308 |
275 | #define USB_DEVICE_ID_GTCO_309 0x0309 | 276 | #define USB_DEVICE_ID_GTCO_309 0x0309 |
276 | #define USB_DEVICE_ID_GTCO_400 0x0400 | 277 | #define USB_DEVICE_ID_GTCO_400 0x0400 |
277 | #define USB_DEVICE_ID_GTCO_401 0x0401 | 278 | #define USB_DEVICE_ID_GTCO_401 0x0401 |
278 | #define USB_DEVICE_ID_GTCO_402 0x0402 | 279 | #define USB_DEVICE_ID_GTCO_402 0x0402 |
279 | #define USB_DEVICE_ID_GTCO_403 0x0403 | 280 | #define USB_DEVICE_ID_GTCO_403 0x0403 |
280 | #define USB_DEVICE_ID_GTCO_404 0x0404 | 281 | #define USB_DEVICE_ID_GTCO_404 0x0404 |
281 | #define USB_DEVICE_ID_GTCO_405 0x0405 | 282 | #define USB_DEVICE_ID_GTCO_405 0x0405 |
282 | #define USB_DEVICE_ID_GTCO_500 0x0500 | 283 | #define USB_DEVICE_ID_GTCO_500 0x0500 |
283 | #define USB_DEVICE_ID_GTCO_501 0x0501 | 284 | #define USB_DEVICE_ID_GTCO_501 0x0501 |
284 | #define USB_DEVICE_ID_GTCO_502 0x0502 | 285 | #define USB_DEVICE_ID_GTCO_502 0x0502 |
285 | #define USB_DEVICE_ID_GTCO_503 0x0503 | 286 | #define USB_DEVICE_ID_GTCO_503 0x0503 |
286 | #define USB_DEVICE_ID_GTCO_504 0x0504 | 287 | #define USB_DEVICE_ID_GTCO_504 0x0504 |
287 | #define USB_DEVICE_ID_GTCO_1000 0x1000 | 288 | #define USB_DEVICE_ID_GTCO_1000 0x1000 |
288 | #define USB_DEVICE_ID_GTCO_1001 0x1001 | 289 | #define USB_DEVICE_ID_GTCO_1001 0x1001 |
289 | #define USB_DEVICE_ID_GTCO_1002 0x1002 | 290 | #define USB_DEVICE_ID_GTCO_1002 0x1002 |
290 | #define USB_DEVICE_ID_GTCO_1003 0x1003 | 291 | #define USB_DEVICE_ID_GTCO_1003 0x1003 |
291 | #define USB_DEVICE_ID_GTCO_1004 0x1004 | 292 | #define USB_DEVICE_ID_GTCO_1004 0x1004 |
292 | #define USB_DEVICE_ID_GTCO_1005 0x1005 | 293 | #define USB_DEVICE_ID_GTCO_1005 0x1005 |
293 | #define USB_DEVICE_ID_GTCO_1006 0x1006 | 294 | #define USB_DEVICE_ID_GTCO_1006 0x1006 |
294 | #define USB_DEVICE_ID_GTCO_1007 0x1007 | 295 | #define USB_DEVICE_ID_GTCO_1007 0x1007 |
295 | 296 | ||
296 | #define USB_VENDOR_ID_GYRATION 0x0c16 | 297 | #define USB_VENDOR_ID_GYRATION 0x0c16 |
297 | #define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 | 298 | #define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 |
298 | #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 | 299 | #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 |
299 | #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 | 300 | #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 |
300 | 301 | ||
301 | #define USB_VENDOR_ID_HAPP 0x078b | 302 | #define USB_VENDOR_ID_HAPP 0x078b |
302 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 | 303 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 |
303 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 | 304 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
304 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 | 305 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 |
305 | 306 | ||
306 | #define USB_VENDOR_ID_IMATION 0x0718 | 307 | #define USB_VENDOR_ID_IMATION 0x0718 |
307 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 308 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
308 | 309 | ||
309 | #define USB_VENDOR_ID_JESS 0x0c45 | 310 | #define USB_VENDOR_ID_JESS 0x0c45 |
310 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 | 311 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 |
311 | 312 | ||
312 | #define USB_VENDOR_ID_KBGEAR 0x084e | 313 | #define USB_VENDOR_ID_KBGEAR 0x084e |
313 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 314 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
314 | 315 | ||
315 | #define USB_VENDOR_ID_KENSINGTON 0x047d | 316 | #define USB_VENDOR_ID_KENSINGTON 0x047d |
316 | #define USB_DEVICE_ID_KS_SLIMBLADE 0x2041 | 317 | #define USB_DEVICE_ID_KS_SLIMBLADE 0x2041 |
317 | 318 | ||
318 | #define USB_VENDOR_ID_KWORLD 0x1b80 | 319 | #define USB_VENDOR_ID_KWORLD 0x1b80 |
319 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 | 320 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 |
320 | 321 | ||
321 | #define USB_VENDOR_ID_KYE 0x0458 | 322 | #define USB_VENDOR_ID_KYE 0x0458 |
322 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 | 323 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 |
323 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | 324 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
324 | 325 | ||
325 | #define USB_VENDOR_ID_LABTEC 0x1020 | 326 | #define USB_VENDOR_ID_LABTEC 0x1020 |
326 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 | 327 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
327 | 328 | ||
328 | #define USB_VENDOR_ID_LD 0x0f11 | 329 | #define USB_VENDOR_ID_LD 0x0f11 |
329 | #define USB_DEVICE_ID_LD_CASSY 0x1000 | 330 | #define USB_DEVICE_ID_LD_CASSY 0x1000 |
330 | #define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 | 331 | #define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 |
331 | #define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 | 332 | #define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 |
332 | #define USB_DEVICE_ID_LD_JWM 0x1080 | 333 | #define USB_DEVICE_ID_LD_JWM 0x1080 |
333 | #define USB_DEVICE_ID_LD_DMMP 0x1081 | 334 | #define USB_DEVICE_ID_LD_DMMP 0x1081 |
334 | #define USB_DEVICE_ID_LD_UMIP 0x1090 | 335 | #define USB_DEVICE_ID_LD_UMIP 0x1090 |
335 | #define USB_DEVICE_ID_LD_XRAY1 0x1100 | 336 | #define USB_DEVICE_ID_LD_XRAY1 0x1100 |
336 | #define USB_DEVICE_ID_LD_XRAY2 0x1101 | 337 | #define USB_DEVICE_ID_LD_XRAY2 0x1101 |
337 | #define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 | 338 | #define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 |
338 | #define USB_DEVICE_ID_LD_COM3LAB 0x2000 | 339 | #define USB_DEVICE_ID_LD_COM3LAB 0x2000 |
339 | #define USB_DEVICE_ID_LD_TELEPORT 0x2010 | 340 | #define USB_DEVICE_ID_LD_TELEPORT 0x2010 |
340 | #define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 | 341 | #define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 |
341 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 | 342 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 |
342 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 | 343 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 |
343 | 344 | ||
344 | #define USB_VENDOR_ID_LOGITECH 0x046d | 345 | #define USB_VENDOR_ID_LOGITECH 0x046d |
345 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 346 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
346 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 | 347 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
347 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f | 348 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f |
349 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a | ||
348 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 | 350 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 |
349 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 | 351 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 |
350 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 | 352 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 |
351 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 | 353 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 |
352 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 | 354 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 |
353 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 | 355 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 |
354 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 | 356 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 |
355 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 | 357 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 |
356 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 | 358 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 |
357 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 | 359 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 |
358 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 | 360 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 |
361 | #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c | ||
359 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a | 362 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a |
360 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c | 363 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c |
361 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 | 364 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 |
362 | #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 | 365 | #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 |
363 | #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 | 366 | #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 |
364 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 | 367 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
365 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 | 368 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
366 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 | 369 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 |
367 | #define USB_DEVICE_ID_DINOVO_EDGE 0xc714 | 370 | #define USB_DEVICE_ID_DINOVO_EDGE 0xc714 |
368 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f | 371 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f |
369 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 | 372 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 |
370 | 373 | ||
371 | #define USB_VENDOR_ID_MCC 0x09db | 374 | #define USB_VENDOR_ID_MCC 0x09db |
372 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 | 375 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 |
373 | #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a | 376 | #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a |
374 | 377 | ||
375 | #define USB_VENDOR_ID_MGE 0x0463 | 378 | #define USB_VENDOR_ID_MGE 0x0463 |
376 | #define USB_DEVICE_ID_MGE_UPS 0xffff | 379 | #define USB_DEVICE_ID_MGE_UPS 0xffff |
377 | #define USB_DEVICE_ID_MGE_UPS1 0x0001 | 380 | #define USB_DEVICE_ID_MGE_UPS1 0x0001 |
378 | 381 | ||
379 | #define USB_VENDOR_ID_MICROCHIP 0x04d8 | 382 | #define USB_VENDOR_ID_MICROCHIP 0x04d8 |
380 | #define USB_DEVICE_ID_PICKIT1 0x0032 | 383 | #define USB_DEVICE_ID_PICKIT1 0x0032 |
381 | #define USB_DEVICE_ID_PICKIT2 0x0033 | 384 | #define USB_DEVICE_ID_PICKIT2 0x0033 |
382 | #define USB_DEVICE_ID_PICOLCD 0xc002 | 385 | #define USB_DEVICE_ID_PICOLCD 0xc002 |
383 | #define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 | 386 | #define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 |
384 | 387 | ||
385 | #define USB_VENDOR_ID_MICROSOFT 0x045e | 388 | #define USB_VENDOR_ID_MICROSOFT 0x045e |
386 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 389 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
387 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | 390 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d |
388 | #define USB_DEVICE_ID_MS_NE4K 0x00db | 391 | #define USB_DEVICE_ID_MS_NE4K 0x00db |
389 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | 392 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 |
390 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 | 393 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 |
391 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 394 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
392 | 395 | ||
393 | #define USB_VENDOR_ID_MOJO 0x8282 | 396 | #define USB_VENDOR_ID_MOJO 0x8282 |
394 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 397 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
395 | 398 | ||
396 | #define USB_VENDOR_ID_MONTEREY 0x0566 | 399 | #define USB_VENDOR_ID_MONTEREY 0x0566 |
397 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 | 400 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 |
398 | 401 | ||
399 | #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 | 402 | #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 |
400 | #define USB_DEVICE_ID_N_S_HARMONY 0xc359 | 403 | #define USB_DEVICE_ID_N_S_HARMONY 0xc359 |
401 | 404 | ||
402 | #define USB_VENDOR_ID_NATSU 0x08b7 | 405 | #define USB_VENDOR_ID_NATSU 0x08b7 |
403 | #define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 | 406 | #define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 |
404 | 407 | ||
405 | #define USB_VENDOR_ID_NCR 0x0404 | 408 | #define USB_VENDOR_ID_NCR 0x0404 |
406 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 | 409 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 |
407 | #define USB_DEVICE_ID_NCR_LAST 0x03ff | 410 | #define USB_DEVICE_ID_NCR_LAST 0x03ff |
408 | 411 | ||
409 | #define USB_VENDOR_ID_NEC 0x073e | 412 | #define USB_VENDOR_ID_NEC 0x073e |
410 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 | 413 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 |
411 | 414 | ||
412 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 | 415 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 |
413 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 | 416 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 |
414 | 417 | ||
415 | #define USB_VENDOR_ID_NTRIG 0x1b96 | 418 | #define USB_VENDOR_ID_NTRIG 0x1b96 |
416 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 | 419 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 |
417 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 | 420 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 |
418 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 | 421 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 |
419 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3 0x0005 | 422 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3 0x0005 |
420 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4 0x0006 | 423 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4 0x0006 |
421 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5 0x0007 | 424 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5 0x0007 |
422 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6 0x0008 | 425 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6 0x0008 |
423 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7 0x0009 | 426 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7 0x0009 |
424 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8 0x000A | 427 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8 0x000A |
425 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9 0x000B | 428 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9 0x000B |
426 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10 0x000C | 429 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10 0x000C |
427 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11 0x000D | 430 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11 0x000D |
428 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12 0x000E | 431 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12 0x000E |
429 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13 0x000F | 432 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13 0x000F |
430 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14 0x0010 | 433 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14 0x0010 |
431 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15 0x0011 | 434 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15 0x0011 |
432 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 | 435 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 |
433 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 | 436 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 |
434 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 | 437 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 |
435 | 438 | ||
436 | #define USB_VENDOR_ID_ONTRAK 0x0a07 | 439 | #define USB_VENDOR_ID_ONTRAK 0x0a07 |
437 | #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 | 440 | #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 |
438 | 441 | ||
439 | #define USB_VENDOR_ID_ORTEK 0x05a4 | 442 | #define USB_VENDOR_ID_ORTEK 0x05a4 |
440 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 | 443 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 |
441 | 444 | ||
442 | #define USB_VENDOR_ID_PANJIT 0x134c | 445 | #define USB_VENDOR_ID_PANJIT 0x134c |
443 | 446 | ||
444 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | 447 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 |
445 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 | 448 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 |
446 | 449 | ||
447 | #define USB_VENDOR_ID_PETALYNX 0x18b1 | 450 | #define USB_VENDOR_ID_PETALYNX 0x18b1 |
448 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | 451 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 |
449 | 452 | ||
450 | #define USB_VENDOR_ID_PHILIPS 0x0471 | 453 | #define USB_VENDOR_ID_PHILIPS 0x0471 |
451 | #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 | 454 | #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 |
452 | 455 | ||
453 | #define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 | 456 | #define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 |
454 | #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff | 457 | #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff |
455 | 458 | ||
456 | #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 | 459 | #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 |
457 | #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 | 460 | #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 |
458 | 461 | ||
459 | #define USB_VENDOR_ID_POWERCOM 0x0d9f | 462 | #define USB_VENDOR_ID_POWERCOM 0x0d9f |
460 | #define USB_DEVICE_ID_POWERCOM_UPS 0x0002 | 463 | #define USB_DEVICE_ID_POWERCOM_UPS 0x0002 |
461 | 464 | ||
462 | #define USB_VENDOR_ID_PRODIGE 0x05af | 465 | #define USB_VENDOR_ID_PRODIGE 0x05af |
463 | #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 | 466 | #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 |
464 | 467 | ||
465 | #define USB_VENDOR_ID_QUANTA 0x0408 | 468 | #define USB_VENDOR_ID_QUANTA 0x0408 |
466 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 | 469 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 |
467 | #define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001 | 470 | #define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001 |
468 | 471 | ||
469 | #define USB_VENDOR_ID_ROCCAT 0x1e7d | 472 | #define USB_VENDOR_ID_ROCCAT 0x1e7d |
470 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced | 473 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced |
474 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 | ||
475 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 | ||
471 | 476 | ||
472 | #define USB_VENDOR_ID_SAITEK 0x06a3 | 477 | #define USB_VENDOR_ID_SAITEK 0x06a3 |
473 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 | 478 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 |
474 | 479 | ||
475 | #define USB_VENDOR_ID_SAMSUNG 0x0419 | 480 | #define USB_VENDOR_ID_SAMSUNG 0x0419 |
476 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 | 481 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 |
477 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 | 482 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 |
478 | 483 | ||
479 | #define USB_VENDOR_ID_SONY 0x054c | 484 | #define USB_VENDOR_ID_SONY 0x054c |
480 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b | 485 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b |
481 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 486 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
482 | 487 | ||
483 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | 488 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 |
484 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 | 489 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 |
485 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046 | 490 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046 |
486 | 491 | ||
487 | #define USB_VENDOR_ID_STANTUM 0x1f87 | 492 | #define USB_VENDOR_ID_STANTUM 0x1f87 |
488 | #define USB_DEVICE_ID_MTP 0x0002 | 493 | #define USB_DEVICE_ID_MTP 0x0002 |
489 | 494 | ||
490 | #define USB_VENDOR_ID_STANTUM_STM 0x0483 | 495 | #define USB_VENDOR_ID_STANTUM_STM 0x0483 |
491 | #define USB_DEVICE_ID_MTP_STM 0x3261 | 496 | #define USB_DEVICE_ID_MTP_STM 0x3261 |
492 | 497 | ||
493 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 | 498 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 |
494 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 | 499 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 |
495 | 500 | ||
496 | #define USB_VENDOR_ID_SUN 0x0430 | 501 | #define USB_VENDOR_ID_SUN 0x0430 |
497 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab | 502 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab |
498 | 503 | ||
499 | #define USB_VENDOR_ID_SUNPLUS 0x04fc | 504 | #define USB_VENDOR_ID_SUNPLUS 0x04fc |
500 | #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 | 505 | #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 |
501 | 506 | ||
502 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f | 507 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f |
503 | 508 | ||
504 | #define USB_VENDOR_ID_TOPSEED 0x0766 | 509 | #define USB_VENDOR_ID_TOPSEED 0x0766 |
505 | #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 | 510 | #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 |
506 | 511 | ||
507 | #define USB_VENDOR_ID_TOPSEED2 0x1784 | 512 | #define USB_VENDOR_ID_TOPSEED2 0x1784 |
508 | #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 | 513 | #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 |
509 | 514 | ||
510 | #define USB_VENDOR_ID_TOPMAX 0x0663 | 515 | #define USB_VENDOR_ID_TOPMAX 0x0663 |
511 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 | 516 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 |
512 | 517 | ||
513 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd | 518 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd |
514 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | 519 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 |
515 | 520 | ||
516 | #define USB_VENDOR_ID_TURBOX 0x062a | 521 | #define USB_VENDOR_ID_TURBOX 0x062a |
517 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | 522 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 |
518 | #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 | 523 | #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 |
519 | 524 | ||
520 | #define USB_VENDOR_ID_TWINHAN 0x6253 | 525 | #define USB_VENDOR_ID_TWINHAN 0x6253 |
521 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 | 526 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 |
522 | 527 | ||
523 | #define USB_VENDOR_ID_UCLOGIC 0x5543 | 528 | #define USB_VENDOR_ID_UCLOGIC 0x5543 |
524 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 | 529 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 |
525 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 | 530 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 |
526 | #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 | 531 | #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 |
527 | 532 | ||
528 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 533 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
529 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 534 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
530 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | 535 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 |
531 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | 536 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 |
532 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 537 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
533 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 | 538 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 |
534 | 539 | ||
535 | #define USB_VENDOR_ID_WACOM 0x056a | 540 | #define USB_VENDOR_ID_WACOM 0x056a |
536 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 | 541 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 |
537 | 542 | ||
538 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | 543 | #define USB_VENDOR_ID_WISEGROUP 0x0925 |
539 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 | 544 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 |
540 | #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 | 545 | #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 |
541 | #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 | 546 | #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 |
542 | #define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 | 547 | #define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 |
543 | #define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800 | 548 | #define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800 |
544 | #define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 | 549 | #define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 |
545 | 550 | ||
546 | #define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 | 551 | #define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 |
547 | #define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 | 552 | #define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 |
548 | #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 | 553 | #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 |
549 | 554 | ||
550 | #define USB_VENDOR_ID_YEALINK 0x6993 | 555 | #define USB_VENDOR_ID_YEALINK 0x6993 |
551 | #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 | 556 | #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 |
552 | 557 | ||
553 | #define USB_VENDOR_ID_ZEROPLUS 0x0c12 | 558 | #define USB_VENDOR_ID_ZEROPLUS 0x0c12 |
554 | 559 | ||
555 | #define USB_VENDOR_ID_ZYDACRON 0x13EC | 560 | #define USB_VENDOR_ID_ZYDACRON 0x13EC |
556 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 | 561 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 |
557 | 562 | ||
558 | #endif | 563 | #endif |
559 | 564 |
drivers/hid/hid-input.c
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
3 | * Copyright (c) 2006-2010 Jiri Kosina | 3 | * Copyright (c) 2006-2010 Jiri Kosina |
4 | * | 4 | * |
5 | * HID to Linux Input mapping | 5 | * HID to Linux Input mapping |
6 | */ | 6 | */ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | * | 22 | * |
23 | * Should you need to contact me, the author, you can do so either by | 23 | * Should you need to contact me, the author, you can do so either by |
24 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 24 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
25 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 25 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | 31 | ||
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | #include <linux/hid-debug.h> | 33 | #include <linux/hid-debug.h> |
34 | 34 | ||
35 | #define unk KEY_UNKNOWN | 35 | #define unk KEY_UNKNOWN |
36 | 36 | ||
37 | static const unsigned char hid_keyboard[256] = { | 37 | static const unsigned char hid_keyboard[256] = { |
38 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | 38 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, |
39 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | 39 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, |
40 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | 40 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, |
41 | 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, | 41 | 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, |
42 | 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, | 42 | 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, |
43 | 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, | 43 | 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, |
44 | 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, | 44 | 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, |
45 | 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, | 45 | 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, |
46 | 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, | 46 | 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, |
47 | 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 47 | 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
48 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 48 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
49 | unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, | 49 | unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, |
50 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 50 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
51 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 51 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
52 | 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, | 52 | 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, |
53 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | 53 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static const struct { | 56 | static const struct { |
57 | __s32 x; | 57 | __s32 x; |
58 | __s32 y; | 58 | __s32 y; |
59 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; | 59 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; |
60 | 60 | ||
61 | #define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c)) | 61 | #define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c)) |
62 | #define map_rel(c) hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c)) | 62 | #define map_rel(c) hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c)) |
63 | #define map_key(c) hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c)) | 63 | #define map_key(c) hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c)) |
64 | #define map_led(c) hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c)) | 64 | #define map_led(c) hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c)) |
65 | 65 | ||
66 | #define map_abs_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ | 66 | #define map_abs_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ |
67 | &max, EV_ABS, (c)) | 67 | &max, EV_ABS, (c)) |
68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ | 68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ |
69 | &max, EV_KEY, (c)) | 69 | &max, EV_KEY, (c)) |
70 | 70 | ||
71 | static inline int match_scancode(unsigned int code, unsigned int scancode) | 71 | static inline int match_scancode(unsigned int code, unsigned int scancode) |
72 | { | 72 | { |
73 | if (scancode == 0) | 73 | if (scancode == 0) |
74 | return 1; | 74 | return 1; |
75 | 75 | ||
76 | return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; | 76 | return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; |
77 | } | 77 | } |
78 | 78 | ||
79 | static inline int match_keycode(unsigned int code, unsigned int keycode) | 79 | static inline int match_keycode(unsigned int code, unsigned int keycode) |
80 | { | 80 | { |
81 | if (keycode == 0) | 81 | if (keycode == 0) |
82 | return 1; | 82 | return 1; |
83 | 83 | ||
84 | return code == keycode; | 84 | return code == keycode; |
85 | } | 85 | } |
86 | 86 | ||
87 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, | 87 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, |
88 | unsigned int scancode, | 88 | unsigned int scancode, |
89 | unsigned int keycode) | 89 | unsigned int keycode) |
90 | { | 90 | { |
91 | int i, j, k; | 91 | int i, j, k; |
92 | struct hid_report *report; | 92 | struct hid_report *report; |
93 | struct hid_usage *usage; | 93 | struct hid_usage *usage; |
94 | 94 | ||
95 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { | 95 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { |
96 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | 96 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { |
97 | for (i = 0; i < report->maxfield; i++) { | 97 | for (i = 0; i < report->maxfield; i++) { |
98 | for ( j = 0; j < report->field[i]->maxusage; j++) { | 98 | for ( j = 0; j < report->field[i]->maxusage; j++) { |
99 | usage = report->field[i]->usage + j; | 99 | usage = report->field[i]->usage + j; |
100 | if (usage->type == EV_KEY && | 100 | if (usage->type == EV_KEY && |
101 | match_scancode(usage->hid, scancode) && | 101 | match_scancode(usage->hid, scancode) && |
102 | match_keycode(usage->code, keycode)) | 102 | match_keycode(usage->code, keycode)) |
103 | return usage; | 103 | return usage; |
104 | } | 104 | } |
105 | } | 105 | } |
106 | } | 106 | } |
107 | } | 107 | } |
108 | return NULL; | 108 | return NULL; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int hidinput_getkeycode(struct input_dev *dev, | 111 | static int hidinput_getkeycode(struct input_dev *dev, |
112 | unsigned int scancode, unsigned int *keycode) | 112 | unsigned int scancode, unsigned int *keycode) |
113 | { | 113 | { |
114 | struct hid_device *hid = input_get_drvdata(dev); | 114 | struct hid_device *hid = input_get_drvdata(dev); |
115 | struct hid_usage *usage; | 115 | struct hid_usage *usage; |
116 | 116 | ||
117 | usage = hidinput_find_key(hid, scancode, 0); | 117 | usage = hidinput_find_key(hid, scancode, 0); |
118 | if (usage) { | 118 | if (usage) { |
119 | *keycode = usage->code; | 119 | *keycode = usage->code; |
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | return -EINVAL; | 122 | return -EINVAL; |
123 | } | 123 | } |
124 | 124 | ||
125 | static int hidinput_setkeycode(struct input_dev *dev, | 125 | static int hidinput_setkeycode(struct input_dev *dev, |
126 | unsigned int scancode, unsigned int keycode) | 126 | unsigned int scancode, unsigned int keycode) |
127 | { | 127 | { |
128 | struct hid_device *hid = input_get_drvdata(dev); | 128 | struct hid_device *hid = input_get_drvdata(dev); |
129 | struct hid_usage *usage; | 129 | struct hid_usage *usage; |
130 | int old_keycode; | 130 | int old_keycode; |
131 | 131 | ||
132 | usage = hidinput_find_key(hid, scancode, 0); | 132 | usage = hidinput_find_key(hid, scancode, 0); |
133 | if (usage) { | 133 | if (usage) { |
134 | old_keycode = usage->code; | 134 | old_keycode = usage->code; |
135 | usage->code = keycode; | 135 | usage->code = keycode; |
136 | 136 | ||
137 | clear_bit(old_keycode, dev->keybit); | 137 | clear_bit(old_keycode, dev->keybit); |
138 | set_bit(usage->code, dev->keybit); | 138 | set_bit(usage->code, dev->keybit); |
139 | dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); | 139 | dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); |
140 | /* Set the keybit for the old keycode if the old keycode is used | 140 | /* Set the keybit for the old keycode if the old keycode is used |
141 | * by another key */ | 141 | * by another key */ |
142 | if (hidinput_find_key (hid, 0, old_keycode)) | 142 | if (hidinput_find_key (hid, 0, old_keycode)) |
143 | set_bit(old_keycode, dev->keybit); | 143 | set_bit(old_keycode, dev->keybit); |
144 | 144 | ||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | return -EINVAL; | 148 | return -EINVAL; |
149 | } | 149 | } |
150 | 150 | ||
151 | 151 | ||
152 | /** | 152 | /** |
153 | * hidinput_calc_abs_res - calculate an absolute axis resolution | 153 | * hidinput_calc_abs_res - calculate an absolute axis resolution |
154 | * @field: the HID report field to calculate resolution for | 154 | * @field: the HID report field to calculate resolution for |
155 | * @code: axis code | 155 | * @code: axis code |
156 | * | 156 | * |
157 | * The formula is: | 157 | * The formula is: |
158 | * (logical_maximum - logical_minimum) | 158 | * (logical_maximum - logical_minimum) |
159 | * resolution = ---------------------------------------------------------- | 159 | * resolution = ---------------------------------------------------------- |
160 | * (physical_maximum - physical_minimum) * 10 ^ unit_exponent | 160 | * (physical_maximum - physical_minimum) * 10 ^ unit_exponent |
161 | * | 161 | * |
162 | * as seen in the HID specification v1.11 6.2.2.7 Global Items. | 162 | * as seen in the HID specification v1.11 6.2.2.7 Global Items. |
163 | * | 163 | * |
164 | * Only exponent 1 length units are processed. Centimeters are converted to | 164 | * Only exponent 1 length units are processed. Centimeters are converted to |
165 | * inches. Degrees are converted to radians. | 165 | * inches. Degrees are converted to radians. |
166 | */ | 166 | */ |
167 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | 167 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) |
168 | { | 168 | { |
169 | __s32 unit_exponent = field->unit_exponent; | 169 | __s32 unit_exponent = field->unit_exponent; |
170 | __s32 logical_extents = field->logical_maximum - | 170 | __s32 logical_extents = field->logical_maximum - |
171 | field->logical_minimum; | 171 | field->logical_minimum; |
172 | __s32 physical_extents = field->physical_maximum - | 172 | __s32 physical_extents = field->physical_maximum - |
173 | field->physical_minimum; | 173 | field->physical_minimum; |
174 | __s32 prev; | 174 | __s32 prev; |
175 | 175 | ||
176 | /* Check if the extents are sane */ | 176 | /* Check if the extents are sane */ |
177 | if (logical_extents <= 0 || physical_extents <= 0) | 177 | if (logical_extents <= 0 || physical_extents <= 0) |
178 | return 0; | 178 | return 0; |
179 | 179 | ||
180 | /* | 180 | /* |
181 | * Verify and convert units. | 181 | * Verify and convert units. |
182 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding | 182 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding |
183 | */ | 183 | */ |
184 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { | 184 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { |
185 | if (field->unit == 0x11) { /* If centimeters */ | 185 | if (field->unit == 0x11) { /* If centimeters */ |
186 | /* Convert to inches */ | 186 | /* Convert to inches */ |
187 | prev = logical_extents; | 187 | prev = logical_extents; |
188 | logical_extents *= 254; | 188 | logical_extents *= 254; |
189 | if (logical_extents < prev) | 189 | if (logical_extents < prev) |
190 | return 0; | 190 | return 0; |
191 | unit_exponent += 2; | 191 | unit_exponent += 2; |
192 | } else if (field->unit != 0x13) { /* If not inches */ | 192 | } else if (field->unit != 0x13) { /* If not inches */ |
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { | 195 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { |
196 | if (field->unit == 0x14) { /* If degrees */ | 196 | if (field->unit == 0x14) { /* If degrees */ |
197 | /* Convert to radians */ | 197 | /* Convert to radians */ |
198 | prev = logical_extents; | 198 | prev = logical_extents; |
199 | logical_extents *= 573; | 199 | logical_extents *= 573; |
200 | if (logical_extents < prev) | 200 | if (logical_extents < prev) |
201 | return 0; | 201 | return 0; |
202 | unit_exponent += 1; | 202 | unit_exponent += 1; |
203 | } else if (field->unit != 0x12) { /* If not radians */ | 203 | } else if (field->unit != 0x12) { /* If not radians */ |
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | } else { | 206 | } else { |
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | /* Apply negative unit exponent */ | 210 | /* Apply negative unit exponent */ |
211 | for (; unit_exponent < 0; unit_exponent++) { | 211 | for (; unit_exponent < 0; unit_exponent++) { |
212 | prev = logical_extents; | 212 | prev = logical_extents; |
213 | logical_extents *= 10; | 213 | logical_extents *= 10; |
214 | if (logical_extents < prev) | 214 | if (logical_extents < prev) |
215 | return 0; | 215 | return 0; |
216 | } | 216 | } |
217 | /* Apply positive unit exponent */ | 217 | /* Apply positive unit exponent */ |
218 | for (; unit_exponent > 0; unit_exponent--) { | 218 | for (; unit_exponent > 0; unit_exponent--) { |
219 | prev = physical_extents; | 219 | prev = physical_extents; |
220 | physical_extents *= 10; | 220 | physical_extents *= 10; |
221 | if (physical_extents < prev) | 221 | if (physical_extents < prev) |
222 | return 0; | 222 | return 0; |
223 | } | 223 | } |
224 | 224 | ||
225 | /* Calculate resolution */ | 225 | /* Calculate resolution */ |
226 | return logical_extents / physical_extents; | 226 | return logical_extents / physical_extents; |
227 | } | 227 | } |
228 | 228 | ||
229 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | 229 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, |
230 | struct hid_usage *usage) | 230 | struct hid_usage *usage) |
231 | { | 231 | { |
232 | struct input_dev *input = hidinput->input; | 232 | struct input_dev *input = hidinput->input; |
233 | struct hid_device *device = input_get_drvdata(input); | 233 | struct hid_device *device = input_get_drvdata(input); |
234 | int max = 0, code; | 234 | int max = 0, code; |
235 | unsigned long *bit = NULL; | 235 | unsigned long *bit = NULL; |
236 | 236 | ||
237 | field->hidinput = hidinput; | 237 | field->hidinput = hidinput; |
238 | 238 | ||
239 | if (field->flags & HID_MAIN_ITEM_CONSTANT) | 239 | if (field->flags & HID_MAIN_ITEM_CONSTANT) |
240 | goto ignore; | 240 | goto ignore; |
241 | 241 | ||
242 | /* only LED usages are supported in output fields */ | 242 | /* only LED usages are supported in output fields */ |
243 | if (field->report_type == HID_OUTPUT_REPORT && | 243 | if (field->report_type == HID_OUTPUT_REPORT && |
244 | (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { | 244 | (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { |
245 | goto ignore; | 245 | goto ignore; |
246 | } | 246 | } |
247 | 247 | ||
248 | if (device->driver->input_mapping) { | 248 | if (device->driver->input_mapping) { |
249 | int ret = device->driver->input_mapping(device, hidinput, field, | 249 | int ret = device->driver->input_mapping(device, hidinput, field, |
250 | usage, &bit, &max); | 250 | usage, &bit, &max); |
251 | if (ret > 0) | 251 | if (ret > 0) |
252 | goto mapped; | 252 | goto mapped; |
253 | if (ret < 0) | 253 | if (ret < 0) |
254 | goto ignore; | 254 | goto ignore; |
255 | } | 255 | } |
256 | 256 | ||
257 | switch (usage->hid & HID_USAGE_PAGE) { | 257 | switch (usage->hid & HID_USAGE_PAGE) { |
258 | case HID_UP_UNDEFINED: | 258 | case HID_UP_UNDEFINED: |
259 | goto ignore; | 259 | goto ignore; |
260 | 260 | ||
261 | case HID_UP_KEYBOARD: | 261 | case HID_UP_KEYBOARD: |
262 | set_bit(EV_REP, input->evbit); | 262 | set_bit(EV_REP, input->evbit); |
263 | 263 | ||
264 | if ((usage->hid & HID_USAGE) < 256) { | 264 | if ((usage->hid & HID_USAGE) < 256) { |
265 | if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; | 265 | if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; |
266 | map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); | 266 | map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); |
267 | } else | 267 | } else |
268 | map_key(KEY_UNKNOWN); | 268 | map_key(KEY_UNKNOWN); |
269 | 269 | ||
270 | break; | 270 | break; |
271 | 271 | ||
272 | case HID_UP_BUTTON: | 272 | case HID_UP_BUTTON: |
273 | code = ((usage->hid - 1) & HID_USAGE); | 273 | code = ((usage->hid - 1) & HID_USAGE); |
274 | 274 | ||
275 | switch (field->application) { | 275 | switch (field->application) { |
276 | case HID_GD_MOUSE: | 276 | case HID_GD_MOUSE: |
277 | case HID_GD_POINTER: code += 0x110; break; | 277 | case HID_GD_POINTER: code += 0x110; break; |
278 | case HID_GD_JOYSTICK: | 278 | case HID_GD_JOYSTICK: |
279 | if (code <= 0xf) | 279 | if (code <= 0xf) |
280 | code += BTN_JOYSTICK; | 280 | code += BTN_JOYSTICK; |
281 | else | 281 | else |
282 | code += BTN_TRIGGER_HAPPY; | 282 | code += BTN_TRIGGER_HAPPY; |
283 | break; | 283 | break; |
284 | case HID_GD_GAMEPAD: code += 0x130; break; | 284 | case HID_GD_GAMEPAD: code += 0x130; break; |
285 | default: | 285 | default: |
286 | switch (field->physical) { | 286 | switch (field->physical) { |
287 | case HID_GD_MOUSE: | 287 | case HID_GD_MOUSE: |
288 | case HID_GD_POINTER: code += 0x110; break; | 288 | case HID_GD_POINTER: code += 0x110; break; |
289 | case HID_GD_JOYSTICK: code += 0x120; break; | 289 | case HID_GD_JOYSTICK: code += 0x120; break; |
290 | case HID_GD_GAMEPAD: code += 0x130; break; | 290 | case HID_GD_GAMEPAD: code += 0x130; break; |
291 | default: code += 0x100; | 291 | default: code += 0x100; |
292 | } | 292 | } |
293 | } | 293 | } |
294 | 294 | ||
295 | map_key(code); | 295 | map_key(code); |
296 | break; | 296 | break; |
297 | 297 | ||
298 | case HID_UP_SIMULATION: | 298 | case HID_UP_SIMULATION: |
299 | switch (usage->hid & 0xffff) { | 299 | switch (usage->hid & 0xffff) { |
300 | case 0xba: map_abs(ABS_RUDDER); break; | 300 | case 0xba: map_abs(ABS_RUDDER); break; |
301 | case 0xbb: map_abs(ABS_THROTTLE); break; | 301 | case 0xbb: map_abs(ABS_THROTTLE); break; |
302 | case 0xc4: map_abs(ABS_GAS); break; | 302 | case 0xc4: map_abs(ABS_GAS); break; |
303 | case 0xc5: map_abs(ABS_BRAKE); break; | 303 | case 0xc5: map_abs(ABS_BRAKE); break; |
304 | case 0xc8: map_abs(ABS_WHEEL); break; | 304 | case 0xc8: map_abs(ABS_WHEEL); break; |
305 | default: goto ignore; | 305 | default: goto ignore; |
306 | } | 306 | } |
307 | break; | 307 | break; |
308 | 308 | ||
309 | case HID_UP_GENDESK: | 309 | case HID_UP_GENDESK: |
310 | if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ | 310 | if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ |
311 | switch (usage->hid & 0xf) { | 311 | switch (usage->hid & 0xf) { |
312 | case 0x1: map_key_clear(KEY_POWER); break; | 312 | case 0x1: map_key_clear(KEY_POWER); break; |
313 | case 0x2: map_key_clear(KEY_SLEEP); break; | 313 | case 0x2: map_key_clear(KEY_SLEEP); break; |
314 | case 0x3: map_key_clear(KEY_WAKEUP); break; | 314 | case 0x3: map_key_clear(KEY_WAKEUP); break; |
315 | default: goto unknown; | 315 | default: goto unknown; |
316 | } | 316 | } |
317 | break; | 317 | break; |
318 | } | 318 | } |
319 | 319 | ||
320 | if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ | 320 | if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ |
321 | switch (usage->hid) { | 321 | switch (usage->hid) { |
322 | case HID_GD_UP: usage->hat_dir = 1; break; | 322 | case HID_GD_UP: usage->hat_dir = 1; break; |
323 | case HID_GD_DOWN: usage->hat_dir = 5; break; | 323 | case HID_GD_DOWN: usage->hat_dir = 5; break; |
324 | case HID_GD_RIGHT: usage->hat_dir = 3; break; | 324 | case HID_GD_RIGHT: usage->hat_dir = 3; break; |
325 | case HID_GD_LEFT: usage->hat_dir = 7; break; | 325 | case HID_GD_LEFT: usage->hat_dir = 7; break; |
326 | default: goto unknown; | 326 | default: goto unknown; |
327 | } | 327 | } |
328 | if (field->dpad) { | 328 | if (field->dpad) { |
329 | map_abs(field->dpad); | 329 | map_abs(field->dpad); |
330 | goto ignore; | 330 | goto ignore; |
331 | } | 331 | } |
332 | map_abs(ABS_HAT0X); | 332 | map_abs(ABS_HAT0X); |
333 | break; | 333 | break; |
334 | } | 334 | } |
335 | 335 | ||
336 | switch (usage->hid) { | 336 | switch (usage->hid) { |
337 | /* These usage IDs map directly to the usage codes. */ | 337 | /* These usage IDs map directly to the usage codes. */ |
338 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: | 338 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: |
339 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: | 339 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: |
340 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: | 340 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: |
341 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | 341 | if (field->flags & HID_MAIN_ITEM_RELATIVE) |
342 | map_rel(usage->hid & 0xf); | 342 | map_rel(usage->hid & 0xf); |
343 | else | 343 | else |
344 | map_abs(usage->hid & 0xf); | 344 | map_abs(usage->hid & 0xf); |
345 | break; | 345 | break; |
346 | 346 | ||
347 | case HID_GD_HATSWITCH: | 347 | case HID_GD_HATSWITCH: |
348 | usage->hat_min = field->logical_minimum; | 348 | usage->hat_min = field->logical_minimum; |
349 | usage->hat_max = field->logical_maximum; | 349 | usage->hat_max = field->logical_maximum; |
350 | map_abs(ABS_HAT0X); | 350 | map_abs(ABS_HAT0X); |
351 | break; | 351 | break; |
352 | 352 | ||
353 | case HID_GD_START: map_key_clear(BTN_START); break; | 353 | case HID_GD_START: map_key_clear(BTN_START); break; |
354 | case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; | 354 | case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; |
355 | 355 | ||
356 | default: goto unknown; | 356 | default: goto unknown; |
357 | } | 357 | } |
358 | 358 | ||
359 | break; | 359 | break; |
360 | 360 | ||
361 | case HID_UP_LED: | 361 | case HID_UP_LED: |
362 | switch (usage->hid & 0xffff) { /* HID-Value: */ | 362 | switch (usage->hid & 0xffff) { /* HID-Value: */ |
363 | case 0x01: map_led (LED_NUML); break; /* "Num Lock" */ | 363 | case 0x01: map_led (LED_NUML); break; /* "Num Lock" */ |
364 | case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */ | 364 | case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */ |
365 | case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */ | 365 | case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */ |
366 | case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */ | 366 | case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */ |
367 | case 0x05: map_led (LED_KANA); break; /* "Kana" */ | 367 | case 0x05: map_led (LED_KANA); break; /* "Kana" */ |
368 | case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */ | 368 | case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */ |
369 | case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */ | 369 | case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */ |
370 | case 0x09: map_led (LED_MUTE); break; /* "Mute" */ | 370 | case 0x09: map_led (LED_MUTE); break; /* "Mute" */ |
371 | case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ | 371 | case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ |
372 | case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ | 372 | case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ |
373 | case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ | 373 | case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ |
374 | 374 | ||
375 | default: goto ignore; | 375 | default: goto ignore; |
376 | } | 376 | } |
377 | break; | 377 | break; |
378 | 378 | ||
379 | case HID_UP_DIGITIZER: | 379 | case HID_UP_DIGITIZER: |
380 | switch (usage->hid & 0xff) { | 380 | switch (usage->hid & 0xff) { |
381 | case 0x00: /* Undefined */ | 381 | case 0x00: /* Undefined */ |
382 | goto ignore; | 382 | goto ignore; |
383 | 383 | ||
384 | case 0x30: /* TipPressure */ | 384 | case 0x30: /* TipPressure */ |
385 | if (!test_bit(BTN_TOUCH, input->keybit)) { | 385 | if (!test_bit(BTN_TOUCH, input->keybit)) { |
386 | device->quirks |= HID_QUIRK_NOTOUCH; | 386 | device->quirks |= HID_QUIRK_NOTOUCH; |
387 | set_bit(EV_KEY, input->evbit); | 387 | set_bit(EV_KEY, input->evbit); |
388 | set_bit(BTN_TOUCH, input->keybit); | 388 | set_bit(BTN_TOUCH, input->keybit); |
389 | } | 389 | } |
390 | map_abs_clear(ABS_PRESSURE); | 390 | map_abs_clear(ABS_PRESSURE); |
391 | break; | 391 | break; |
392 | 392 | ||
393 | case 0x32: /* InRange */ | 393 | case 0x32: /* InRange */ |
394 | switch (field->physical & 0xff) { | 394 | switch (field->physical & 0xff) { |
395 | case 0x21: map_key(BTN_TOOL_MOUSE); break; | 395 | case 0x21: map_key(BTN_TOOL_MOUSE); break; |
396 | case 0x22: map_key(BTN_TOOL_FINGER); break; | 396 | case 0x22: map_key(BTN_TOOL_FINGER); break; |
397 | default: map_key(BTN_TOOL_PEN); break; | 397 | default: map_key(BTN_TOOL_PEN); break; |
398 | } | 398 | } |
399 | break; | 399 | break; |
400 | 400 | ||
401 | case 0x3c: /* Invert */ | 401 | case 0x3c: /* Invert */ |
402 | map_key_clear(BTN_TOOL_RUBBER); | 402 | map_key_clear(BTN_TOOL_RUBBER); |
403 | break; | 403 | break; |
404 | 404 | ||
405 | case 0x33: /* Touch */ | 405 | case 0x33: /* Touch */ |
406 | case 0x42: /* TipSwitch */ | 406 | case 0x42: /* TipSwitch */ |
407 | case 0x43: /* TipSwitch2 */ | 407 | case 0x43: /* TipSwitch2 */ |
408 | device->quirks &= ~HID_QUIRK_NOTOUCH; | 408 | device->quirks &= ~HID_QUIRK_NOTOUCH; |
409 | map_key_clear(BTN_TOUCH); | 409 | map_key_clear(BTN_TOUCH); |
410 | break; | 410 | break; |
411 | 411 | ||
412 | case 0x44: /* BarrelSwitch */ | 412 | case 0x44: /* BarrelSwitch */ |
413 | map_key_clear(BTN_STYLUS); | 413 | map_key_clear(BTN_STYLUS); |
414 | break; | 414 | break; |
415 | 415 | ||
416 | default: goto unknown; | 416 | default: goto unknown; |
417 | } | 417 | } |
418 | break; | 418 | break; |
419 | 419 | ||
420 | case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ | 420 | case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ |
421 | switch (usage->hid & HID_USAGE) { | 421 | switch (usage->hid & HID_USAGE) { |
422 | case 0x000: goto ignore; | 422 | case 0x000: goto ignore; |
423 | case 0x034: map_key_clear(KEY_SLEEP); break; | 423 | case 0x034: map_key_clear(KEY_SLEEP); break; |
424 | case 0x036: map_key_clear(BTN_MISC); break; | 424 | case 0x036: map_key_clear(BTN_MISC); break; |
425 | 425 | ||
426 | case 0x040: map_key_clear(KEY_MENU); break; | 426 | case 0x040: map_key_clear(KEY_MENU); break; |
427 | case 0x045: map_key_clear(KEY_RADIO); break; | 427 | case 0x045: map_key_clear(KEY_RADIO); break; |
428 | 428 | ||
429 | case 0x083: map_key_clear(KEY_LAST); break; | 429 | case 0x083: map_key_clear(KEY_LAST); break; |
430 | case 0x088: map_key_clear(KEY_PC); break; | 430 | case 0x088: map_key_clear(KEY_PC); break; |
431 | case 0x089: map_key_clear(KEY_TV); break; | 431 | case 0x089: map_key_clear(KEY_TV); break; |
432 | case 0x08a: map_key_clear(KEY_WWW); break; | 432 | case 0x08a: map_key_clear(KEY_WWW); break; |
433 | case 0x08b: map_key_clear(KEY_DVD); break; | 433 | case 0x08b: map_key_clear(KEY_DVD); break; |
434 | case 0x08c: map_key_clear(KEY_PHONE); break; | 434 | case 0x08c: map_key_clear(KEY_PHONE); break; |
435 | case 0x08d: map_key_clear(KEY_PROGRAM); break; | 435 | case 0x08d: map_key_clear(KEY_PROGRAM); break; |
436 | case 0x08e: map_key_clear(KEY_VIDEOPHONE); break; | 436 | case 0x08e: map_key_clear(KEY_VIDEOPHONE); break; |
437 | case 0x08f: map_key_clear(KEY_GAMES); break; | 437 | case 0x08f: map_key_clear(KEY_GAMES); break; |
438 | case 0x090: map_key_clear(KEY_MEMO); break; | 438 | case 0x090: map_key_clear(KEY_MEMO); break; |
439 | case 0x091: map_key_clear(KEY_CD); break; | 439 | case 0x091: map_key_clear(KEY_CD); break; |
440 | case 0x092: map_key_clear(KEY_VCR); break; | 440 | case 0x092: map_key_clear(KEY_VCR); break; |
441 | case 0x093: map_key_clear(KEY_TUNER); break; | 441 | case 0x093: map_key_clear(KEY_TUNER); break; |
442 | case 0x094: map_key_clear(KEY_EXIT); break; | 442 | case 0x094: map_key_clear(KEY_EXIT); break; |
443 | case 0x095: map_key_clear(KEY_HELP); break; | 443 | case 0x095: map_key_clear(KEY_HELP); break; |
444 | case 0x096: map_key_clear(KEY_TAPE); break; | 444 | case 0x096: map_key_clear(KEY_TAPE); break; |
445 | case 0x097: map_key_clear(KEY_TV2); break; | 445 | case 0x097: map_key_clear(KEY_TV2); break; |
446 | case 0x098: map_key_clear(KEY_SAT); break; | 446 | case 0x098: map_key_clear(KEY_SAT); break; |
447 | case 0x09a: map_key_clear(KEY_PVR); break; | 447 | case 0x09a: map_key_clear(KEY_PVR); break; |
448 | 448 | ||
449 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; | 449 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; |
450 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; | 450 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; |
451 | case 0x0a0: map_key_clear(KEY_VCR2); break; | 451 | case 0x0a0: map_key_clear(KEY_VCR2); break; |
452 | 452 | ||
453 | case 0x0b0: map_key_clear(KEY_PLAY); break; | 453 | case 0x0b0: map_key_clear(KEY_PLAY); break; |
454 | case 0x0b1: map_key_clear(KEY_PAUSE); break; | 454 | case 0x0b1: map_key_clear(KEY_PAUSE); break; |
455 | case 0x0b2: map_key_clear(KEY_RECORD); break; | 455 | case 0x0b2: map_key_clear(KEY_RECORD); break; |
456 | case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; | 456 | case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; |
457 | case 0x0b4: map_key_clear(KEY_REWIND); break; | 457 | case 0x0b4: map_key_clear(KEY_REWIND); break; |
458 | case 0x0b5: map_key_clear(KEY_NEXTSONG); break; | 458 | case 0x0b5: map_key_clear(KEY_NEXTSONG); break; |
459 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; | 459 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; |
460 | case 0x0b7: map_key_clear(KEY_STOPCD); break; | 460 | case 0x0b7: map_key_clear(KEY_STOPCD); break; |
461 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; | 461 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; |
462 | case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; | 462 | case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; |
463 | 463 | ||
464 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; | 464 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; |
465 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; | 465 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; |
466 | case 0x0e2: map_key_clear(KEY_MUTE); break; | 466 | case 0x0e2: map_key_clear(KEY_MUTE); break; |
467 | case 0x0e5: map_key_clear(KEY_BASSBOOST); break; | 467 | case 0x0e5: map_key_clear(KEY_BASSBOOST); break; |
468 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 468 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
469 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 469 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
470 | 470 | ||
471 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; | 471 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; |
472 | case 0x183: map_key_clear(KEY_CONFIG); break; | 472 | case 0x183: map_key_clear(KEY_CONFIG); break; |
473 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; | 473 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; |
474 | case 0x185: map_key_clear(KEY_EDITOR); break; | 474 | case 0x185: map_key_clear(KEY_EDITOR); break; |
475 | case 0x186: map_key_clear(KEY_SPREADSHEET); break; | 475 | case 0x186: map_key_clear(KEY_SPREADSHEET); break; |
476 | case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break; | 476 | case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break; |
477 | case 0x188: map_key_clear(KEY_PRESENTATION); break; | 477 | case 0x188: map_key_clear(KEY_PRESENTATION); break; |
478 | case 0x189: map_key_clear(KEY_DATABASE); break; | 478 | case 0x189: map_key_clear(KEY_DATABASE); break; |
479 | case 0x18a: map_key_clear(KEY_MAIL); break; | 479 | case 0x18a: map_key_clear(KEY_MAIL); break; |
480 | case 0x18b: map_key_clear(KEY_NEWS); break; | 480 | case 0x18b: map_key_clear(KEY_NEWS); break; |
481 | case 0x18c: map_key_clear(KEY_VOICEMAIL); break; | 481 | case 0x18c: map_key_clear(KEY_VOICEMAIL); break; |
482 | case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break; | 482 | case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break; |
483 | case 0x18e: map_key_clear(KEY_CALENDAR); break; | 483 | case 0x18e: map_key_clear(KEY_CALENDAR); break; |
484 | case 0x191: map_key_clear(KEY_FINANCE); break; | 484 | case 0x191: map_key_clear(KEY_FINANCE); break; |
485 | case 0x192: map_key_clear(KEY_CALC); break; | 485 | case 0x192: map_key_clear(KEY_CALC); break; |
486 | case 0x194: map_key_clear(KEY_FILE); break; | 486 | case 0x194: map_key_clear(KEY_FILE); break; |
487 | case 0x196: map_key_clear(KEY_WWW); break; | 487 | case 0x196: map_key_clear(KEY_WWW); break; |
488 | case 0x199: map_key_clear(KEY_CHAT); break; | 488 | case 0x199: map_key_clear(KEY_CHAT); break; |
489 | case 0x19c: map_key_clear(KEY_LOGOFF); break; | 489 | case 0x19c: map_key_clear(KEY_LOGOFF); break; |
490 | case 0x19e: map_key_clear(KEY_COFFEE); break; | 490 | case 0x19e: map_key_clear(KEY_COFFEE); break; |
491 | case 0x1a6: map_key_clear(KEY_HELP); break; | 491 | case 0x1a6: map_key_clear(KEY_HELP); break; |
492 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; | 492 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; |
493 | case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; | 493 | case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; |
494 | case 0x1b6: map_key_clear(KEY_MEDIA); break; | 494 | case 0x1b6: map_key_clear(KEY_MEDIA); break; |
495 | case 0x1b7: map_key_clear(KEY_SOUND); break; | 495 | case 0x1b7: map_key_clear(KEY_SOUND); break; |
496 | case 0x1bc: map_key_clear(KEY_MESSENGER); break; | 496 | case 0x1bc: map_key_clear(KEY_MESSENGER); break; |
497 | case 0x1bd: map_key_clear(KEY_INFO); break; | 497 | case 0x1bd: map_key_clear(KEY_INFO); break; |
498 | case 0x201: map_key_clear(KEY_NEW); break; | 498 | case 0x201: map_key_clear(KEY_NEW); break; |
499 | case 0x202: map_key_clear(KEY_OPEN); break; | 499 | case 0x202: map_key_clear(KEY_OPEN); break; |
500 | case 0x203: map_key_clear(KEY_CLOSE); break; | 500 | case 0x203: map_key_clear(KEY_CLOSE); break; |
501 | case 0x204: map_key_clear(KEY_EXIT); break; | 501 | case 0x204: map_key_clear(KEY_EXIT); break; |
502 | case 0x207: map_key_clear(KEY_SAVE); break; | 502 | case 0x207: map_key_clear(KEY_SAVE); break; |
503 | case 0x208: map_key_clear(KEY_PRINT); break; | 503 | case 0x208: map_key_clear(KEY_PRINT); break; |
504 | case 0x209: map_key_clear(KEY_PROPS); break; | 504 | case 0x209: map_key_clear(KEY_PROPS); break; |
505 | case 0x21a: map_key_clear(KEY_UNDO); break; | 505 | case 0x21a: map_key_clear(KEY_UNDO); break; |
506 | case 0x21b: map_key_clear(KEY_COPY); break; | 506 | case 0x21b: map_key_clear(KEY_COPY); break; |
507 | case 0x21c: map_key_clear(KEY_CUT); break; | 507 | case 0x21c: map_key_clear(KEY_CUT); break; |
508 | case 0x21d: map_key_clear(KEY_PASTE); break; | 508 | case 0x21d: map_key_clear(KEY_PASTE); break; |
509 | case 0x21f: map_key_clear(KEY_FIND); break; | 509 | case 0x21f: map_key_clear(KEY_FIND); break; |
510 | case 0x221: map_key_clear(KEY_SEARCH); break; | 510 | case 0x221: map_key_clear(KEY_SEARCH); break; |
511 | case 0x222: map_key_clear(KEY_GOTO); break; | 511 | case 0x222: map_key_clear(KEY_GOTO); break; |
512 | case 0x223: map_key_clear(KEY_HOMEPAGE); break; | 512 | case 0x223: map_key_clear(KEY_HOMEPAGE); break; |
513 | case 0x224: map_key_clear(KEY_BACK); break; | 513 | case 0x224: map_key_clear(KEY_BACK); break; |
514 | case 0x225: map_key_clear(KEY_FORWARD); break; | 514 | case 0x225: map_key_clear(KEY_FORWARD); break; |
515 | case 0x226: map_key_clear(KEY_STOP); break; | 515 | case 0x226: map_key_clear(KEY_STOP); break; |
516 | case 0x227: map_key_clear(KEY_REFRESH); break; | 516 | case 0x227: map_key_clear(KEY_REFRESH); break; |
517 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; | 517 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; |
518 | case 0x22d: map_key_clear(KEY_ZOOMIN); break; | 518 | case 0x22d: map_key_clear(KEY_ZOOMIN); break; |
519 | case 0x22e: map_key_clear(KEY_ZOOMOUT); break; | 519 | case 0x22e: map_key_clear(KEY_ZOOMOUT); break; |
520 | case 0x22f: map_key_clear(KEY_ZOOMRESET); break; | 520 | case 0x22f: map_key_clear(KEY_ZOOMRESET); break; |
521 | case 0x233: map_key_clear(KEY_SCROLLUP); break; | 521 | case 0x233: map_key_clear(KEY_SCROLLUP); break; |
522 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; | 522 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; |
523 | case 0x238: map_rel(REL_HWHEEL); break; | 523 | case 0x238: map_rel(REL_HWHEEL); break; |
524 | case 0x25f: map_key_clear(KEY_CANCEL); break; | 524 | case 0x25f: map_key_clear(KEY_CANCEL); break; |
525 | case 0x279: map_key_clear(KEY_REDO); break; | 525 | case 0x279: map_key_clear(KEY_REDO); break; |
526 | 526 | ||
527 | case 0x289: map_key_clear(KEY_REPLY); break; | 527 | case 0x289: map_key_clear(KEY_REPLY); break; |
528 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 528 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
529 | case 0x28c: map_key_clear(KEY_SEND); break; | 529 | case 0x28c: map_key_clear(KEY_SEND); break; |
530 | 530 | ||
531 | default: goto ignore; | 531 | default: goto ignore; |
532 | } | 532 | } |
533 | break; | 533 | break; |
534 | 534 | ||
535 | case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ | 535 | case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ |
536 | set_bit(EV_REP, input->evbit); | 536 | set_bit(EV_REP, input->evbit); |
537 | switch (usage->hid & HID_USAGE) { | 537 | switch (usage->hid & HID_USAGE) { |
538 | case 0x021: map_key_clear(KEY_PRINT); break; | 538 | case 0x021: map_key_clear(KEY_PRINT); break; |
539 | case 0x070: map_key_clear(KEY_HP); break; | 539 | case 0x070: map_key_clear(KEY_HP); break; |
540 | case 0x071: map_key_clear(KEY_CAMERA); break; | 540 | case 0x071: map_key_clear(KEY_CAMERA); break; |
541 | case 0x072: map_key_clear(KEY_SOUND); break; | 541 | case 0x072: map_key_clear(KEY_SOUND); break; |
542 | case 0x073: map_key_clear(KEY_QUESTION); break; | 542 | case 0x073: map_key_clear(KEY_QUESTION); break; |
543 | case 0x080: map_key_clear(KEY_EMAIL); break; | 543 | case 0x080: map_key_clear(KEY_EMAIL); break; |
544 | case 0x081: map_key_clear(KEY_CHAT); break; | 544 | case 0x081: map_key_clear(KEY_CHAT); break; |
545 | case 0x082: map_key_clear(KEY_SEARCH); break; | 545 | case 0x082: map_key_clear(KEY_SEARCH); break; |
546 | case 0x083: map_key_clear(KEY_CONNECT); break; | 546 | case 0x083: map_key_clear(KEY_CONNECT); break; |
547 | case 0x084: map_key_clear(KEY_FINANCE); break; | 547 | case 0x084: map_key_clear(KEY_FINANCE); break; |
548 | case 0x085: map_key_clear(KEY_SPORT); break; | 548 | case 0x085: map_key_clear(KEY_SPORT); break; |
549 | case 0x086: map_key_clear(KEY_SHOP); break; | 549 | case 0x086: map_key_clear(KEY_SHOP); break; |
550 | default: goto ignore; | 550 | default: goto ignore; |
551 | } | 551 | } |
552 | break; | 552 | break; |
553 | 553 | ||
554 | case HID_UP_MSVENDOR: | 554 | case HID_UP_MSVENDOR: |
555 | goto ignore; | 555 | goto ignore; |
556 | 556 | ||
557 | case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ | 557 | case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ |
558 | set_bit(EV_REP, input->evbit); | 558 | set_bit(EV_REP, input->evbit); |
559 | goto ignore; | 559 | goto ignore; |
560 | 560 | ||
561 | case HID_UP_LOGIVENDOR: | 561 | case HID_UP_LOGIVENDOR: |
562 | goto ignore; | 562 | goto ignore; |
563 | 563 | ||
564 | case HID_UP_PID: | 564 | case HID_UP_PID: |
565 | switch (usage->hid & HID_USAGE) { | 565 | switch (usage->hid & HID_USAGE) { |
566 | case 0xa4: map_key_clear(BTN_DEAD); break; | 566 | case 0xa4: map_key_clear(BTN_DEAD); break; |
567 | default: goto ignore; | 567 | default: goto ignore; |
568 | } | 568 | } |
569 | break; | 569 | break; |
570 | 570 | ||
571 | default: | 571 | default: |
572 | unknown: | 572 | unknown: |
573 | if (field->report_size == 1) { | 573 | if (field->report_size == 1) { |
574 | if (field->report->type == HID_OUTPUT_REPORT) { | 574 | if (field->report->type == HID_OUTPUT_REPORT) { |
575 | map_led(LED_MISC); | 575 | map_led(LED_MISC); |
576 | break; | 576 | break; |
577 | } | 577 | } |
578 | map_key(BTN_MISC); | 578 | map_key(BTN_MISC); |
579 | break; | 579 | break; |
580 | } | 580 | } |
581 | if (field->flags & HID_MAIN_ITEM_RELATIVE) { | 581 | if (field->flags & HID_MAIN_ITEM_RELATIVE) { |
582 | map_rel(REL_MISC); | 582 | map_rel(REL_MISC); |
583 | break; | 583 | break; |
584 | } | 584 | } |
585 | map_abs(ABS_MISC); | 585 | map_abs(ABS_MISC); |
586 | break; | 586 | break; |
587 | } | 587 | } |
588 | 588 | ||
589 | mapped: | 589 | mapped: |
590 | if (device->driver->input_mapped && device->driver->input_mapped(device, | 590 | if (device->driver->input_mapped && device->driver->input_mapped(device, |
591 | hidinput, field, usage, &bit, &max) < 0) | 591 | hidinput, field, usage, &bit, &max) < 0) |
592 | goto ignore; | 592 | goto ignore; |
593 | 593 | ||
594 | set_bit(usage->type, input->evbit); | 594 | set_bit(usage->type, input->evbit); |
595 | 595 | ||
596 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) | 596 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) |
597 | usage->code = find_next_zero_bit(bit, max + 1, usage->code); | 597 | usage->code = find_next_zero_bit(bit, max + 1, usage->code); |
598 | 598 | ||
599 | if (usage->code > max) | 599 | if (usage->code > max) |
600 | goto ignore; | 600 | goto ignore; |
601 | 601 | ||
602 | 602 | ||
603 | if (usage->type == EV_ABS) { | 603 | if (usage->type == EV_ABS) { |
604 | 604 | ||
605 | int a = field->logical_minimum; | 605 | int a = field->logical_minimum; |
606 | int b = field->logical_maximum; | 606 | int b = field->logical_maximum; |
607 | 607 | ||
608 | if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) { | 608 | if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) { |
609 | a = field->logical_minimum = 0; | 609 | a = field->logical_minimum = 0; |
610 | b = field->logical_maximum = 255; | 610 | b = field->logical_maximum = 255; |
611 | } | 611 | } |
612 | 612 | ||
613 | if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) | 613 | if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) |
614 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); | 614 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); |
615 | else input_set_abs_params(input, usage->code, a, b, 0, 0); | 615 | else input_set_abs_params(input, usage->code, a, b, 0, 0); |
616 | 616 | ||
617 | input_abs_set_res(input, usage->code, | 617 | input_abs_set_res(input, usage->code, |
618 | hidinput_calc_abs_res(field, usage->code)); | 618 | hidinput_calc_abs_res(field, usage->code)); |
619 | 619 | ||
620 | /* use a larger default input buffer for MT devices */ | 620 | /* use a larger default input buffer for MT devices */ |
621 | if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0) | 621 | if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0) |
622 | input_set_events_per_packet(input, 60); | 622 | input_set_events_per_packet(input, 60); |
623 | } | 623 | } |
624 | 624 | ||
625 | if (usage->type == EV_ABS && | 625 | if (usage->type == EV_ABS && |
626 | (usage->hat_min < usage->hat_max || usage->hat_dir)) { | 626 | (usage->hat_min < usage->hat_max || usage->hat_dir)) { |
627 | int i; | 627 | int i; |
628 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { | 628 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { |
629 | input_set_abs_params(input, i, -1, 1, 0, 0); | 629 | input_set_abs_params(input, i, -1, 1, 0, 0); |
630 | set_bit(i, input->absbit); | 630 | set_bit(i, input->absbit); |
631 | } | 631 | } |
632 | if (usage->hat_dir && !field->dpad) | 632 | if (usage->hat_dir && !field->dpad) |
633 | field->dpad = usage->code; | 633 | field->dpad = usage->code; |
634 | } | 634 | } |
635 | 635 | ||
636 | /* for those devices which produce Consumer volume usage as relative, | 636 | /* for those devices which produce Consumer volume usage as relative, |
637 | * we emulate pressing volumeup/volumedown appropriate number of times | 637 | * we emulate pressing volumeup/volumedown appropriate number of times |
638 | * in hidinput_hid_event() | 638 | * in hidinput_hid_event() |
639 | */ | 639 | */ |
640 | if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && | 640 | if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && |
641 | (usage->code == ABS_VOLUME)) { | 641 | (usage->code == ABS_VOLUME)) { |
642 | set_bit(KEY_VOLUMEUP, input->keybit); | 642 | set_bit(KEY_VOLUMEUP, input->keybit); |
643 | set_bit(KEY_VOLUMEDOWN, input->keybit); | 643 | set_bit(KEY_VOLUMEDOWN, input->keybit); |
644 | } | 644 | } |
645 | 645 | ||
646 | if (usage->type == EV_KEY) { | 646 | if (usage->type == EV_KEY) { |
647 | set_bit(EV_MSC, input->evbit); | 647 | set_bit(EV_MSC, input->evbit); |
648 | set_bit(MSC_SCAN, input->mscbit); | 648 | set_bit(MSC_SCAN, input->mscbit); |
649 | } | 649 | } |
650 | 650 | ||
651 | ignore: | 651 | ignore: |
652 | return; | 652 | return; |
653 | 653 | ||
654 | } | 654 | } |
655 | 655 | ||
656 | void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) | 656 | void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) |
657 | { | 657 | { |
658 | struct input_dev *input; | 658 | struct input_dev *input; |
659 | unsigned *quirks = &hid->quirks; | 659 | unsigned *quirks = &hid->quirks; |
660 | 660 | ||
661 | if (!field->hidinput) | 661 | if (!field->hidinput) |
662 | return; | 662 | return; |
663 | 663 | ||
664 | input = field->hidinput->input; | 664 | input = field->hidinput->input; |
665 | 665 | ||
666 | if (!usage->type) | 666 | if (!usage->type) |
667 | return; | 667 | return; |
668 | 668 | ||
669 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 669 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
670 | int hat_dir = usage->hat_dir; | 670 | int hat_dir = usage->hat_dir; |
671 | if (!hat_dir) | 671 | if (!hat_dir) |
672 | hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; | 672 | hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; |
673 | if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; | 673 | if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; |
674 | input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); | 674 | input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); |
675 | input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); | 675 | input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); |
676 | return; | 676 | return; |
677 | } | 677 | } |
678 | 678 | ||
679 | if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ | 679 | if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ |
680 | *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); | 680 | *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); |
681 | return; | 681 | return; |
682 | } | 682 | } |
683 | 683 | ||
684 | if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */ | 684 | if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */ |
685 | if (value) { | 685 | if (value) { |
686 | input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); | 686 | input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); |
687 | return; | 687 | return; |
688 | } | 688 | } |
689 | input_event(input, usage->type, usage->code, 0); | 689 | input_event(input, usage->type, usage->code, 0); |
690 | input_event(input, usage->type, BTN_TOOL_RUBBER, 0); | 690 | input_event(input, usage->type, BTN_TOOL_RUBBER, 0); |
691 | return; | 691 | return; |
692 | } | 692 | } |
693 | 693 | ||
694 | if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */ | 694 | if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */ |
695 | int a = field->logical_minimum; | 695 | int a = field->logical_minimum; |
696 | int b = field->logical_maximum; | 696 | int b = field->logical_maximum; |
697 | input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); | 697 | input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); |
698 | } | 698 | } |
699 | 699 | ||
700 | if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ | 700 | if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ |
701 | dbg_hid("Maximum Effects - %d\n",value); | 701 | dbg_hid("Maximum Effects - %d\n",value); |
702 | return; | 702 | return; |
703 | } | 703 | } |
704 | 704 | ||
705 | if (usage->hid == (HID_UP_PID | 0x7fUL)) { | 705 | if (usage->hid == (HID_UP_PID | 0x7fUL)) { |
706 | dbg_hid("PID Pool Report\n"); | 706 | dbg_hid("PID Pool Report\n"); |
707 | return; | 707 | return; |
708 | } | 708 | } |
709 | 709 | ||
710 | if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ | 710 | if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ |
711 | return; | 711 | return; |
712 | 712 | ||
713 | if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && | 713 | if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && |
714 | (usage->code == ABS_VOLUME)) { | 714 | (usage->code == ABS_VOLUME)) { |
715 | int count = abs(value); | 715 | int count = abs(value); |
716 | int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN; | 716 | int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN; |
717 | int i; | 717 | int i; |
718 | 718 | ||
719 | for (i = 0; i < count; i++) { | 719 | for (i = 0; i < count; i++) { |
720 | input_event(input, EV_KEY, direction, 1); | 720 | input_event(input, EV_KEY, direction, 1); |
721 | input_sync(input); | 721 | input_sync(input); |
722 | input_event(input, EV_KEY, direction, 0); | 722 | input_event(input, EV_KEY, direction, 0); |
723 | input_sync(input); | 723 | input_sync(input); |
724 | } | 724 | } |
725 | return; | 725 | return; |
726 | } | 726 | } |
727 | 727 | ||
728 | /* report the usage code as scancode if the key status has changed */ | 728 | /* report the usage code as scancode if the key status has changed */ |
729 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 729 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
730 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 730 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
731 | 731 | ||
732 | input_event(input, usage->type, usage->code, value); | 732 | input_event(input, usage->type, usage->code, value); |
733 | 733 | ||
734 | if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) | 734 | if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) |
735 | input_event(input, usage->type, usage->code, 0); | 735 | input_event(input, usage->type, usage->code, 0); |
736 | } | 736 | } |
737 | 737 | ||
738 | void hidinput_report_event(struct hid_device *hid, struct hid_report *report) | 738 | void hidinput_report_event(struct hid_device *hid, struct hid_report *report) |
739 | { | 739 | { |
740 | struct hid_input *hidinput; | 740 | struct hid_input *hidinput; |
741 | 741 | ||
742 | if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC) | ||
743 | return; | ||
744 | |||
742 | list_for_each_entry(hidinput, &hid->inputs, list) | 745 | list_for_each_entry(hidinput, &hid->inputs, list) |
743 | input_sync(hidinput->input); | 746 | input_sync(hidinput->input); |
744 | } | 747 | } |
745 | EXPORT_SYMBOL_GPL(hidinput_report_event); | 748 | EXPORT_SYMBOL_GPL(hidinput_report_event); |
746 | 749 | ||
747 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) | 750 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) |
748 | { | 751 | { |
749 | struct hid_report *report; | 752 | struct hid_report *report; |
750 | int i, j; | 753 | int i, j; |
751 | 754 | ||
752 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { | 755 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { |
753 | for (i = 0; i < report->maxfield; i++) { | 756 | for (i = 0; i < report->maxfield; i++) { |
754 | *field = report->field[i]; | 757 | *field = report->field[i]; |
755 | for (j = 0; j < (*field)->maxusage; j++) | 758 | for (j = 0; j < (*field)->maxusage; j++) |
756 | if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) | 759 | if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) |
757 | return j; | 760 | return j; |
758 | } | 761 | } |
759 | } | 762 | } |
760 | return -1; | 763 | return -1; |
761 | } | 764 | } |
762 | EXPORT_SYMBOL_GPL(hidinput_find_field); | 765 | EXPORT_SYMBOL_GPL(hidinput_find_field); |
763 | 766 | ||
764 | static int hidinput_open(struct input_dev *dev) | 767 | static int hidinput_open(struct input_dev *dev) |
765 | { | 768 | { |
766 | struct hid_device *hid = input_get_drvdata(dev); | 769 | struct hid_device *hid = input_get_drvdata(dev); |
767 | 770 | ||
768 | return hid->ll_driver->open(hid); | 771 | return hid->ll_driver->open(hid); |
769 | } | 772 | } |
770 | 773 | ||
771 | static void hidinput_close(struct input_dev *dev) | 774 | static void hidinput_close(struct input_dev *dev) |
772 | { | 775 | { |
773 | struct hid_device *hid = input_get_drvdata(dev); | 776 | struct hid_device *hid = input_get_drvdata(dev); |
774 | 777 | ||
775 | hid->ll_driver->close(hid); | 778 | hid->ll_driver->close(hid); |
776 | } | 779 | } |
777 | 780 | ||
778 | /* | 781 | /* |
779 | * Register the input device; print a message. | 782 | * Register the input device; print a message. |
780 | * Configure the input layer interface | 783 | * Configure the input layer interface |
781 | * Read all reports and initialize the absolute field values. | 784 | * Read all reports and initialize the absolute field values. |
782 | */ | 785 | */ |
783 | 786 | ||
784 | int hidinput_connect(struct hid_device *hid, unsigned int force) | 787 | int hidinput_connect(struct hid_device *hid, unsigned int force) |
785 | { | 788 | { |
786 | struct hid_report *report; | 789 | struct hid_report *report; |
787 | struct hid_input *hidinput = NULL; | 790 | struct hid_input *hidinput = NULL; |
788 | struct input_dev *input_dev; | 791 | struct input_dev *input_dev; |
789 | int i, j, k; | 792 | int i, j, k; |
790 | int max_report_type = HID_OUTPUT_REPORT; | 793 | int max_report_type = HID_OUTPUT_REPORT; |
791 | 794 | ||
792 | INIT_LIST_HEAD(&hid->inputs); | 795 | INIT_LIST_HEAD(&hid->inputs); |
793 | 796 | ||
794 | if (!force) { | 797 | if (!force) { |
795 | for (i = 0; i < hid->maxcollection; i++) { | 798 | for (i = 0; i < hid->maxcollection; i++) { |
796 | struct hid_collection *col = &hid->collection[i]; | 799 | struct hid_collection *col = &hid->collection[i]; |
797 | if (col->type == HID_COLLECTION_APPLICATION || | 800 | if (col->type == HID_COLLECTION_APPLICATION || |
798 | col->type == HID_COLLECTION_PHYSICAL) | 801 | col->type == HID_COLLECTION_PHYSICAL) |
799 | if (IS_INPUT_APPLICATION(col->usage)) | 802 | if (IS_INPUT_APPLICATION(col->usage)) |
800 | break; | 803 | break; |
801 | } | 804 | } |
802 | 805 | ||
803 | if (i == hid->maxcollection) | 806 | if (i == hid->maxcollection) |
804 | return -1; | 807 | return -1; |
805 | } | 808 | } |
806 | 809 | ||
807 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) | 810 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) |
808 | max_report_type = HID_INPUT_REPORT; | 811 | max_report_type = HID_INPUT_REPORT; |
809 | 812 | ||
810 | for (k = HID_INPUT_REPORT; k <= max_report_type; k++) | 813 | for (k = HID_INPUT_REPORT; k <= max_report_type; k++) |
811 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | 814 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { |
812 | 815 | ||
813 | if (!report->maxfield) | 816 | if (!report->maxfield) |
814 | continue; | 817 | continue; |
815 | 818 | ||
816 | if (!hidinput) { | 819 | if (!hidinput) { |
817 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | 820 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); |
818 | input_dev = input_allocate_device(); | 821 | input_dev = input_allocate_device(); |
819 | if (!hidinput || !input_dev) { | 822 | if (!hidinput || !input_dev) { |
820 | kfree(hidinput); | 823 | kfree(hidinput); |
821 | input_free_device(input_dev); | 824 | input_free_device(input_dev); |
822 | err_hid("Out of memory during hid input probe"); | 825 | err_hid("Out of memory during hid input probe"); |
823 | goto out_unwind; | 826 | goto out_unwind; |
824 | } | 827 | } |
825 | 828 | ||
826 | input_set_drvdata(input_dev, hid); | 829 | input_set_drvdata(input_dev, hid); |
827 | input_dev->event = | 830 | input_dev->event = |
828 | hid->ll_driver->hidinput_input_event; | 831 | hid->ll_driver->hidinput_input_event; |
829 | input_dev->open = hidinput_open; | 832 | input_dev->open = hidinput_open; |
830 | input_dev->close = hidinput_close; | 833 | input_dev->close = hidinput_close; |
831 | input_dev->setkeycode = hidinput_setkeycode; | 834 | input_dev->setkeycode = hidinput_setkeycode; |
832 | input_dev->getkeycode = hidinput_getkeycode; | 835 | input_dev->getkeycode = hidinput_getkeycode; |
833 | 836 | ||
834 | input_dev->name = hid->name; | 837 | input_dev->name = hid->name; |
835 | input_dev->phys = hid->phys; | 838 | input_dev->phys = hid->phys; |
836 | input_dev->uniq = hid->uniq; | 839 | input_dev->uniq = hid->uniq; |
837 | input_dev->id.bustype = hid->bus; | 840 | input_dev->id.bustype = hid->bus; |
838 | input_dev->id.vendor = hid->vendor; | 841 | input_dev->id.vendor = hid->vendor; |
839 | input_dev->id.product = hid->product; | 842 | input_dev->id.product = hid->product; |
840 | input_dev->id.version = hid->version; | 843 | input_dev->id.version = hid->version; |
841 | input_dev->dev.parent = hid->dev.parent; | 844 | input_dev->dev.parent = hid->dev.parent; |
842 | hidinput->input = input_dev; | 845 | hidinput->input = input_dev; |
843 | list_add_tail(&hidinput->list, &hid->inputs); | 846 | list_add_tail(&hidinput->list, &hid->inputs); |
844 | } | 847 | } |
845 | 848 | ||
846 | for (i = 0; i < report->maxfield; i++) | 849 | for (i = 0; i < report->maxfield; i++) |
847 | for (j = 0; j < report->field[i]->maxusage; j++) | 850 | for (j = 0; j < report->field[i]->maxusage; j++) |
848 | hidinput_configure_usage(hidinput, report->field[i], | 851 | hidinput_configure_usage(hidinput, report->field[i], |
849 | report->field[i]->usage + j); | 852 | report->field[i]->usage + j); |
850 | 853 | ||
851 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { | 854 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { |
852 | /* This will leave hidinput NULL, so that it | 855 | /* This will leave hidinput NULL, so that it |
853 | * allocates another one if we have more inputs on | 856 | * allocates another one if we have more inputs on |
854 | * the same interface. Some devices (e.g. Happ's | 857 | * the same interface. Some devices (e.g. Happ's |
855 | * UGCI) cram a lot of unrelated inputs into the | 858 | * UGCI) cram a lot of unrelated inputs into the |
856 | * same interface. */ | 859 | * same interface. */ |
857 | hidinput->report = report; | 860 | hidinput->report = report; |
858 | if (input_register_device(hidinput->input)) | 861 | if (input_register_device(hidinput->input)) |
859 | goto out_cleanup; | 862 | goto out_cleanup; |
860 | hidinput = NULL; | 863 | hidinput = NULL; |
861 | } | 864 | } |
862 | } | 865 | } |
863 | 866 | ||
864 | if (hidinput && input_register_device(hidinput->input)) | 867 | if (hidinput && input_register_device(hidinput->input)) |
865 | goto out_cleanup; | 868 | goto out_cleanup; |
866 | 869 | ||
867 | return 0; | 870 | return 0; |
868 | 871 | ||
869 | out_cleanup: | 872 | out_cleanup: |
870 | input_free_device(hidinput->input); | 873 | input_free_device(hidinput->input); |
871 | kfree(hidinput); | 874 | kfree(hidinput); |
872 | out_unwind: | 875 | out_unwind: |
873 | /* unwind the ones we already registered */ | 876 | /* unwind the ones we already registered */ |
874 | hidinput_disconnect(hid); | 877 | hidinput_disconnect(hid); |
875 | 878 | ||
876 | return -1; | 879 | return -1; |
877 | } | 880 | } |
878 | EXPORT_SYMBOL_GPL(hidinput_connect); | 881 | EXPORT_SYMBOL_GPL(hidinput_connect); |
879 | 882 | ||
880 | void hidinput_disconnect(struct hid_device *hid) | 883 | void hidinput_disconnect(struct hid_device *hid) |
881 | { | 884 | { |
882 | struct hid_input *hidinput, *next; | 885 | struct hid_input *hidinput, *next; |
883 | 886 | ||
884 | list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { | 887 | list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { |
885 | list_del(&hidinput->list); | 888 | list_del(&hidinput->list); |
886 | input_unregister_device(hidinput->input); | 889 | input_unregister_device(hidinput->input); |
887 | kfree(hidinput); | 890 | kfree(hidinput); |
888 | } | 891 | } |
889 | } | 892 | } |
890 | EXPORT_SYMBOL_GPL(hidinput_disconnect); | 893 | EXPORT_SYMBOL_GPL(hidinput_disconnect); |
891 | 894 | ||
892 | 895 |
drivers/hid/hid-lg.c
1 | /* | 1 | /* |
2 | * HID driver for some logitech "special" devices | 2 | * HID driver for some logitech "special" devices |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006-2007 Jiri Kosina | 7 | * Copyright (c) 2006-2007 Jiri Kosina |
8 | * Copyright (c) 2007 Paul Walmsley | 8 | * Copyright (c) 2007 Paul Walmsley |
9 | * Copyright (c) 2008 Jiri Slaby | 9 | * Copyright (c) 2008 Jiri Slaby |
10 | * Copyright (c) 2010 Hendrik Iben | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | /* | 13 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
14 | * under the terms of the GNU General Public License as published by the Free | 15 | * under the terms of the GNU General Public License as published by the Free |
15 | * Software Foundation; either version 2 of the License, or (at your option) | 16 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 17 | * any later version. |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include <linux/device.h> | 20 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/random.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/wait.h> | ||
22 | 26 | ||
23 | #include "hid-ids.h" | 27 | #include "hid-ids.h" |
24 | #include "hid-lg.h" | 28 | #include "hid-lg.h" |
25 | 29 | ||
26 | #define LG_RDESC 0x001 | 30 | #define LG_RDESC 0x001 |
27 | #define LG_BAD_RELATIVE_KEYS 0x002 | 31 | #define LG_BAD_RELATIVE_KEYS 0x002 |
28 | #define LG_DUPLICATE_USAGES 0x004 | 32 | #define LG_DUPLICATE_USAGES 0x004 |
29 | #define LG_EXPANDED_KEYMAP 0x010 | 33 | #define LG_EXPANDED_KEYMAP 0x010 |
30 | #define LG_IGNORE_DOUBLED_WHEEL 0x020 | 34 | #define LG_IGNORE_DOUBLED_WHEEL 0x020 |
31 | #define LG_WIRELESS 0x040 | 35 | #define LG_WIRELESS 0x040 |
32 | #define LG_INVERT_HWHEEL 0x080 | 36 | #define LG_INVERT_HWHEEL 0x080 |
33 | #define LG_NOGET 0x100 | 37 | #define LG_NOGET 0x100 |
34 | #define LG_FF 0x200 | 38 | #define LG_FF 0x200 |
35 | #define LG_FF2 0x400 | 39 | #define LG_FF2 0x400 |
36 | #define LG_RDESC_REL_ABS 0x800 | 40 | #define LG_RDESC_REL_ABS 0x800 |
37 | #define LG_FF3 0x1000 | 41 | #define LG_FF3 0x1000 |
42 | #define LG_FF4 0x2000 | ||
38 | 43 | ||
39 | /* | 44 | /* |
40 | * Certain Logitech keyboards send in report #3 keys which are far | 45 | * Certain Logitech keyboards send in report #3 keys which are far |
41 | * above the logical maximum described in descriptor. This extends | 46 | * above the logical maximum described in descriptor. This extends |
42 | * the original value of 0x28c of logical maximum to 0x104d | 47 | * the original value of 0x28c of logical maximum to 0x104d |
43 | */ | 48 | */ |
44 | static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 49 | static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
45 | unsigned int rsize) | 50 | unsigned int rsize) |
46 | { | 51 | { |
47 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 52 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
48 | 53 | ||
49 | if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && | 54 | if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && |
50 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 55 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
51 | dev_info(&hdev->dev, "fixing up Logitech keyboard report " | 56 | dev_info(&hdev->dev, "fixing up Logitech keyboard report " |
52 | "descriptor\n"); | 57 | "descriptor\n"); |
53 | rdesc[84] = rdesc[89] = 0x4d; | 58 | rdesc[84] = rdesc[89] = 0x4d; |
54 | rdesc[85] = rdesc[90] = 0x10; | 59 | rdesc[85] = rdesc[90] = 0x10; |
55 | } | 60 | } |
56 | if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 && | 61 | if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 && |
57 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | 62 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && |
58 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | 63 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { |
59 | dev_info(&hdev->dev, "fixing up rel/abs in Logitech " | 64 | dev_info(&hdev->dev, "fixing up rel/abs in Logitech " |
60 | "report descriptor\n"); | 65 | "report descriptor\n"); |
61 | rdesc[33] = rdesc[50] = 0x02; | 66 | rdesc[33] = rdesc[50] = 0x02; |
62 | } | 67 | } |
68 | |||
69 | if ((quirks & LG_FF4) && rsize >= 101 && | ||
70 | rdesc[41] == 0x95 && rdesc[42] == 0x0B && | ||
71 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { | ||
72 | dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless " | ||
73 | "button descriptor\n"); | ||
74 | rdesc[41] = 0x05; | ||
75 | rdesc[42] = 0x09; | ||
76 | rdesc[47] = 0x95; | ||
77 | rdesc[48] = 0x0B; | ||
78 | } | ||
63 | } | 79 | } |
64 | 80 | ||
65 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 81 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
66 | EV_KEY, (c)) | 82 | EV_KEY, (c)) |
67 | 83 | ||
68 | static int lg_ultrax_remote_mapping(struct hid_input *hi, | 84 | static int lg_ultrax_remote_mapping(struct hid_input *hi, |
69 | struct hid_usage *usage, unsigned long **bit, int *max) | 85 | struct hid_usage *usage, unsigned long **bit, int *max) |
70 | { | 86 | { |
71 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | 87 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) |
72 | return 0; | 88 | return 0; |
73 | 89 | ||
74 | set_bit(EV_REP, hi->input->evbit); | 90 | set_bit(EV_REP, hi->input->evbit); |
75 | switch (usage->hid & HID_USAGE) { | 91 | switch (usage->hid & HID_USAGE) { |
76 | /* Reported on Logitech Ultra X Media Remote */ | 92 | /* Reported on Logitech Ultra X Media Remote */ |
77 | case 0x004: lg_map_key_clear(KEY_AGAIN); break; | 93 | case 0x004: lg_map_key_clear(KEY_AGAIN); break; |
78 | case 0x00d: lg_map_key_clear(KEY_HOME); break; | 94 | case 0x00d: lg_map_key_clear(KEY_HOME); break; |
79 | case 0x024: lg_map_key_clear(KEY_SHUFFLE); break; | 95 | case 0x024: lg_map_key_clear(KEY_SHUFFLE); break; |
80 | case 0x025: lg_map_key_clear(KEY_TV); break; | 96 | case 0x025: lg_map_key_clear(KEY_TV); break; |
81 | case 0x026: lg_map_key_clear(KEY_MENU); break; | 97 | case 0x026: lg_map_key_clear(KEY_MENU); break; |
82 | case 0x031: lg_map_key_clear(KEY_AUDIO); break; | 98 | case 0x031: lg_map_key_clear(KEY_AUDIO); break; |
83 | case 0x032: lg_map_key_clear(KEY_TEXT); break; | 99 | case 0x032: lg_map_key_clear(KEY_TEXT); break; |
84 | case 0x033: lg_map_key_clear(KEY_LAST); break; | 100 | case 0x033: lg_map_key_clear(KEY_LAST); break; |
85 | case 0x047: lg_map_key_clear(KEY_MP3); break; | 101 | case 0x047: lg_map_key_clear(KEY_MP3); break; |
86 | case 0x048: lg_map_key_clear(KEY_DVD); break; | 102 | case 0x048: lg_map_key_clear(KEY_DVD); break; |
87 | case 0x049: lg_map_key_clear(KEY_MEDIA); break; | 103 | case 0x049: lg_map_key_clear(KEY_MEDIA); break; |
88 | case 0x04a: lg_map_key_clear(KEY_VIDEO); break; | 104 | case 0x04a: lg_map_key_clear(KEY_VIDEO); break; |
89 | case 0x04b: lg_map_key_clear(KEY_ANGLE); break; | 105 | case 0x04b: lg_map_key_clear(KEY_ANGLE); break; |
90 | case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break; | 106 | case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break; |
91 | case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break; | 107 | case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break; |
92 | case 0x051: lg_map_key_clear(KEY_RED); break; | 108 | case 0x051: lg_map_key_clear(KEY_RED); break; |
93 | case 0x052: lg_map_key_clear(KEY_CLOSE); break; | 109 | case 0x052: lg_map_key_clear(KEY_CLOSE); break; |
94 | 110 | ||
95 | default: | 111 | default: |
96 | return 0; | 112 | return 0; |
97 | } | 113 | } |
98 | return 1; | 114 | return 1; |
99 | } | 115 | } |
100 | 116 | ||
101 | static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage, | 117 | static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage, |
102 | unsigned long **bit, int *max) | 118 | unsigned long **bit, int *max) |
103 | { | 119 | { |
104 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | 120 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) |
105 | return 0; | 121 | return 0; |
106 | 122 | ||
107 | switch (usage->hid & HID_USAGE) { | 123 | switch (usage->hid & HID_USAGE) { |
108 | 124 | ||
109 | case 0x00d: lg_map_key_clear(KEY_MEDIA); break; | 125 | case 0x00d: lg_map_key_clear(KEY_MEDIA); break; |
110 | default: | 126 | default: |
111 | return 0; | 127 | return 0; |
112 | 128 | ||
113 | } | 129 | } |
114 | return 1; | 130 | return 1; |
115 | } | 131 | } |
116 | 132 | ||
117 | static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, | 133 | static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, |
118 | unsigned long **bit, int *max) | 134 | unsigned long **bit, int *max) |
119 | { | 135 | { |
120 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 136 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
121 | return 0; | 137 | return 0; |
122 | 138 | ||
123 | switch (usage->hid & HID_USAGE) { | 139 | switch (usage->hid & HID_USAGE) { |
124 | case 0x1001: lg_map_key_clear(KEY_MESSENGER); break; | 140 | case 0x1001: lg_map_key_clear(KEY_MESSENGER); break; |
125 | case 0x1003: lg_map_key_clear(KEY_SOUND); break; | 141 | case 0x1003: lg_map_key_clear(KEY_SOUND); break; |
126 | case 0x1004: lg_map_key_clear(KEY_VIDEO); break; | 142 | case 0x1004: lg_map_key_clear(KEY_VIDEO); break; |
127 | case 0x1005: lg_map_key_clear(KEY_AUDIO); break; | 143 | case 0x1005: lg_map_key_clear(KEY_AUDIO); break; |
128 | case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; | 144 | case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; |
129 | /* The following two entries are Playlist 1 and 2 on the MX3200 */ | 145 | /* The following two entries are Playlist 1 and 2 on the MX3200 */ |
130 | case 0x100f: lg_map_key_clear(KEY_FN_1); break; | 146 | case 0x100f: lg_map_key_clear(KEY_FN_1); break; |
131 | case 0x1010: lg_map_key_clear(KEY_FN_2); break; | 147 | case 0x1010: lg_map_key_clear(KEY_FN_2); break; |
132 | case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; | 148 | case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; |
133 | case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; | 149 | case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; |
134 | case 0x1013: lg_map_key_clear(KEY_CAMERA); break; | 150 | case 0x1013: lg_map_key_clear(KEY_CAMERA); break; |
135 | case 0x1014: lg_map_key_clear(KEY_MESSENGER); break; | 151 | case 0x1014: lg_map_key_clear(KEY_MESSENGER); break; |
136 | case 0x1015: lg_map_key_clear(KEY_RECORD); break; | 152 | case 0x1015: lg_map_key_clear(KEY_RECORD); break; |
137 | case 0x1016: lg_map_key_clear(KEY_PLAYER); break; | 153 | case 0x1016: lg_map_key_clear(KEY_PLAYER); break; |
138 | case 0x1017: lg_map_key_clear(KEY_EJECTCD); break; | 154 | case 0x1017: lg_map_key_clear(KEY_EJECTCD); break; |
139 | case 0x1018: lg_map_key_clear(KEY_MEDIA); break; | 155 | case 0x1018: lg_map_key_clear(KEY_MEDIA); break; |
140 | case 0x1019: lg_map_key_clear(KEY_PROG1); break; | 156 | case 0x1019: lg_map_key_clear(KEY_PROG1); break; |
141 | case 0x101a: lg_map_key_clear(KEY_PROG2); break; | 157 | case 0x101a: lg_map_key_clear(KEY_PROG2); break; |
142 | case 0x101b: lg_map_key_clear(KEY_PROG3); break; | 158 | case 0x101b: lg_map_key_clear(KEY_PROG3); break; |
143 | case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS); break; | 159 | case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS); break; |
144 | case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; | 160 | case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; |
145 | case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; | 161 | case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; |
146 | case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; | 162 | case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; |
147 | case 0x1023: lg_map_key_clear(KEY_CLOSE); break; | 163 | case 0x1023: lg_map_key_clear(KEY_CLOSE); break; |
148 | case 0x1027: lg_map_key_clear(KEY_MENU); break; | 164 | case 0x1027: lg_map_key_clear(KEY_MENU); break; |
149 | /* this one is marked as 'Rotate' */ | 165 | /* this one is marked as 'Rotate' */ |
150 | case 0x1028: lg_map_key_clear(KEY_ANGLE); break; | 166 | case 0x1028: lg_map_key_clear(KEY_ANGLE); break; |
151 | case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; | 167 | case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; |
152 | case 0x102a: lg_map_key_clear(KEY_BACK); break; | 168 | case 0x102a: lg_map_key_clear(KEY_BACK); break; |
153 | case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; | 169 | case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; |
154 | case 0x102d: lg_map_key_clear(KEY_WWW); break; | 170 | case 0x102d: lg_map_key_clear(KEY_WWW); break; |
155 | /* The following two are 'Start/answer call' and 'End/reject call' | 171 | /* The following two are 'Start/answer call' and 'End/reject call' |
156 | on the MX3200 */ | 172 | on the MX3200 */ |
157 | case 0x1031: lg_map_key_clear(KEY_OK); break; | 173 | case 0x1031: lg_map_key_clear(KEY_OK); break; |
158 | case 0x1032: lg_map_key_clear(KEY_CANCEL); break; | 174 | case 0x1032: lg_map_key_clear(KEY_CANCEL); break; |
159 | case 0x1041: lg_map_key_clear(KEY_BATTERY); break; | 175 | case 0x1041: lg_map_key_clear(KEY_BATTERY); break; |
160 | case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; | 176 | case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; |
161 | case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; | 177 | case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; |
162 | case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break; | 178 | case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break; |
163 | case 0x1045: lg_map_key_clear(KEY_UNDO); break; | 179 | case 0x1045: lg_map_key_clear(KEY_UNDO); break; |
164 | case 0x1046: lg_map_key_clear(KEY_REDO); break; | 180 | case 0x1046: lg_map_key_clear(KEY_REDO); break; |
165 | case 0x1047: lg_map_key_clear(KEY_PRINT); break; | 181 | case 0x1047: lg_map_key_clear(KEY_PRINT); break; |
166 | case 0x1048: lg_map_key_clear(KEY_SAVE); break; | 182 | case 0x1048: lg_map_key_clear(KEY_SAVE); break; |
167 | case 0x1049: lg_map_key_clear(KEY_PROG1); break; | 183 | case 0x1049: lg_map_key_clear(KEY_PROG1); break; |
168 | case 0x104a: lg_map_key_clear(KEY_PROG2); break; | 184 | case 0x104a: lg_map_key_clear(KEY_PROG2); break; |
169 | case 0x104b: lg_map_key_clear(KEY_PROG3); break; | 185 | case 0x104b: lg_map_key_clear(KEY_PROG3); break; |
170 | case 0x104c: lg_map_key_clear(KEY_PROG4); break; | 186 | case 0x104c: lg_map_key_clear(KEY_PROG4); break; |
171 | 187 | ||
172 | default: | 188 | default: |
173 | return 0; | 189 | return 0; |
174 | } | 190 | } |
175 | return 1; | 191 | return 1; |
176 | } | 192 | } |
177 | 193 | ||
178 | static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 194 | static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
179 | struct hid_field *field, struct hid_usage *usage, | 195 | struct hid_field *field, struct hid_usage *usage, |
180 | unsigned long **bit, int *max) | 196 | unsigned long **bit, int *max) |
181 | { | 197 | { |
182 | /* extended mapping for certain Logitech hardware (Logitech cordless | 198 | /* extended mapping for certain Logitech hardware (Logitech cordless |
183 | desktop LX500) */ | 199 | desktop LX500) */ |
184 | static const u8 e_keymap[] = { | 200 | static const u8 e_keymap[] = { |
185 | 0,216, 0,213,175,156, 0, 0, 0, 0, | 201 | 0,216, 0,213,175,156, 0, 0, 0, 0, |
186 | 144, 0, 0, 0, 0, 0, 0, 0, 0,212, | 202 | 144, 0, 0, 0, 0, 0, 0, 0, 0,212, |
187 | 174,167,152,161,112, 0, 0, 0,154, 0, | 203 | 174,167,152,161,112, 0, 0, 0,154, 0, |
188 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 204 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
189 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 205 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
190 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 206 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
191 | 0, 0, 0, 0, 0,183,184,185,186,187, | 207 | 0, 0, 0, 0, 0,183,184,185,186,187, |
192 | 188,189,190,191,192,193,194, 0, 0, 0 | 208 | 188,189,190,191,192,193,194, 0, 0, 0 |
193 | }; | 209 | }; |
194 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 210 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
195 | unsigned int hid = usage->hid; | 211 | unsigned int hid = usage->hid; |
196 | 212 | ||
197 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && | 213 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && |
198 | lg_ultrax_remote_mapping(hi, usage, bit, max)) | 214 | lg_ultrax_remote_mapping(hi, usage, bit, max)) |
199 | return 1; | 215 | return 1; |
200 | 216 | ||
201 | if (hdev->product == USB_DEVICE_ID_DINOVO_MINI && | 217 | if (hdev->product == USB_DEVICE_ID_DINOVO_MINI && |
202 | lg_dinovo_mapping(hi, usage, bit, max)) | 218 | lg_dinovo_mapping(hi, usage, bit, max)) |
203 | return 1; | 219 | return 1; |
204 | 220 | ||
205 | if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) | 221 | if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) |
206 | return 1; | 222 | return 1; |
207 | 223 | ||
208 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | 224 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) |
209 | return 0; | 225 | return 0; |
210 | 226 | ||
211 | hid &= HID_USAGE; | 227 | hid &= HID_USAGE; |
212 | 228 | ||
213 | /* Special handling for Logitech Cordless Desktop */ | 229 | /* Special handling for Logitech Cordless Desktop */ |
214 | if (field->application == HID_GD_MOUSE) { | 230 | if (field->application == HID_GD_MOUSE) { |
215 | if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && | 231 | if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && |
216 | (hid == 7 || hid == 8)) | 232 | (hid == 7 || hid == 8)) |
217 | return -1; | 233 | return -1; |
218 | } else { | 234 | } else { |
219 | if ((quirks & LG_EXPANDED_KEYMAP) && | 235 | if ((quirks & LG_EXPANDED_KEYMAP) && |
220 | hid < ARRAY_SIZE(e_keymap) && | 236 | hid < ARRAY_SIZE(e_keymap) && |
221 | e_keymap[hid] != 0) { | 237 | e_keymap[hid] != 0) { |
222 | hid_map_usage(hi, usage, bit, max, EV_KEY, | 238 | hid_map_usage(hi, usage, bit, max, EV_KEY, |
223 | e_keymap[hid]); | 239 | e_keymap[hid]); |
224 | return 1; | 240 | return 1; |
225 | } | 241 | } |
226 | } | 242 | } |
227 | 243 | ||
228 | return 0; | 244 | return 0; |
229 | } | 245 | } |
230 | 246 | ||
231 | static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 247 | static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
232 | struct hid_field *field, struct hid_usage *usage, | 248 | struct hid_field *field, struct hid_usage *usage, |
233 | unsigned long **bit, int *max) | 249 | unsigned long **bit, int *max) |
234 | { | 250 | { |
235 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 251 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
236 | 252 | ||
237 | if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && | 253 | if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && |
238 | (field->flags & HID_MAIN_ITEM_RELATIVE)) | 254 | (field->flags & HID_MAIN_ITEM_RELATIVE)) |
239 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; | 255 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; |
240 | 256 | ||
241 | if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || | 257 | if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || |
242 | usage->type == EV_REL || usage->type == EV_ABS)) | 258 | usage->type == EV_REL || usage->type == EV_ABS)) |
243 | clear_bit(usage->code, *bit); | 259 | clear_bit(usage->code, *bit); |
244 | 260 | ||
245 | return 0; | 261 | return 0; |
246 | } | 262 | } |
247 | 263 | ||
248 | static int lg_event(struct hid_device *hdev, struct hid_field *field, | 264 | static int lg_event(struct hid_device *hdev, struct hid_field *field, |
249 | struct hid_usage *usage, __s32 value) | 265 | struct hid_usage *usage, __s32 value) |
250 | { | 266 | { |
251 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 267 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
252 | 268 | ||
253 | if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { | 269 | if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { |
254 | input_event(field->hidinput->input, usage->type, usage->code, | 270 | input_event(field->hidinput->input, usage->type, usage->code, |
255 | -value); | 271 | -value); |
256 | return 1; | 272 | return 1; |
257 | } | 273 | } |
258 | 274 | ||
259 | return 0; | 275 | return 0; |
260 | } | 276 | } |
261 | 277 | ||
262 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | 278 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) |
263 | { | 279 | { |
264 | unsigned long quirks = id->driver_data; | 280 | unsigned long quirks = id->driver_data; |
265 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 281 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
266 | int ret; | 282 | int ret; |
267 | 283 | ||
268 | hid_set_drvdata(hdev, (void *)quirks); | 284 | hid_set_drvdata(hdev, (void *)quirks); |
269 | 285 | ||
270 | if (quirks & LG_NOGET) | 286 | if (quirks & LG_NOGET) |
271 | hdev->quirks |= HID_QUIRK_NOGET; | 287 | hdev->quirks |= HID_QUIRK_NOGET; |
272 | 288 | ||
273 | ret = hid_parse(hdev); | 289 | ret = hid_parse(hdev); |
274 | if (ret) { | 290 | if (ret) { |
275 | dev_err(&hdev->dev, "parse failed\n"); | 291 | dev_err(&hdev->dev, "parse failed\n"); |
276 | goto err_free; | 292 | goto err_free; |
277 | } | 293 | } |
278 | 294 | ||
279 | if (quirks & (LG_FF | LG_FF2 | LG_FF3)) | 295 | if (quirks & (LG_FF | LG_FF2 | LG_FF3)) |
280 | connect_mask &= ~HID_CONNECT_FF; | 296 | connect_mask &= ~HID_CONNECT_FF; |
281 | 297 | ||
282 | ret = hid_hw_start(hdev, connect_mask); | 298 | ret = hid_hw_start(hdev, connect_mask); |
283 | if (ret) { | 299 | if (ret) { |
284 | dev_err(&hdev->dev, "hw start failed\n"); | 300 | dev_err(&hdev->dev, "hw start failed\n"); |
285 | goto err_free; | 301 | goto err_free; |
286 | } | 302 | } |
287 | 303 | ||
304 | if (quirks & LG_FF4) { | ||
305 | unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
306 | |||
307 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | ||
308 | |||
309 | if (ret >= 0) { | ||
310 | /* insert a little delay of 10 jiffies ~ 40ms */ | ||
311 | wait_queue_head_t wait; | ||
312 | init_waitqueue_head (&wait); | ||
313 | wait_event_interruptible_timeout(wait, 0, 10); | ||
314 | |||
315 | /* Select random Address */ | ||
316 | buf[1] = 0xB2; | ||
317 | get_random_bytes(&buf[2], 2); | ||
318 | |||
319 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | ||
320 | } | ||
321 | } | ||
322 | |||
288 | if (quirks & LG_FF) | 323 | if (quirks & LG_FF) |
289 | lgff_init(hdev); | 324 | lgff_init(hdev); |
290 | if (quirks & LG_FF2) | 325 | if (quirks & LG_FF2) |
291 | lg2ff_init(hdev); | 326 | lg2ff_init(hdev); |
292 | if (quirks & LG_FF3) | 327 | if (quirks & LG_FF3) |
293 | lg3ff_init(hdev); | 328 | lg3ff_init(hdev); |
329 | if (quirks & LG_FF4) | ||
330 | lg4ff_init(hdev); | ||
294 | 331 | ||
295 | return 0; | 332 | return 0; |
296 | err_free: | 333 | err_free: |
297 | return ret; | 334 | return ret; |
298 | } | 335 | } |
299 | 336 | ||
300 | static const struct hid_device_id lg_devices[] = { | 337 | static const struct hid_device_id lg_devices[] = { |
301 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), | 338 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), |
302 | .driver_data = LG_RDESC | LG_WIRELESS }, | 339 | .driver_data = LG_RDESC | LG_WIRELESS }, |
303 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), | 340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), |
304 | .driver_data = LG_RDESC | LG_WIRELESS }, | 341 | .driver_data = LG_RDESC | LG_WIRELESS }, |
305 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), | 342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), |
306 | .driver_data = LG_RDESC | LG_WIRELESS }, | 343 | .driver_data = LG_RDESC | LG_WIRELESS }, |
307 | 344 | ||
308 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), | 345 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), |
309 | .driver_data = LG_BAD_RELATIVE_KEYS }, | 346 | .driver_data = LG_BAD_RELATIVE_KEYS }, |
310 | 347 | ||
311 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), | 348 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), |
312 | .driver_data = LG_DUPLICATE_USAGES }, | 349 | .driver_data = LG_DUPLICATE_USAGES }, |
313 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), | 350 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), |
314 | .driver_data = LG_DUPLICATE_USAGES }, | 351 | .driver_data = LG_DUPLICATE_USAGES }, |
315 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), | 352 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), |
316 | .driver_data = LG_DUPLICATE_USAGES }, | 353 | .driver_data = LG_DUPLICATE_USAGES }, |
317 | 354 | ||
318 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), | 355 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), |
319 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, | 356 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, |
320 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), | 357 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), |
321 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, | 358 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, |
322 | 359 | ||
323 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), | 360 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), |
324 | .driver_data = LG_NOGET }, | 361 | .driver_data = LG_NOGET }, |
325 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), | 362 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), |
326 | .driver_data = LG_NOGET | LG_FF }, | 363 | .driver_data = LG_NOGET | LG_FF }, |
327 | 364 | ||
365 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD), | ||
366 | .driver_data = LG_FF2 }, | ||
328 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), | 367 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), |
329 | .driver_data = LG_FF }, | 368 | .driver_data = LG_FF }, |
330 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), | 369 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), |
331 | .driver_data = LG_FF }, | 370 | .driver_data = LG_FF }, |
332 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), | 371 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), |
333 | .driver_data = LG_FF }, | 372 | .driver_data = LG_FF }, |
334 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), | 373 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), |
335 | .driver_data = LG_FF }, | 374 | .driver_data = LG_FF }, |
336 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), | 375 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), |
337 | .driver_data = LG_FF }, | 376 | .driver_data = LG_FF }, |
338 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), | 377 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), |
339 | .driver_data = LG_FF }, | 378 | .driver_data = LG_FF }, |
340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), | 379 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), |
341 | .driver_data = LG_FF }, | 380 | .driver_data = LG_FF }, |
381 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), | ||
382 | .driver_data = LG_FF4 }, | ||
342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), | 383 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), |
343 | .driver_data = LG_FF }, | 384 | .driver_data = LG_FF }, |
344 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), | 385 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), |
345 | .driver_data = LG_FF2 }, | 386 | .driver_data = LG_FF2 }, |
346 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940), | 387 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940), |
347 | .driver_data = LG_FF3 }, | 388 | .driver_data = LG_FF3 }, |
348 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR), | 389 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR), |
349 | .driver_data = LG_RDESC_REL_ABS }, | 390 | .driver_data = LG_RDESC_REL_ABS }, |
350 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER), | 391 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER), |
351 | .driver_data = LG_RDESC_REL_ABS }, | 392 | .driver_data = LG_RDESC_REL_ABS }, |
352 | { } | 393 | { } |
353 | }; | 394 | }; |
354 | 395 | ||
355 | MODULE_DEVICE_TABLE(hid, lg_devices); | 396 | MODULE_DEVICE_TABLE(hid, lg_devices); |
356 | 397 | ||
357 | static struct hid_driver lg_driver = { | 398 | static struct hid_driver lg_driver = { |
358 | .name = "logitech", | 399 | .name = "logitech", |
359 | .id_table = lg_devices, | 400 | .id_table = lg_devices, |
360 | .report_fixup = lg_report_fixup, | 401 | .report_fixup = lg_report_fixup, |
361 | .input_mapping = lg_input_mapping, | 402 | .input_mapping = lg_input_mapping, |
362 | .input_mapped = lg_input_mapped, | 403 | .input_mapped = lg_input_mapped, |
363 | .event = lg_event, | 404 | .event = lg_event, |
364 | .probe = lg_probe, | 405 | .probe = lg_probe, |
365 | }; | 406 | }; |
366 | 407 | ||
367 | static int __init lg_init(void) | 408 | static int __init lg_init(void) |
368 | { | 409 | { |
369 | return hid_register_driver(&lg_driver); | 410 | return hid_register_driver(&lg_driver); |
370 | } | 411 | } |
371 | 412 | ||
372 | static void __exit lg_exit(void) | 413 | static void __exit lg_exit(void) |
373 | { | 414 | { |
374 | hid_unregister_driver(&lg_driver); | 415 | hid_unregister_driver(&lg_driver); |
375 | } | 416 | } |
376 | 417 | ||
377 | module_init(lg_init); | 418 | module_init(lg_init); |
378 | module_exit(lg_exit); | 419 | module_exit(lg_exit); |
379 | MODULE_LICENSE("GPL"); | 420 | MODULE_LICENSE("GPL"); |
380 | 421 |
drivers/hid/hid-lg.h
1 | #ifndef __HID_LG_H | 1 | #ifndef __HID_LG_H |
2 | #define __HID_LG_H | 2 | #define __HID_LG_H |
3 | 3 | ||
4 | #ifdef CONFIG_LOGITECH_FF | 4 | #ifdef CONFIG_LOGITECH_FF |
5 | int lgff_init(struct hid_device *hdev); | 5 | int lgff_init(struct hid_device *hdev); |
6 | #else | 6 | #else |
7 | static inline int lgff_init(struct hid_device *hdev) { return -1; } | 7 | static inline int lgff_init(struct hid_device *hdev) { return -1; } |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #ifdef CONFIG_LOGIRUMBLEPAD2_FF | 10 | #ifdef CONFIG_LOGIRUMBLEPAD2_FF |
11 | int lg2ff_init(struct hid_device *hdev); | 11 | int lg2ff_init(struct hid_device *hdev); |
12 | #else | 12 | #else |
13 | static inline int lg2ff_init(struct hid_device *hdev) { return -1; } | 13 | static inline int lg2ff_init(struct hid_device *hdev) { return -1; } |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #ifdef CONFIG_LOGIG940_FF | 16 | #ifdef CONFIG_LOGIG940_FF |
17 | int lg3ff_init(struct hid_device *hdev); | 17 | int lg3ff_init(struct hid_device *hdev); |
18 | #else | 18 | #else |
19 | static inline int lg3ff_init(struct hid_device *hdev) { return -1; } | 19 | static inline int lg3ff_init(struct hid_device *hdev) { return -1; } |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef CONFIG_LOGIWII_FF | ||
23 | int lg4ff_init(struct hid_device *hdev); | ||
24 | #else | ||
25 | static inline int lg4ff_init(struct hid_device *hdev) { return -1; } | ||
26 | #endif | ||
27 | |||
22 | #endif | 28 | #endif |
23 | 29 |
drivers/hid/hid-lg2ff.c
1 | /* | 1 | /* |
2 | * Force feedback support for Logitech Rumblepad 2 | 2 | * Force feedback support for Logitech RumblePad and Rumblepad 2 |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com> | 4 | * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | 23 | ||
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/hid.h> | 27 | #include <linux/hid.h> |
28 | 28 | ||
29 | #include "usbhid/usbhid.h" | 29 | #include "usbhid/usbhid.h" |
30 | #include "hid-lg.h" | 30 | #include "hid-lg.h" |
31 | 31 | ||
32 | struct lg2ff_device { | 32 | struct lg2ff_device { |
33 | struct hid_report *report; | 33 | struct hid_report *report; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static int play_effect(struct input_dev *dev, void *data, | 36 | static int play_effect(struct input_dev *dev, void *data, |
37 | struct ff_effect *effect) | 37 | struct ff_effect *effect) |
38 | { | 38 | { |
39 | struct hid_device *hid = input_get_drvdata(dev); | 39 | struct hid_device *hid = input_get_drvdata(dev); |
40 | struct lg2ff_device *lg2ff = data; | 40 | struct lg2ff_device *lg2ff = data; |
41 | int weak, strong; | 41 | int weak, strong; |
42 | 42 | ||
43 | strong = effect->u.rumble.strong_magnitude; | 43 | strong = effect->u.rumble.strong_magnitude; |
44 | weak = effect->u.rumble.weak_magnitude; | 44 | weak = effect->u.rumble.weak_magnitude; |
45 | 45 | ||
46 | if (weak || strong) { | 46 | if (weak || strong) { |
47 | weak = weak * 0xff / 0xffff; | 47 | weak = weak * 0xff / 0xffff; |
48 | strong = strong * 0xff / 0xffff; | 48 | strong = strong * 0xff / 0xffff; |
49 | 49 | ||
50 | lg2ff->report->field[0]->value[0] = 0x51; | 50 | lg2ff->report->field[0]->value[0] = 0x51; |
51 | lg2ff->report->field[0]->value[2] = weak; | 51 | lg2ff->report->field[0]->value[2] = weak; |
52 | lg2ff->report->field[0]->value[4] = strong; | 52 | lg2ff->report->field[0]->value[4] = strong; |
53 | } else { | 53 | } else { |
54 | lg2ff->report->field[0]->value[0] = 0xf3; | 54 | lg2ff->report->field[0]->value[0] = 0xf3; |
55 | lg2ff->report->field[0]->value[2] = 0x00; | 55 | lg2ff->report->field[0]->value[2] = 0x00; |
56 | lg2ff->report->field[0]->value[4] = 0x00; | 56 | lg2ff->report->field[0]->value[4] = 0x00; |
57 | } | 57 | } |
58 | 58 | ||
59 | usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT); | 59 | usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT); |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | int lg2ff_init(struct hid_device *hid) | 63 | int lg2ff_init(struct hid_device *hid) |
64 | { | 64 | { |
65 | struct lg2ff_device *lg2ff; | 65 | struct lg2ff_device *lg2ff; |
66 | struct hid_report *report; | 66 | struct hid_report *report; |
67 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 67 | struct hid_input *hidinput = list_entry(hid->inputs.next, |
68 | struct hid_input, list); | 68 | struct hid_input, list); |
69 | struct list_head *report_list = | 69 | struct list_head *report_list = |
70 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 70 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
71 | struct input_dev *dev = hidinput->input; | 71 | struct input_dev *dev = hidinput->input; |
72 | int error; | 72 | int error; |
73 | 73 | ||
74 | if (list_empty(report_list)) { | 74 | if (list_empty(report_list)) { |
75 | dev_err(&hid->dev, "no output report found\n"); | 75 | dev_err(&hid->dev, "no output report found\n"); |
76 | return -ENODEV; | 76 | return -ENODEV; |
77 | } | 77 | } |
78 | 78 | ||
79 | report = list_entry(report_list->next, struct hid_report, list); | 79 | report = list_entry(report_list->next, struct hid_report, list); |
80 | 80 | ||
81 | if (report->maxfield < 1) { | 81 | if (report->maxfield < 1) { |
82 | dev_err(&hid->dev, "output report is empty\n"); | 82 | dev_err(&hid->dev, "output report is empty\n"); |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | } | 84 | } |
85 | if (report->field[0]->report_count < 7) { | 85 | if (report->field[0]->report_count < 7) { |
86 | dev_err(&hid->dev, "not enough values in the field\n"); | 86 | dev_err(&hid->dev, "not enough values in the field\n"); |
87 | return -ENODEV; | 87 | return -ENODEV; |
88 | } | 88 | } |
89 | 89 | ||
90 | lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); | 90 | lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); |
91 | if (!lg2ff) | 91 | if (!lg2ff) |
92 | return -ENOMEM; | 92 | return -ENOMEM; |
93 | 93 | ||
94 | set_bit(FF_RUMBLE, dev->ffbit); | 94 | set_bit(FF_RUMBLE, dev->ffbit); |
95 | 95 | ||
96 | error = input_ff_create_memless(dev, lg2ff, play_effect); | 96 | error = input_ff_create_memless(dev, lg2ff, play_effect); |
97 | if (error) { | 97 | if (error) { |
98 | kfree(lg2ff); | 98 | kfree(lg2ff); |
99 | return error; | 99 | return error; |
100 | } | 100 | } |
101 | 101 | ||
102 | lg2ff->report = report; | 102 | lg2ff->report = report; |
103 | report->field[0]->value[0] = 0xf3; | 103 | report->field[0]->value[0] = 0xf3; |
104 | report->field[0]->value[1] = 0x00; | 104 | report->field[0]->value[1] = 0x00; |
105 | report->field[0]->value[2] = 0x00; | 105 | report->field[0]->value[2] = 0x00; |
106 | report->field[0]->value[3] = 0x00; | 106 | report->field[0]->value[3] = 0x00; |
107 | report->field[0]->value[4] = 0x00; | 107 | report->field[0]->value[4] = 0x00; |
108 | report->field[0]->value[5] = 0x00; | 108 | report->field[0]->value[5] = 0x00; |
109 | report->field[0]->value[6] = 0x00; | 109 | report->field[0]->value[6] = 0x00; |
110 | 110 | ||
111 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 111 | usbhid_submit_report(hid, report, USB_DIR_OUT); |
112 | 112 | ||
113 | dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by " | 113 | dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by " |
114 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); | 114 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); |
115 | 115 | ||
116 | return 0; | 116 | return 0; |
117 | } | 117 | } |
118 | 118 |
drivers/hid/hid-lg4ff.c
File was created | 1 | /* | |
2 | * Force feedback support for Logitech Speed Force Wireless | ||
3 | * | ||
4 | * http://wiibrew.org/wiki/Logitech_USB_steering_wheel | ||
5 | * | ||
6 | * Copyright (c) 2010 Simon Wood <simon@mungewell.org> | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <linux/input.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <linux/hid.h> | ||
29 | |||
30 | #include "usbhid/usbhid.h" | ||
31 | #include "hid-lg.h" | ||
32 | |||
33 | struct lg4ff_device { | ||
34 | struct hid_report *report; | ||
35 | }; | ||
36 | |||
37 | static const signed short ff4_wheel_ac[] = { | ||
38 | FF_CONSTANT, | ||
39 | FF_AUTOCENTER, | ||
40 | -1 | ||
41 | }; | ||
42 | |||
43 | static int hid_lg4ff_play(struct input_dev *dev, void *data, | ||
44 | struct ff_effect *effect) | ||
45 | { | ||
46 | struct hid_device *hid = input_get_drvdata(dev); | ||
47 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
48 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
49 | int x; | ||
50 | |||
51 | #define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff | ||
52 | |||
53 | switch (effect->type) { | ||
54 | case FF_CONSTANT: | ||
55 | x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ | ||
56 | CLAMP(x); | ||
57 | report->field[0]->value[0] = 0x11; /* Slot 1 */ | ||
58 | report->field[0]->value[1] = 0x10; | ||
59 | report->field[0]->value[2] = x; | ||
60 | report->field[0]->value[3] = 0x00; | ||
61 | report->field[0]->value[4] = 0x00; | ||
62 | report->field[0]->value[5] = 0x08; | ||
63 | report->field[0]->value[6] = 0x00; | ||
64 | dbg_hid("Autocenter, x=0x%02X\n", x); | ||
65 | |||
66 | usbhid_submit_report(hid, report, USB_DIR_OUT); | ||
67 | break; | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude) | ||
73 | { | ||
74 | struct hid_device *hid = input_get_drvdata(dev); | ||
75 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
76 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
77 | __s32 *value = report->field[0]->value; | ||
78 | |||
79 | *value++ = 0xfe; | ||
80 | *value++ = 0x0d; | ||
81 | *value++ = 0x07; | ||
82 | *value++ = 0x07; | ||
83 | *value++ = (magnitude >> 8) & 0xff; | ||
84 | *value++ = 0x00; | ||
85 | *value = 0x00; | ||
86 | |||
87 | usbhid_submit_report(hid, report, USB_DIR_OUT); | ||
88 | } | ||
89 | |||
90 | |||
91 | int lg4ff_init(struct hid_device *hid) | ||
92 | { | ||
93 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
94 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
95 | struct input_dev *dev = hidinput->input; | ||
96 | struct hid_report *report; | ||
97 | struct hid_field *field; | ||
98 | const signed short *ff_bits = ff4_wheel_ac; | ||
99 | int error; | ||
100 | int i; | ||
101 | |||
102 | /* Find the report to use */ | ||
103 | if (list_empty(report_list)) { | ||
104 | err_hid("No output report found"); | ||
105 | return -1; | ||
106 | } | ||
107 | |||
108 | /* Check that the report looks ok */ | ||
109 | report = list_entry(report_list->next, struct hid_report, list); | ||
110 | if (!report) { | ||
111 | err_hid("NULL output report"); | ||
112 | return -1; | ||
113 | } | ||
114 | |||
115 | field = report->field[0]; | ||
116 | if (!field) { | ||
117 | err_hid("NULL field"); | ||
118 | return -1; | ||
119 | } | ||
120 | |||
121 | for (i = 0; ff_bits[i] >= 0; i++) | ||
122 | set_bit(ff_bits[i], dev->ffbit); | ||
123 | |||
124 | error = input_ff_create_memless(dev, NULL, hid_lg4ff_play); | ||
125 | |||
126 | if (error) | ||
127 | return error; | ||
128 | |||
129 | if (test_bit(FF_AUTOCENTER, dev->ffbit)) | ||
130 | dev->ff->set_autocenter = hid_lg4ff_set_autocenter; | ||
131 | |||
132 | dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by " | ||
133 | "Simon Wood <simon@mungewell.org>\n"); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 |
drivers/hid/hid-magicmouse.c
1 | /* | 1 | /* |
2 | * Apple "Magic" Wireless Mouse driver | 2 | * Apple "Magic" Wireless Mouse driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> | 4 | * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> |
5 | * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com> | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | /* | 8 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 9 | * 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 | * 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 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 12 | * any later version. |
12 | */ | 13 | */ |
13 | 14 | ||
14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
15 | #include <linux/hid.h> | 16 | #include <linux/hid.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
19 | 20 | ||
20 | #include "hid-ids.h" | 21 | #include "hid-ids.h" |
21 | 22 | ||
22 | static bool emulate_3button = true; | 23 | static bool emulate_3button = true; |
23 | module_param(emulate_3button, bool, 0644); | 24 | module_param(emulate_3button, bool, 0644); |
24 | MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); | 25 | MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); |
25 | 26 | ||
26 | static int middle_button_start = -350; | 27 | static int middle_button_start = -350; |
27 | static int middle_button_stop = +350; | 28 | static int middle_button_stop = +350; |
28 | 29 | ||
29 | static bool emulate_scroll_wheel = true; | 30 | static bool emulate_scroll_wheel = true; |
30 | module_param(emulate_scroll_wheel, bool, 0644); | 31 | module_param(emulate_scroll_wheel, bool, 0644); |
31 | MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); | 32 | MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); |
32 | 33 | ||
33 | static unsigned int scroll_speed = 32; | 34 | static unsigned int scroll_speed = 32; |
34 | static int param_set_scroll_speed(const char *val, struct kernel_param *kp) { | 35 | static int param_set_scroll_speed(const char *val, struct kernel_param *kp) { |
35 | unsigned long speed; | 36 | unsigned long speed; |
36 | if (!val || strict_strtoul(val, 0, &speed) || speed > 63) | 37 | if (!val || strict_strtoul(val, 0, &speed) || speed > 63) |
37 | return -EINVAL; | 38 | return -EINVAL; |
38 | scroll_speed = speed; | 39 | scroll_speed = speed; |
39 | return 0; | 40 | return 0; |
40 | } | 41 | } |
41 | module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644); | 42 | module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644); |
42 | MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)"); | 43 | MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)"); |
43 | 44 | ||
44 | static bool scroll_acceleration = false; | 45 | static bool scroll_acceleration = false; |
45 | module_param(scroll_acceleration, bool, 0644); | 46 | module_param(scroll_acceleration, bool, 0644); |
46 | MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); | 47 | MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); |
47 | 48 | ||
48 | static bool report_touches = true; | 49 | static bool report_touches = true; |
49 | module_param(report_touches, bool, 0644); | 50 | module_param(report_touches, bool, 0644); |
50 | MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); | 51 | MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); |
51 | 52 | ||
52 | static bool report_undeciphered; | 53 | static bool report_undeciphered; |
53 | module_param(report_undeciphered, bool, 0644); | 54 | module_param(report_undeciphered, bool, 0644); |
54 | MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); | 55 | MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); |
55 | 56 | ||
56 | #define TOUCH_REPORT_ID 0x29 | 57 | #define TRACKPAD_REPORT_ID 0x28 |
58 | #define MOUSE_REPORT_ID 0x29 | ||
59 | #define DOUBLE_REPORT_ID 0xf7 | ||
57 | /* These definitions are not precise, but they're close enough. (Bits | 60 | /* These definitions are not precise, but they're close enough. (Bits |
58 | * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem | 61 | * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem |
59 | * to be some kind of bit mask -- 0x20 may be a near-field reading, | 62 | * to be some kind of bit mask -- 0x20 may be a near-field reading, |
60 | * and 0x40 is actual contact, and 0x10 may be a start/stop or change | 63 | * and 0x40 is actual contact, and 0x10 may be a start/stop or change |
61 | * indication.) | 64 | * indication.) |
62 | */ | 65 | */ |
63 | #define TOUCH_STATE_MASK 0xf0 | 66 | #define TOUCH_STATE_MASK 0xf0 |
64 | #define TOUCH_STATE_NONE 0x00 | 67 | #define TOUCH_STATE_NONE 0x00 |
65 | #define TOUCH_STATE_START 0x30 | 68 | #define TOUCH_STATE_START 0x30 |
66 | #define TOUCH_STATE_DRAG 0x40 | 69 | #define TOUCH_STATE_DRAG 0x40 |
67 | 70 | ||
68 | #define SCROLL_ACCEL_DEFAULT 7 | 71 | #define SCROLL_ACCEL_DEFAULT 7 |
69 | 72 | ||
73 | /* Single touch emulation should only begin when no touches are currently down. | ||
74 | * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches | ||
75 | * are down and the touch providing for single touch emulation is lifted, | ||
76 | * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is | ||
77 | * occuring, single_touch_id corresponds with the tracking id of the touch used. | ||
78 | */ | ||
79 | #define NO_TOUCHES -1 | ||
80 | #define SINGLE_TOUCH_UP -2 | ||
81 | |||
70 | /** | 82 | /** |
71 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. | 83 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. |
72 | * @input: Input device through which we report events. | 84 | * @input: Input device through which we report events. |
73 | * @quirks: Currently unused. | 85 | * @quirks: Currently unused. |
74 | * @last_timestamp: Timestamp from most recent (18-bit) touch report | ||
75 | * (units of milliseconds over short windows, but seems to | ||
76 | * increase faster when there are no touches). | ||
77 | * @delta_time: 18-bit difference between the two most recent touch | ||
78 | * reports from the mouse. | ||
79 | * @ntouches: Number of touches in most recent touch report. | 86 | * @ntouches: Number of touches in most recent touch report. |
80 | * @scroll_accel: Number of consecutive scroll motions. | 87 | * @scroll_accel: Number of consecutive scroll motions. |
81 | * @scroll_jiffies: Time of last scroll motion. | 88 | * @scroll_jiffies: Time of last scroll motion. |
82 | * @touches: Most recent data for a touch, indexed by tracking ID. | 89 | * @touches: Most recent data for a touch, indexed by tracking ID. |
83 | * @tracking_ids: Mapping of current touch input data to @touches. | 90 | * @tracking_ids: Mapping of current touch input data to @touches. |
84 | */ | 91 | */ |
85 | struct magicmouse_sc { | 92 | struct magicmouse_sc { |
86 | struct input_dev *input; | 93 | struct input_dev *input; |
87 | unsigned long quirks; | 94 | unsigned long quirks; |
88 | 95 | ||
89 | int last_timestamp; | ||
90 | int delta_time; | ||
91 | int ntouches; | 96 | int ntouches; |
92 | int scroll_accel; | 97 | int scroll_accel; |
93 | unsigned long scroll_jiffies; | 98 | unsigned long scroll_jiffies; |
94 | 99 | ||
95 | struct { | 100 | struct { |
96 | short x; | 101 | short x; |
97 | short y; | 102 | short y; |
98 | short scroll_x; | 103 | short scroll_x; |
99 | short scroll_y; | 104 | short scroll_y; |
100 | u8 size; | 105 | u8 size; |
101 | u8 down; | ||
102 | } touches[16]; | 106 | } touches[16]; |
103 | int tracking_ids[16]; | 107 | int tracking_ids[16]; |
108 | int single_touch_id; | ||
104 | }; | 109 | }; |
105 | 110 | ||
106 | static int magicmouse_firm_touch(struct magicmouse_sc *msc) | 111 | static int magicmouse_firm_touch(struct magicmouse_sc *msc) |
107 | { | 112 | { |
108 | int touch = -1; | 113 | int touch = -1; |
109 | int ii; | 114 | int ii; |
110 | 115 | ||
111 | /* If there is only one "firm" touch, set touch to its | 116 | /* If there is only one "firm" touch, set touch to its |
112 | * tracking ID. | 117 | * tracking ID. |
113 | */ | 118 | */ |
114 | for (ii = 0; ii < msc->ntouches; ii++) { | 119 | for (ii = 0; ii < msc->ntouches; ii++) { |
115 | int idx = msc->tracking_ids[ii]; | 120 | int idx = msc->tracking_ids[ii]; |
116 | if (msc->touches[idx].size < 8) { | 121 | if (msc->touches[idx].size < 8) { |
117 | /* Ignore this touch. */ | 122 | /* Ignore this touch. */ |
118 | } else if (touch >= 0) { | 123 | } else if (touch >= 0) { |
119 | touch = -1; | 124 | touch = -1; |
120 | break; | 125 | break; |
121 | } else { | 126 | } else { |
122 | touch = idx; | 127 | touch = idx; |
123 | } | 128 | } |
124 | } | 129 | } |
125 | 130 | ||
126 | return touch; | 131 | return touch; |
127 | } | 132 | } |
128 | 133 | ||
129 | static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) | 134 | static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) |
130 | { | 135 | { |
131 | int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 | | 136 | int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 | |
132 | test_bit(BTN_RIGHT, msc->input->key) << 1 | | 137 | test_bit(BTN_RIGHT, msc->input->key) << 1 | |
133 | test_bit(BTN_MIDDLE, msc->input->key) << 2; | 138 | test_bit(BTN_MIDDLE, msc->input->key) << 2; |
134 | 139 | ||
135 | if (emulate_3button) { | 140 | if (emulate_3button) { |
136 | int id; | 141 | int id; |
137 | 142 | ||
138 | /* If some button was pressed before, keep it held | 143 | /* If some button was pressed before, keep it held |
139 | * down. Otherwise, if there's exactly one firm | 144 | * down. Otherwise, if there's exactly one firm |
140 | * touch, use that to override the mouse's guess. | 145 | * touch, use that to override the mouse's guess. |
141 | */ | 146 | */ |
142 | if (state == 0) { | 147 | if (state == 0) { |
143 | /* The button was released. */ | 148 | /* The button was released. */ |
144 | } else if (last_state != 0) { | 149 | } else if (last_state != 0) { |
145 | state = last_state; | 150 | state = last_state; |
146 | } else if ((id = magicmouse_firm_touch(msc)) >= 0) { | 151 | } else if ((id = magicmouse_firm_touch(msc)) >= 0) { |
147 | int x = msc->touches[id].x; | 152 | int x = msc->touches[id].x; |
148 | if (x < middle_button_start) | 153 | if (x < middle_button_start) |
149 | state = 1; | 154 | state = 1; |
150 | else if (x > middle_button_stop) | 155 | else if (x > middle_button_stop) |
151 | state = 2; | 156 | state = 2; |
152 | else | 157 | else |
153 | state = 4; | 158 | state = 4; |
154 | } /* else: we keep the mouse's guess */ | 159 | } /* else: we keep the mouse's guess */ |
155 | 160 | ||
156 | input_report_key(msc->input, BTN_MIDDLE, state & 4); | 161 | input_report_key(msc->input, BTN_MIDDLE, state & 4); |
157 | } | 162 | } |
158 | 163 | ||
159 | input_report_key(msc->input, BTN_LEFT, state & 1); | 164 | input_report_key(msc->input, BTN_LEFT, state & 1); |
160 | input_report_key(msc->input, BTN_RIGHT, state & 2); | 165 | input_report_key(msc->input, BTN_RIGHT, state & 2); |
161 | 166 | ||
162 | if (state != last_state) | 167 | if (state != last_state) |
163 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; | 168 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; |
164 | } | 169 | } |
165 | 170 | ||
166 | static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) | 171 | static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) |
167 | { | 172 | { |
168 | struct input_dev *input = msc->input; | 173 | struct input_dev *input = msc->input; |
169 | __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; | 174 | int id, x, y, size, orientation, touch_major, touch_minor, state, down; |
170 | int misc = tdata[5] | tdata[6] << 8; | ||
171 | int id = (misc >> 6) & 15; | ||
172 | int x = x_y << 12 >> 20; | ||
173 | int y = -(x_y >> 20); | ||
174 | int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; | ||
175 | 175 | ||
176 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { | ||
177 | id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; | ||
178 | x = (tdata[1] << 28 | tdata[0] << 20) >> 20; | ||
179 | y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); | ||
180 | size = tdata[5] & 0x3f; | ||
181 | orientation = (tdata[6] >> 2) - 32; | ||
182 | touch_major = tdata[3]; | ||
183 | touch_minor = tdata[4]; | ||
184 | state = tdata[7] & TOUCH_STATE_MASK; | ||
185 | down = state != TOUCH_STATE_NONE; | ||
186 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
187 | id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; | ||
188 | x = (tdata[1] << 27 | tdata[0] << 19) >> 19; | ||
189 | y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); | ||
190 | size = tdata[6] & 0x3f; | ||
191 | orientation = (tdata[7] >> 2) - 32; | ||
192 | touch_major = tdata[4]; | ||
193 | touch_minor = tdata[5]; | ||
194 | state = tdata[8] & TOUCH_STATE_MASK; | ||
195 | down = state != TOUCH_STATE_NONE; | ||
196 | } | ||
197 | |||
176 | /* Store tracking ID and other fields. */ | 198 | /* Store tracking ID and other fields. */ |
177 | msc->tracking_ids[raw_id] = id; | 199 | msc->tracking_ids[raw_id] = id; |
178 | msc->touches[id].x = x; | 200 | msc->touches[id].x = x; |
179 | msc->touches[id].y = y; | 201 | msc->touches[id].y = y; |
180 | msc->touches[id].size = misc & 63; | 202 | msc->touches[id].size = size; |
181 | 203 | ||
182 | /* If requested, emulate a scroll wheel by detecting small | 204 | /* If requested, emulate a scroll wheel by detecting small |
183 | * vertical touch motions. | 205 | * vertical touch motions. |
184 | */ | 206 | */ |
185 | if (emulate_scroll_wheel) { | 207 | if (emulate_scroll_wheel) { |
186 | unsigned long now = jiffies; | 208 | unsigned long now = jiffies; |
187 | int step_x = msc->touches[id].scroll_x - x; | 209 | int step_x = msc->touches[id].scroll_x - x; |
188 | int step_y = msc->touches[id].scroll_y - y; | 210 | int step_y = msc->touches[id].scroll_y - y; |
189 | 211 | ||
190 | /* Calculate and apply the scroll motion. */ | 212 | /* Calculate and apply the scroll motion. */ |
191 | switch (tdata[7] & TOUCH_STATE_MASK) { | 213 | switch (state) { |
192 | case TOUCH_STATE_START: | 214 | case TOUCH_STATE_START: |
193 | msc->touches[id].scroll_x = x; | 215 | msc->touches[id].scroll_x = x; |
194 | msc->touches[id].scroll_y = y; | 216 | msc->touches[id].scroll_y = y; |
195 | 217 | ||
196 | /* Reset acceleration after half a second. */ | 218 | /* Reset acceleration after half a second. */ |
197 | if (scroll_acceleration && time_before(now, | 219 | if (scroll_acceleration && time_before(now, |
198 | msc->scroll_jiffies + HZ / 2)) | 220 | msc->scroll_jiffies + HZ / 2)) |
199 | msc->scroll_accel = max_t(int, | 221 | msc->scroll_accel = max_t(int, |
200 | msc->scroll_accel - 1, 1); | 222 | msc->scroll_accel - 1, 1); |
201 | else | 223 | else |
202 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; | 224 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; |
203 | 225 | ||
204 | break; | 226 | break; |
205 | case TOUCH_STATE_DRAG: | 227 | case TOUCH_STATE_DRAG: |
206 | step_x /= (64 - (int)scroll_speed) * msc->scroll_accel; | 228 | step_x /= (64 - (int)scroll_speed) * msc->scroll_accel; |
207 | if (step_x != 0) { | 229 | if (step_x != 0) { |
208 | msc->touches[id].scroll_x -= step_x * | 230 | msc->touches[id].scroll_x -= step_x * |
209 | (64 - scroll_speed) * msc->scroll_accel; | 231 | (64 - scroll_speed) * msc->scroll_accel; |
210 | msc->scroll_jiffies = now; | 232 | msc->scroll_jiffies = now; |
211 | input_report_rel(input, REL_HWHEEL, -step_x); | 233 | input_report_rel(input, REL_HWHEEL, -step_x); |
212 | } | 234 | } |
213 | 235 | ||
214 | step_y /= (64 - (int)scroll_speed) * msc->scroll_accel; | 236 | step_y /= (64 - (int)scroll_speed) * msc->scroll_accel; |
215 | if (step_y != 0) { | 237 | if (step_y != 0) { |
216 | msc->touches[id].scroll_y -= step_y * | 238 | msc->touches[id].scroll_y -= step_y * |
217 | (64 - scroll_speed) * msc->scroll_accel; | 239 | (64 - scroll_speed) * msc->scroll_accel; |
218 | msc->scroll_jiffies = now; | 240 | msc->scroll_jiffies = now; |
219 | input_report_rel(input, REL_WHEEL, step_y); | 241 | input_report_rel(input, REL_WHEEL, step_y); |
220 | } | 242 | } |
221 | break; | 243 | break; |
222 | } | 244 | } |
223 | } | 245 | } |
224 | 246 | ||
247 | if (down) { | ||
248 | msc->ntouches++; | ||
249 | if (msc->single_touch_id == NO_TOUCHES) | ||
250 | msc->single_touch_id = id; | ||
251 | } else if (msc->single_touch_id == id) | ||
252 | msc->single_touch_id = SINGLE_TOUCH_UP; | ||
253 | |||
225 | /* Generate the input events for this touch. */ | 254 | /* Generate the input events for this touch. */ |
226 | if (report_touches && down) { | 255 | if (report_touches && down) { |
227 | int orientation = (misc >> 10) - 32; | ||
228 | |||
229 | msc->touches[id].down = 1; | ||
230 | |||
231 | input_report_abs(input, ABS_MT_TRACKING_ID, id); | 256 | input_report_abs(input, ABS_MT_TRACKING_ID, id); |
232 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); | 257 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); |
233 | input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); | 258 | input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); |
234 | input_report_abs(input, ABS_MT_ORIENTATION, orientation); | 259 | input_report_abs(input, ABS_MT_ORIENTATION, orientation); |
235 | input_report_abs(input, ABS_MT_POSITION_X, x); | 260 | input_report_abs(input, ABS_MT_POSITION_X, x); |
236 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 261 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
237 | 262 | ||
238 | if (report_undeciphered) | 263 | if (report_undeciphered) { |
239 | input_event(input, EV_MSC, MSC_RAW, tdata[7]); | 264 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) |
265 | input_event(input, EV_MSC, MSC_RAW, tdata[7]); | ||
266 | else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
267 | input_event(input, EV_MSC, MSC_RAW, tdata[8]); | ||
268 | } | ||
240 | 269 | ||
241 | input_mt_sync(input); | 270 | input_mt_sync(input); |
242 | } | 271 | } |
243 | } | 272 | } |
244 | 273 | ||
245 | static int magicmouse_raw_event(struct hid_device *hdev, | 274 | static int magicmouse_raw_event(struct hid_device *hdev, |
246 | struct hid_report *report, u8 *data, int size) | 275 | struct hid_report *report, u8 *data, int size) |
247 | { | 276 | { |
248 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | 277 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); |
249 | struct input_dev *input = msc->input; | 278 | struct input_dev *input = msc->input; |
250 | int x, y, ts, ii, clicks, last_up; | 279 | int x = 0, y = 0, ii, clicks = 0, npoints; |
251 | 280 | ||
252 | switch (data[0]) { | 281 | switch (data[0]) { |
253 | case 0x10: | 282 | case TRACKPAD_REPORT_ID: |
254 | if (size != 6) | 283 | /* Expect four bytes of prefix, and N*9 bytes of touch data. */ |
284 | if (size < 4 || ((size - 4) % 9) != 0) | ||
255 | return 0; | 285 | return 0; |
256 | x = (__s16)(data[2] | data[3] << 8); | 286 | npoints = (size - 4) / 9; |
257 | y = (__s16)(data[4] | data[5] << 8); | 287 | msc->ntouches = 0; |
288 | for (ii = 0; ii < npoints; ii++) | ||
289 | magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); | ||
290 | |||
291 | /* We don't need an MT sync here because trackpad emits a | ||
292 | * BTN_TOUCH event in a new frame when all touches are released. | ||
293 | */ | ||
294 | if (msc->ntouches == 0) | ||
295 | msc->single_touch_id = NO_TOUCHES; | ||
296 | |||
258 | clicks = data[1]; | 297 | clicks = data[1]; |
298 | |||
299 | /* The following bits provide a device specific timestamp. They | ||
300 | * are unused here. | ||
301 | * | ||
302 | * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; | ||
303 | */ | ||
259 | break; | 304 | break; |
260 | case TOUCH_REPORT_ID: | 305 | case MOUSE_REPORT_ID: |
261 | /* Expect six bytes of prefix, and N*8 bytes of touch data. */ | 306 | /* Expect six bytes of prefix, and N*8 bytes of touch data. */ |
262 | if (size < 6 || ((size - 6) % 8) != 0) | 307 | if (size < 6 || ((size - 6) % 8) != 0) |
263 | return 0; | 308 | return 0; |
264 | ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; | 309 | npoints = (size - 6) / 8; |
265 | msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; | 310 | msc->ntouches = 0; |
266 | msc->last_timestamp = ts; | 311 | for (ii = 0; ii < npoints; ii++) |
267 | msc->ntouches = (size - 6) / 8; | ||
268 | for (ii = 0; ii < msc->ntouches; ii++) | ||
269 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); | 312 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); |
270 | 313 | ||
271 | if (report_touches) { | 314 | if (report_touches && msc->ntouches == 0) |
272 | last_up = 1; | 315 | input_mt_sync(input); |
273 | for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { | ||
274 | if (msc->touches[ii].down) { | ||
275 | last_up = 0; | ||
276 | msc->touches[ii].down = 0; | ||
277 | } | ||
278 | } | ||
279 | if (last_up) { | ||
280 | input_mt_sync(input); | ||
281 | } | ||
282 | } | ||
283 | 316 | ||
284 | /* When emulating three-button mode, it is important | 317 | /* When emulating three-button mode, it is important |
285 | * to have the current touch information before | 318 | * to have the current touch information before |
286 | * generating a click event. | 319 | * generating a click event. |
287 | */ | 320 | */ |
288 | x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; | 321 | x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; |
289 | y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; | 322 | y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; |
290 | clicks = data[3]; | 323 | clicks = data[3]; |
324 | |||
325 | /* The following bits provide a device specific timestamp. They | ||
326 | * are unused here. | ||
327 | * | ||
328 | * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; | ||
329 | */ | ||
291 | break; | 330 | break; |
292 | case 0x20: /* Theoretically battery status (0-100), but I have | 331 | case DOUBLE_REPORT_ID: |
293 | * never seen it -- maybe it is only upon request. | 332 | /* Sometimes the trackpad sends two touch reports in one |
294 | */ | 333 | * packet. |
295 | case 0x60: /* Unknown, maybe laser on/off. */ | 334 | */ |
296 | case 0x61: /* Laser reflection status change. | 335 | magicmouse_raw_event(hdev, report, data + 2, data[1]); |
297 | * data[1]: 0 = spotted, 1 = lost | 336 | magicmouse_raw_event(hdev, report, data + 2 + data[1], |
298 | */ | 337 | size - 2 - data[1]); |
338 | break; | ||
299 | default: | 339 | default: |
300 | return 0; | 340 | return 0; |
301 | } | 341 | } |
302 | 342 | ||
303 | magicmouse_emit_buttons(msc, clicks & 3); | 343 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
304 | input_report_rel(input, REL_X, x); | 344 | magicmouse_emit_buttons(msc, clicks & 3); |
305 | input_report_rel(input, REL_Y, y); | 345 | input_report_rel(input, REL_X, x); |
346 | input_report_rel(input, REL_Y, y); | ||
347 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
348 | input_report_key(input, BTN_MOUSE, clicks & 1); | ||
349 | input_report_key(input, BTN_TOUCH, msc->ntouches > 0); | ||
350 | input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); | ||
351 | input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); | ||
352 | input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); | ||
353 | input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); | ||
354 | if (msc->single_touch_id >= 0) { | ||
355 | input_report_abs(input, ABS_X, | ||
356 | msc->touches[msc->single_touch_id].x); | ||
357 | input_report_abs(input, ABS_Y, | ||
358 | msc->touches[msc->single_touch_id].y); | ||
359 | } | ||
360 | } | ||
361 | |||
306 | input_sync(input); | 362 | input_sync(input); |
307 | return 1; | 363 | return 1; |
308 | } | 364 | } |
309 | 365 | ||
310 | static int magicmouse_input_open(struct input_dev *dev) | ||
311 | { | ||
312 | struct hid_device *hid = input_get_drvdata(dev); | ||
313 | |||
314 | return hid->ll_driver->open(hid); | ||
315 | } | ||
316 | |||
317 | static void magicmouse_input_close(struct input_dev *dev) | ||
318 | { | ||
319 | struct hid_device *hid = input_get_drvdata(dev); | ||
320 | |||
321 | hid->ll_driver->close(hid); | ||
322 | } | ||
323 | |||
324 | static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) | 366 | static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) |
325 | { | 367 | { |
326 | input_set_drvdata(input, hdev); | ||
327 | input->event = hdev->ll_driver->hidinput_input_event; | ||
328 | input->open = magicmouse_input_open; | ||
329 | input->close = magicmouse_input_close; | ||
330 | |||
331 | input->name = hdev->name; | ||
332 | input->phys = hdev->phys; | ||
333 | input->uniq = hdev->uniq; | ||
334 | input->id.bustype = hdev->bus; | ||
335 | input->id.vendor = hdev->vendor; | ||
336 | input->id.product = hdev->product; | ||
337 | input->id.version = hdev->version; | ||
338 | input->dev.parent = hdev->dev.parent; | ||
339 | |||
340 | __set_bit(EV_KEY, input->evbit); | 368 | __set_bit(EV_KEY, input->evbit); |
341 | __set_bit(BTN_LEFT, input->keybit); | ||
342 | __set_bit(BTN_RIGHT, input->keybit); | ||
343 | if (emulate_3button) | ||
344 | __set_bit(BTN_MIDDLE, input->keybit); | ||
345 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
346 | 369 | ||
347 | __set_bit(EV_REL, input->evbit); | 370 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
348 | __set_bit(REL_X, input->relbit); | 371 | __set_bit(BTN_LEFT, input->keybit); |
349 | __set_bit(REL_Y, input->relbit); | 372 | __set_bit(BTN_RIGHT, input->keybit); |
350 | if (emulate_scroll_wheel) { | 373 | if (emulate_3button) |
351 | __set_bit(REL_WHEEL, input->relbit); | 374 | __set_bit(BTN_MIDDLE, input->keybit); |
352 | __set_bit(REL_HWHEEL, input->relbit); | 375 | |
376 | __set_bit(EV_REL, input->evbit); | ||
377 | __set_bit(REL_X, input->relbit); | ||
378 | __set_bit(REL_Y, input->relbit); | ||
379 | if (emulate_scroll_wheel) { | ||
380 | __set_bit(REL_WHEEL, input->relbit); | ||
381 | __set_bit(REL_HWHEEL, input->relbit); | ||
382 | } | ||
383 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
384 | __set_bit(BTN_MOUSE, input->keybit); | ||
385 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
386 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | ||
387 | __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); | ||
388 | __set_bit(BTN_TOOL_QUADTAP, input->keybit); | ||
389 | __set_bit(BTN_TOUCH, input->keybit); | ||
353 | } | 390 | } |
354 | 391 | ||
355 | if (report_touches) { | 392 | if (report_touches) { |
356 | __set_bit(EV_ABS, input->evbit); | 393 | __set_bit(EV_ABS, input->evbit); |
357 | 394 | ||
358 | input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); | 395 | input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); |
359 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); | 396 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); |
360 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); | 397 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); |
361 | input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); | 398 | input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); |
362 | input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, | 399 | |
363 | 4, 0); | ||
364 | /* Note: Touch Y position from the device is inverted relative | 400 | /* Note: Touch Y position from the device is inverted relative |
365 | * to how pointer motion is reported (and relative to how USB | 401 | * to how pointer motion is reported (and relative to how USB |
366 | * HID recommends the coordinates work). This driver keeps | 402 | * HID recommends the coordinates work). This driver keeps |
367 | * the origin at the same position, and just uses the additive | 403 | * the origin at the same position, and just uses the additive |
368 | * inverse of the reported Y. | 404 | * inverse of the reported Y. |
369 | */ | 405 | */ |
370 | input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, | 406 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
371 | 4, 0); | 407 | input_set_abs_params(input, ABS_MT_POSITION_X, -1100, |
408 | 1358, 4, 0); | ||
409 | input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, | ||
410 | 2047, 4, 0); | ||
411 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
412 | input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); | ||
413 | input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); | ||
414 | input_set_abs_params(input, ABS_MT_POSITION_X, -2909, | ||
415 | 3167, 4, 0); | ||
416 | input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, | ||
417 | 2565, 4, 0); | ||
418 | } | ||
372 | } | 419 | } |
373 | 420 | ||
374 | if (report_undeciphered) { | 421 | if (report_undeciphered) { |
375 | __set_bit(EV_MSC, input->evbit); | 422 | __set_bit(EV_MSC, input->evbit); |
376 | __set_bit(MSC_RAW, input->mscbit); | 423 | __set_bit(MSC_RAW, input->mscbit); |
377 | } | 424 | } |
378 | } | 425 | } |
379 | 426 | ||
427 | static int magicmouse_input_mapping(struct hid_device *hdev, | ||
428 | struct hid_input *hi, struct hid_field *field, | ||
429 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
430 | { | ||
431 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | ||
432 | |||
433 | if (!msc->input) | ||
434 | msc->input = hi->input; | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
380 | static int magicmouse_probe(struct hid_device *hdev, | 439 | static int magicmouse_probe(struct hid_device *hdev, |
381 | const struct hid_device_id *id) | 440 | const struct hid_device_id *id) |
382 | { | 441 | { |
383 | __u8 feature_1[] = { 0xd7, 0x01 }; | 442 | __u8 feature[] = { 0xd7, 0x01 }; |
384 | __u8 feature_2[] = { 0xf8, 0x01, 0x32 }; | ||
385 | struct input_dev *input; | ||
386 | struct magicmouse_sc *msc; | 443 | struct magicmouse_sc *msc; |
387 | struct hid_report *report; | 444 | struct hid_report *report; |
388 | int ret; | 445 | int ret; |
389 | 446 | ||
390 | msc = kzalloc(sizeof(*msc), GFP_KERNEL); | 447 | msc = kzalloc(sizeof(*msc), GFP_KERNEL); |
391 | if (msc == NULL) { | 448 | if (msc == NULL) { |
392 | dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n"); | 449 | dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n"); |
393 | return -ENOMEM; | 450 | return -ENOMEM; |
394 | } | 451 | } |
395 | 452 | ||
396 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; | 453 | msc->scroll_accel = SCROLL_ACCEL_DEFAULT; |
397 | 454 | ||
398 | msc->quirks = id->driver_data; | 455 | msc->quirks = id->driver_data; |
399 | hid_set_drvdata(hdev, msc); | 456 | hid_set_drvdata(hdev, msc); |
400 | 457 | ||
458 | msc->single_touch_id = NO_TOUCHES; | ||
459 | |||
401 | ret = hid_parse(hdev); | 460 | ret = hid_parse(hdev); |
402 | if (ret) { | 461 | if (ret) { |
403 | dev_err(&hdev->dev, "magicmouse hid parse failed\n"); | 462 | dev_err(&hdev->dev, "magicmouse hid parse failed\n"); |
404 | goto err_free; | 463 | goto err_free; |
405 | } | 464 | } |
406 | 465 | ||
407 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 466 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
408 | if (ret) { | 467 | if (ret) { |
409 | dev_err(&hdev->dev, "magicmouse hw start failed\n"); | 468 | dev_err(&hdev->dev, "magicmouse hw start failed\n"); |
410 | goto err_free; | 469 | goto err_free; |
411 | } | 470 | } |
412 | 471 | ||
413 | /* we are handling the input ourselves */ | 472 | /* We do this after hid-input is done parsing reports so that |
414 | hidinput_disconnect(hdev); | 473 | * hid-input uses the most natural button and axis IDs. |
474 | */ | ||
475 | if (msc->input) | ||
476 | magicmouse_setup_input(msc->input, hdev); | ||
415 | 477 | ||
416 | report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); | 478 | if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) |
479 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
480 | MOUSE_REPORT_ID); | ||
481 | else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
482 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
483 | TRACKPAD_REPORT_ID); | ||
484 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
485 | DOUBLE_REPORT_ID); | ||
486 | } | ||
487 | |||
417 | if (!report) { | 488 | if (!report) { |
418 | dev_err(&hdev->dev, "unable to register touch report\n"); | 489 | dev_err(&hdev->dev, "unable to register touch report\n"); |
419 | ret = -ENOMEM; | 490 | ret = -ENOMEM; |
420 | goto err_stop_hw; | 491 | goto err_stop_hw; |
drivers/hid/hid-ntrig.c
1 | /* | 1 | /* |
2 | * HID driver for N-Trig touchscreens | 2 | * HID driver for N-Trig touchscreens |
3 | * | 3 | * |
4 | * Copyright (c) 2008-2010 Rafi Rubin | 4 | * Copyright (c) 2008-2010 Rafi Rubin |
5 | * Copyright (c) 2009-2010 Stephane Chatty | 5 | * Copyright (c) 2009-2010 Stephane Chatty |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
11 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
12 | * Software Foundation; either version 2 of the License, or (at your option) | 12 | * Software Foundation; either version 2 of the License, or (at your option) |
13 | * any later version. | 13 | * any later version. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
18 | #include <linux/usb.h> | 18 | #include <linux/usb.h> |
19 | #include "usbhid/usbhid.h" | 19 | #include "usbhid/usbhid.h" |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | #define NTRIG_DUPLICATE_USAGES 0x001 | 25 | #define NTRIG_DUPLICATE_USAGES 0x001 |
26 | 26 | ||
27 | static unsigned int min_width; | 27 | static unsigned int min_width; |
28 | module_param(min_width, uint, 0644); | 28 | module_param(min_width, uint, 0644); |
29 | MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept."); | 29 | MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept."); |
30 | 30 | ||
31 | static unsigned int min_height; | 31 | static unsigned int min_height; |
32 | module_param(min_height, uint, 0644); | 32 | module_param(min_height, uint, 0644); |
33 | MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept."); | 33 | MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept."); |
34 | 34 | ||
35 | static unsigned int activate_slack = 1; | 35 | static unsigned int activate_slack = 1; |
36 | module_param(activate_slack, uint, 0644); | 36 | module_param(activate_slack, uint, 0644); |
37 | MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at " | 37 | MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at " |
38 | "the start of touch input."); | 38 | "the start of touch input."); |
39 | 39 | ||
40 | static unsigned int deactivate_slack = 4; | 40 | static unsigned int deactivate_slack = 4; |
41 | module_param(deactivate_slack, uint, 0644); | 41 | module_param(deactivate_slack, uint, 0644); |
42 | MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before " | 42 | MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before " |
43 | "deactivating touch."); | 43 | "deactivating touch."); |
44 | 44 | ||
45 | static unsigned int activation_width = 64; | 45 | static unsigned int activation_width = 64; |
46 | module_param(activation_width, uint, 0644); | 46 | module_param(activation_width, uint, 0644); |
47 | MODULE_PARM_DESC(activation_width, "Width threshold to immediately start " | 47 | MODULE_PARM_DESC(activation_width, "Width threshold to immediately start " |
48 | "processing touch events."); | 48 | "processing touch events."); |
49 | 49 | ||
50 | static unsigned int activation_height = 32; | 50 | static unsigned int activation_height = 32; |
51 | module_param(activation_height, uint, 0644); | 51 | module_param(activation_height, uint, 0644); |
52 | MODULE_PARM_DESC(activation_height, "Height threshold to immediately start " | 52 | MODULE_PARM_DESC(activation_height, "Height threshold to immediately start " |
53 | "processing touch events."); | 53 | "processing touch events."); |
54 | 54 | ||
55 | struct ntrig_data { | 55 | struct ntrig_data { |
56 | /* Incoming raw values for a single contact */ | 56 | /* Incoming raw values for a single contact */ |
57 | __u16 x, y, w, h; | 57 | __u16 x, y, w, h; |
58 | __u16 id; | 58 | __u16 id; |
59 | 59 | ||
60 | bool tipswitch; | 60 | bool tipswitch; |
61 | bool confidence; | 61 | bool confidence; |
62 | bool first_contact_touch; | 62 | bool first_contact_touch; |
63 | 63 | ||
64 | bool reading_mt; | 64 | bool reading_mt; |
65 | 65 | ||
66 | __u8 mt_footer[4]; | 66 | __u8 mt_footer[4]; |
67 | __u8 mt_foot_count; | 67 | __u8 mt_foot_count; |
68 | 68 | ||
69 | /* The current activation state. */ | 69 | /* The current activation state. */ |
70 | __s8 act_state; | 70 | __s8 act_state; |
71 | 71 | ||
72 | /* Empty frames to ignore before recognizing the end of activity */ | 72 | /* Empty frames to ignore before recognizing the end of activity */ |
73 | __s8 deactivate_slack; | 73 | __s8 deactivate_slack; |
74 | 74 | ||
75 | /* Frames to ignore before acknowledging the start of activity */ | 75 | /* Frames to ignore before acknowledging the start of activity */ |
76 | __s8 activate_slack; | 76 | __s8 activate_slack; |
77 | 77 | ||
78 | /* Minimum size contact to accept */ | 78 | /* Minimum size contact to accept */ |
79 | __u16 min_width; | 79 | __u16 min_width; |
80 | __u16 min_height; | 80 | __u16 min_height; |
81 | 81 | ||
82 | /* Threshold to override activation slack */ | 82 | /* Threshold to override activation slack */ |
83 | __u16 activation_width; | 83 | __u16 activation_width; |
84 | __u16 activation_height; | 84 | __u16 activation_height; |
85 | 85 | ||
86 | __u16 sensor_logical_width; | 86 | __u16 sensor_logical_width; |
87 | __u16 sensor_logical_height; | 87 | __u16 sensor_logical_height; |
88 | __u16 sensor_physical_width; | 88 | __u16 sensor_physical_width; |
89 | __u16 sensor_physical_height; | 89 | __u16 sensor_physical_height; |
90 | }; | 90 | }; |
91 | 91 | ||
92 | 92 | ||
93 | /* | ||
94 | * This function converts the 4 byte raw firmware code into | ||
95 | * a string containing 5 comma separated numbers. | ||
96 | */ | ||
97 | static int ntrig_version_string(unsigned char *raw, char *buf) | ||
98 | { | ||
99 | __u8 a = (raw[1] & 0x0e) >> 1; | ||
100 | __u8 b = (raw[0] & 0x3c) >> 2; | ||
101 | __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5); | ||
102 | __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5); | ||
103 | __u8 e = raw[2] & 0x07; | ||
104 | |||
105 | /* | ||
106 | * As yet unmapped bits: | ||
107 | * 0b11000000 0b11110001 0b00011000 0b00011000 | ||
108 | */ | ||
109 | |||
110 | return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e); | ||
111 | } | ||
112 | |||
113 | static void ntrig_report_version(struct hid_device *hdev) | ||
114 | { | ||
115 | int ret; | ||
116 | char buf[20]; | ||
117 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | ||
118 | unsigned char *data = kmalloc(8, GFP_KERNEL); | ||
119 | |||
120 | if (!data) | ||
121 | goto err_free; | ||
122 | |||
123 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
124 | USB_REQ_CLEAR_FEATURE, | ||
125 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | ||
126 | USB_DIR_IN, | ||
127 | 0x30c, 1, data, 8, | ||
128 | USB_CTRL_SET_TIMEOUT); | ||
129 | |||
130 | if (ret == 8) { | ||
131 | ret = ntrig_version_string(&data[2], buf); | ||
132 | |||
133 | dev_info(&hdev->dev, | ||
134 | "Firmware version: %s (%02x%02x %02x%02x)\n", | ||
135 | buf, data[2], data[3], data[4], data[5]); | ||
136 | } | ||
137 | |||
138 | err_free: | ||
139 | kfree(data); | ||
140 | } | ||
141 | |||
93 | static ssize_t show_phys_width(struct device *dev, | 142 | static ssize_t show_phys_width(struct device *dev, |
94 | struct device_attribute *attr, | 143 | struct device_attribute *attr, |
95 | char *buf) | 144 | char *buf) |
96 | { | 145 | { |
97 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 146 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
98 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 147 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
99 | 148 | ||
100 | return sprintf(buf, "%d\n", nd->sensor_physical_width); | 149 | return sprintf(buf, "%d\n", nd->sensor_physical_width); |
101 | } | 150 | } |
102 | 151 | ||
103 | static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); | 152 | static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); |
104 | 153 | ||
105 | static ssize_t show_phys_height(struct device *dev, | 154 | static ssize_t show_phys_height(struct device *dev, |
106 | struct device_attribute *attr, | 155 | struct device_attribute *attr, |
107 | char *buf) | 156 | char *buf) |
108 | { | 157 | { |
109 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 158 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
110 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 159 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
111 | 160 | ||
112 | return sprintf(buf, "%d\n", nd->sensor_physical_height); | 161 | return sprintf(buf, "%d\n", nd->sensor_physical_height); |
113 | } | 162 | } |
114 | 163 | ||
115 | static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); | 164 | static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); |
116 | 165 | ||
117 | static ssize_t show_log_width(struct device *dev, | 166 | static ssize_t show_log_width(struct device *dev, |
118 | struct device_attribute *attr, | 167 | struct device_attribute *attr, |
119 | char *buf) | 168 | char *buf) |
120 | { | 169 | { |
121 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 170 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
122 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 171 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
123 | 172 | ||
124 | return sprintf(buf, "%d\n", nd->sensor_logical_width); | 173 | return sprintf(buf, "%d\n", nd->sensor_logical_width); |
125 | } | 174 | } |
126 | 175 | ||
127 | static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); | 176 | static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); |
128 | 177 | ||
129 | static ssize_t show_log_height(struct device *dev, | 178 | static ssize_t show_log_height(struct device *dev, |
130 | struct device_attribute *attr, | 179 | struct device_attribute *attr, |
131 | char *buf) | 180 | char *buf) |
132 | { | 181 | { |
133 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 182 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
134 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 183 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
135 | 184 | ||
136 | return sprintf(buf, "%d\n", nd->sensor_logical_height); | 185 | return sprintf(buf, "%d\n", nd->sensor_logical_height); |
137 | } | 186 | } |
138 | 187 | ||
139 | static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); | 188 | static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); |
140 | 189 | ||
141 | static ssize_t show_min_width(struct device *dev, | 190 | static ssize_t show_min_width(struct device *dev, |
142 | struct device_attribute *attr, | 191 | struct device_attribute *attr, |
143 | char *buf) | 192 | char *buf) |
144 | { | 193 | { |
145 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 194 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
146 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 195 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
147 | 196 | ||
148 | return sprintf(buf, "%d\n", nd->min_width * | 197 | return sprintf(buf, "%d\n", nd->min_width * |
149 | nd->sensor_physical_width / | 198 | nd->sensor_physical_width / |
150 | nd->sensor_logical_width); | 199 | nd->sensor_logical_width); |
151 | } | 200 | } |
152 | 201 | ||
153 | static ssize_t set_min_width(struct device *dev, | 202 | static ssize_t set_min_width(struct device *dev, |
154 | struct device_attribute *attr, | 203 | struct device_attribute *attr, |
155 | const char *buf, size_t count) | 204 | const char *buf, size_t count) |
156 | { | 205 | { |
157 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 206 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
158 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 207 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
159 | 208 | ||
160 | unsigned long val; | 209 | unsigned long val; |
161 | 210 | ||
162 | if (strict_strtoul(buf, 0, &val)) | 211 | if (strict_strtoul(buf, 0, &val)) |
163 | return -EINVAL; | 212 | return -EINVAL; |
164 | 213 | ||
165 | if (val > nd->sensor_physical_width) | 214 | if (val > nd->sensor_physical_width) |
166 | return -EINVAL; | 215 | return -EINVAL; |
167 | 216 | ||
168 | nd->min_width = val * nd->sensor_logical_width / | 217 | nd->min_width = val * nd->sensor_logical_width / |
169 | nd->sensor_physical_width; | 218 | nd->sensor_physical_width; |
170 | 219 | ||
171 | return count; | 220 | return count; |
172 | } | 221 | } |
173 | 222 | ||
174 | static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); | 223 | static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); |
175 | 224 | ||
176 | static ssize_t show_min_height(struct device *dev, | 225 | static ssize_t show_min_height(struct device *dev, |
177 | struct device_attribute *attr, | 226 | struct device_attribute *attr, |
178 | char *buf) | 227 | char *buf) |
179 | { | 228 | { |
180 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 229 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
181 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 230 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
182 | 231 | ||
183 | return sprintf(buf, "%d\n", nd->min_height * | 232 | return sprintf(buf, "%d\n", nd->min_height * |
184 | nd->sensor_physical_height / | 233 | nd->sensor_physical_height / |
185 | nd->sensor_logical_height); | 234 | nd->sensor_logical_height); |
186 | } | 235 | } |
187 | 236 | ||
188 | static ssize_t set_min_height(struct device *dev, | 237 | static ssize_t set_min_height(struct device *dev, |
189 | struct device_attribute *attr, | 238 | struct device_attribute *attr, |
190 | const char *buf, size_t count) | 239 | const char *buf, size_t count) |
191 | { | 240 | { |
192 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 241 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
193 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 242 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
194 | 243 | ||
195 | unsigned long val; | 244 | unsigned long val; |
196 | 245 | ||
197 | if (strict_strtoul(buf, 0, &val)) | 246 | if (strict_strtoul(buf, 0, &val)) |
198 | return -EINVAL; | 247 | return -EINVAL; |
199 | 248 | ||
200 | if (val > nd->sensor_physical_height) | 249 | if (val > nd->sensor_physical_height) |
201 | return -EINVAL; | 250 | return -EINVAL; |
202 | 251 | ||
203 | nd->min_height = val * nd->sensor_logical_height / | 252 | nd->min_height = val * nd->sensor_logical_height / |
204 | nd->sensor_physical_height; | 253 | nd->sensor_physical_height; |
205 | 254 | ||
206 | return count; | 255 | return count; |
207 | } | 256 | } |
208 | 257 | ||
209 | static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, | 258 | static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, |
210 | set_min_height); | 259 | set_min_height); |
211 | 260 | ||
212 | static ssize_t show_activate_slack(struct device *dev, | 261 | static ssize_t show_activate_slack(struct device *dev, |
213 | struct device_attribute *attr, | 262 | struct device_attribute *attr, |
214 | char *buf) | 263 | char *buf) |
215 | { | 264 | { |
216 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 265 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
217 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 266 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
218 | 267 | ||
219 | return sprintf(buf, "%d\n", nd->activate_slack); | 268 | return sprintf(buf, "%d\n", nd->activate_slack); |
220 | } | 269 | } |
221 | 270 | ||
222 | static ssize_t set_activate_slack(struct device *dev, | 271 | static ssize_t set_activate_slack(struct device *dev, |
223 | struct device_attribute *attr, | 272 | struct device_attribute *attr, |
224 | const char *buf, size_t count) | 273 | const char *buf, size_t count) |
225 | { | 274 | { |
226 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 275 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
227 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 276 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
228 | 277 | ||
229 | unsigned long val; | 278 | unsigned long val; |
230 | 279 | ||
231 | if (strict_strtoul(buf, 0, &val)) | 280 | if (strict_strtoul(buf, 0, &val)) |
232 | return -EINVAL; | 281 | return -EINVAL; |
233 | 282 | ||
234 | if (val > 0x7f) | 283 | if (val > 0x7f) |
235 | return -EINVAL; | 284 | return -EINVAL; |
236 | 285 | ||
237 | nd->activate_slack = val; | 286 | nd->activate_slack = val; |
238 | 287 | ||
239 | return count; | 288 | return count; |
240 | } | 289 | } |
241 | 290 | ||
242 | static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, | 291 | static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, |
243 | set_activate_slack); | 292 | set_activate_slack); |
244 | 293 | ||
245 | static ssize_t show_activation_width(struct device *dev, | 294 | static ssize_t show_activation_width(struct device *dev, |
246 | struct device_attribute *attr, | 295 | struct device_attribute *attr, |
247 | char *buf) | 296 | char *buf) |
248 | { | 297 | { |
249 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 298 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
250 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 299 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
251 | 300 | ||
252 | return sprintf(buf, "%d\n", nd->activation_width * | 301 | return sprintf(buf, "%d\n", nd->activation_width * |
253 | nd->sensor_physical_width / | 302 | nd->sensor_physical_width / |
254 | nd->sensor_logical_width); | 303 | nd->sensor_logical_width); |
255 | } | 304 | } |
256 | 305 | ||
257 | static ssize_t set_activation_width(struct device *dev, | 306 | static ssize_t set_activation_width(struct device *dev, |
258 | struct device_attribute *attr, | 307 | struct device_attribute *attr, |
259 | const char *buf, size_t count) | 308 | const char *buf, size_t count) |
260 | { | 309 | { |
261 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 310 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
262 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 311 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
263 | 312 | ||
264 | unsigned long val; | 313 | unsigned long val; |
265 | 314 | ||
266 | if (strict_strtoul(buf, 0, &val)) | 315 | if (strict_strtoul(buf, 0, &val)) |
267 | return -EINVAL; | 316 | return -EINVAL; |
268 | 317 | ||
269 | if (val > nd->sensor_physical_width) | 318 | if (val > nd->sensor_physical_width) |
270 | return -EINVAL; | 319 | return -EINVAL; |
271 | 320 | ||
272 | nd->activation_width = val * nd->sensor_logical_width / | 321 | nd->activation_width = val * nd->sensor_logical_width / |
273 | nd->sensor_physical_width; | 322 | nd->sensor_physical_width; |
274 | 323 | ||
275 | return count; | 324 | return count; |
276 | } | 325 | } |
277 | 326 | ||
278 | static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, | 327 | static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, |
279 | set_activation_width); | 328 | set_activation_width); |
280 | 329 | ||
281 | static ssize_t show_activation_height(struct device *dev, | 330 | static ssize_t show_activation_height(struct device *dev, |
282 | struct device_attribute *attr, | 331 | struct device_attribute *attr, |
283 | char *buf) | 332 | char *buf) |
284 | { | 333 | { |
285 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 334 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
286 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 335 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
287 | 336 | ||
288 | return sprintf(buf, "%d\n", nd->activation_height * | 337 | return sprintf(buf, "%d\n", nd->activation_height * |
289 | nd->sensor_physical_height / | 338 | nd->sensor_physical_height / |
290 | nd->sensor_logical_height); | 339 | nd->sensor_logical_height); |
291 | } | 340 | } |
292 | 341 | ||
293 | static ssize_t set_activation_height(struct device *dev, | 342 | static ssize_t set_activation_height(struct device *dev, |
294 | struct device_attribute *attr, | 343 | struct device_attribute *attr, |
295 | const char *buf, size_t count) | 344 | const char *buf, size_t count) |
296 | { | 345 | { |
297 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 346 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
298 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 347 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
299 | 348 | ||
300 | unsigned long val; | 349 | unsigned long val; |
301 | 350 | ||
302 | if (strict_strtoul(buf, 0, &val)) | 351 | if (strict_strtoul(buf, 0, &val)) |
303 | return -EINVAL; | 352 | return -EINVAL; |
304 | 353 | ||
305 | if (val > nd->sensor_physical_height) | 354 | if (val > nd->sensor_physical_height) |
306 | return -EINVAL; | 355 | return -EINVAL; |
307 | 356 | ||
308 | nd->activation_height = val * nd->sensor_logical_height / | 357 | nd->activation_height = val * nd->sensor_logical_height / |
309 | nd->sensor_physical_height; | 358 | nd->sensor_physical_height; |
310 | 359 | ||
311 | return count; | 360 | return count; |
312 | } | 361 | } |
313 | 362 | ||
314 | static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, | 363 | static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, |
315 | show_activation_height, set_activation_height); | 364 | show_activation_height, set_activation_height); |
316 | 365 | ||
317 | static ssize_t show_deactivate_slack(struct device *dev, | 366 | static ssize_t show_deactivate_slack(struct device *dev, |
318 | struct device_attribute *attr, | 367 | struct device_attribute *attr, |
319 | char *buf) | 368 | char *buf) |
320 | { | 369 | { |
321 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 370 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
322 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 371 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
323 | 372 | ||
324 | return sprintf(buf, "%d\n", -nd->deactivate_slack); | 373 | return sprintf(buf, "%d\n", -nd->deactivate_slack); |
325 | } | 374 | } |
326 | 375 | ||
327 | static ssize_t set_deactivate_slack(struct device *dev, | 376 | static ssize_t set_deactivate_slack(struct device *dev, |
328 | struct device_attribute *attr, | 377 | struct device_attribute *attr, |
329 | const char *buf, size_t count) | 378 | const char *buf, size_t count) |
330 | { | 379 | { |
331 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 380 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
332 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 381 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
333 | 382 | ||
334 | unsigned long val; | 383 | unsigned long val; |
335 | 384 | ||
336 | if (strict_strtoul(buf, 0, &val)) | 385 | if (strict_strtoul(buf, 0, &val)) |
337 | return -EINVAL; | 386 | return -EINVAL; |
338 | 387 | ||
339 | /* | 388 | /* |
340 | * No more than 8 terminal frames have been observed so far | 389 | * No more than 8 terminal frames have been observed so far |
341 | * and higher slack is highly likely to leave the single | 390 | * and higher slack is highly likely to leave the single |
342 | * touch emulation stuck down. | 391 | * touch emulation stuck down. |
343 | */ | 392 | */ |
344 | if (val > 7) | 393 | if (val > 7) |
345 | return -EINVAL; | 394 | return -EINVAL; |
346 | 395 | ||
347 | nd->deactivate_slack = -val; | 396 | nd->deactivate_slack = -val; |
348 | 397 | ||
349 | return count; | 398 | return count; |
350 | } | 399 | } |
351 | 400 | ||
352 | static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, | 401 | static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, |
353 | set_deactivate_slack); | 402 | set_deactivate_slack); |
354 | 403 | ||
355 | static struct attribute *sysfs_attrs[] = { | 404 | static struct attribute *sysfs_attrs[] = { |
356 | &dev_attr_sensor_physical_width.attr, | 405 | &dev_attr_sensor_physical_width.attr, |
357 | &dev_attr_sensor_physical_height.attr, | 406 | &dev_attr_sensor_physical_height.attr, |
358 | &dev_attr_sensor_logical_width.attr, | 407 | &dev_attr_sensor_logical_width.attr, |
359 | &dev_attr_sensor_logical_height.attr, | 408 | &dev_attr_sensor_logical_height.attr, |
360 | &dev_attr_min_height.attr, | 409 | &dev_attr_min_height.attr, |
361 | &dev_attr_min_width.attr, | 410 | &dev_attr_min_width.attr, |
362 | &dev_attr_activate_slack.attr, | 411 | &dev_attr_activate_slack.attr, |
363 | &dev_attr_activation_width.attr, | 412 | &dev_attr_activation_width.attr, |
364 | &dev_attr_activation_height.attr, | 413 | &dev_attr_activation_height.attr, |
365 | &dev_attr_deactivate_slack.attr, | 414 | &dev_attr_deactivate_slack.attr, |
366 | NULL | 415 | NULL |
367 | }; | 416 | }; |
368 | 417 | ||
369 | static struct attribute_group ntrig_attribute_group = { | 418 | static struct attribute_group ntrig_attribute_group = { |
370 | .attrs = sysfs_attrs | 419 | .attrs = sysfs_attrs |
371 | }; | 420 | }; |
372 | 421 | ||
373 | /* | 422 | /* |
374 | * this driver is aimed at two firmware versions in circulation: | 423 | * this driver is aimed at two firmware versions in circulation: |
375 | * - dual pen/finger single touch | 424 | * - dual pen/finger single touch |
376 | * - finger multitouch, pen not working | 425 | * - finger multitouch, pen not working |
377 | */ | 426 | */ |
378 | 427 | ||
379 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 428 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
380 | struct hid_field *field, struct hid_usage *usage, | 429 | struct hid_field *field, struct hid_usage *usage, |
381 | unsigned long **bit, int *max) | 430 | unsigned long **bit, int *max) |
382 | { | 431 | { |
383 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 432 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
384 | 433 | ||
385 | /* No special mappings needed for the pen and single touch */ | 434 | /* No special mappings needed for the pen and single touch */ |
386 | if (field->physical) | 435 | if (field->physical) |
387 | return 0; | 436 | return 0; |
388 | 437 | ||
389 | switch (usage->hid & HID_USAGE_PAGE) { | 438 | switch (usage->hid & HID_USAGE_PAGE) { |
390 | case HID_UP_GENDESK: | 439 | case HID_UP_GENDESK: |
391 | switch (usage->hid) { | 440 | switch (usage->hid) { |
392 | case HID_GD_X: | 441 | case HID_GD_X: |
393 | hid_map_usage(hi, usage, bit, max, | 442 | hid_map_usage(hi, usage, bit, max, |
394 | EV_ABS, ABS_MT_POSITION_X); | 443 | EV_ABS, ABS_MT_POSITION_X); |
395 | input_set_abs_params(hi->input, ABS_X, | 444 | input_set_abs_params(hi->input, ABS_X, |
396 | field->logical_minimum, | 445 | field->logical_minimum, |
397 | field->logical_maximum, 0, 0); | 446 | field->logical_maximum, 0, 0); |
398 | 447 | ||
399 | if (!nd->sensor_logical_width) { | 448 | if (!nd->sensor_logical_width) { |
400 | nd->sensor_logical_width = | 449 | nd->sensor_logical_width = |
401 | field->logical_maximum - | 450 | field->logical_maximum - |
402 | field->logical_minimum; | 451 | field->logical_minimum; |
403 | nd->sensor_physical_width = | 452 | nd->sensor_physical_width = |
404 | field->physical_maximum - | 453 | field->physical_maximum - |
405 | field->physical_minimum; | 454 | field->physical_minimum; |
406 | nd->activation_width = activation_width * | 455 | nd->activation_width = activation_width * |
407 | nd->sensor_logical_width / | 456 | nd->sensor_logical_width / |
408 | nd->sensor_physical_width; | 457 | nd->sensor_physical_width; |
409 | nd->min_width = min_width * | 458 | nd->min_width = min_width * |
410 | nd->sensor_logical_width / | 459 | nd->sensor_logical_width / |
411 | nd->sensor_physical_width; | 460 | nd->sensor_physical_width; |
412 | } | 461 | } |
413 | return 1; | 462 | return 1; |
414 | case HID_GD_Y: | 463 | case HID_GD_Y: |
415 | hid_map_usage(hi, usage, bit, max, | 464 | hid_map_usage(hi, usage, bit, max, |
416 | EV_ABS, ABS_MT_POSITION_Y); | 465 | EV_ABS, ABS_MT_POSITION_Y); |
417 | input_set_abs_params(hi->input, ABS_Y, | 466 | input_set_abs_params(hi->input, ABS_Y, |
418 | field->logical_minimum, | 467 | field->logical_minimum, |
419 | field->logical_maximum, 0, 0); | 468 | field->logical_maximum, 0, 0); |
420 | 469 | ||
421 | if (!nd->sensor_logical_height) { | 470 | if (!nd->sensor_logical_height) { |
422 | nd->sensor_logical_height = | 471 | nd->sensor_logical_height = |
423 | field->logical_maximum - | 472 | field->logical_maximum - |
424 | field->logical_minimum; | 473 | field->logical_minimum; |
425 | nd->sensor_physical_height = | 474 | nd->sensor_physical_height = |
426 | field->physical_maximum - | 475 | field->physical_maximum - |
427 | field->physical_minimum; | 476 | field->physical_minimum; |
428 | nd->activation_height = activation_height * | 477 | nd->activation_height = activation_height * |
429 | nd->sensor_logical_height / | 478 | nd->sensor_logical_height / |
430 | nd->sensor_physical_height; | 479 | nd->sensor_physical_height; |
431 | nd->min_height = min_height * | 480 | nd->min_height = min_height * |
432 | nd->sensor_logical_height / | 481 | nd->sensor_logical_height / |
433 | nd->sensor_physical_height; | 482 | nd->sensor_physical_height; |
434 | } | 483 | } |
435 | return 1; | 484 | return 1; |
436 | } | 485 | } |
437 | return 0; | 486 | return 0; |
438 | 487 | ||
439 | case HID_UP_DIGITIZER: | 488 | case HID_UP_DIGITIZER: |
440 | switch (usage->hid) { | 489 | switch (usage->hid) { |
441 | /* we do not want to map these for now */ | 490 | /* we do not want to map these for now */ |
442 | case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ | 491 | case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ |
443 | case HID_DG_INPUTMODE: | 492 | case HID_DG_INPUTMODE: |
444 | case HID_DG_DEVICEINDEX: | 493 | case HID_DG_DEVICEINDEX: |
445 | case HID_DG_CONTACTMAX: | 494 | case HID_DG_CONTACTMAX: |
446 | return -1; | 495 | return -1; |
447 | 496 | ||
448 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ | 497 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ |
449 | case HID_DG_WIDTH: | 498 | case HID_DG_WIDTH: |
450 | hid_map_usage(hi, usage, bit, max, | 499 | hid_map_usage(hi, usage, bit, max, |
451 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 500 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
452 | return 1; | 501 | return 1; |
453 | case HID_DG_HEIGHT: | 502 | case HID_DG_HEIGHT: |
454 | hid_map_usage(hi, usage, bit, max, | 503 | hid_map_usage(hi, usage, bit, max, |
455 | EV_ABS, ABS_MT_TOUCH_MINOR); | 504 | EV_ABS, ABS_MT_TOUCH_MINOR); |
456 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | 505 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, |
457 | 0, 1, 0, 0); | 506 | 0, 1, 0, 0); |
458 | return 1; | 507 | return 1; |
459 | } | 508 | } |
460 | return 0; | 509 | return 0; |
461 | 510 | ||
462 | case 0xff000000: | 511 | case 0xff000000: |
463 | /* we do not want to map these: no input-oriented meaning */ | 512 | /* we do not want to map these: no input-oriented meaning */ |
464 | return -1; | 513 | return -1; |
465 | } | 514 | } |
466 | 515 | ||
467 | return 0; | 516 | return 0; |
468 | } | 517 | } |
469 | 518 | ||
470 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 519 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
471 | struct hid_field *field, struct hid_usage *usage, | 520 | struct hid_field *field, struct hid_usage *usage, |
472 | unsigned long **bit, int *max) | 521 | unsigned long **bit, int *max) |
473 | { | 522 | { |
474 | /* No special mappings needed for the pen and single touch */ | 523 | /* No special mappings needed for the pen and single touch */ |
475 | if (field->physical) | 524 | if (field->physical) |
476 | return 0; | 525 | return 0; |
477 | 526 | ||
478 | if (usage->type == EV_KEY || usage->type == EV_REL | 527 | if (usage->type == EV_KEY || usage->type == EV_REL |
479 | || usage->type == EV_ABS) | 528 | || usage->type == EV_ABS) |
480 | clear_bit(usage->code, *bit); | 529 | clear_bit(usage->code, *bit); |
481 | 530 | ||
482 | return 0; | 531 | return 0; |
483 | } | 532 | } |
484 | 533 | ||
485 | /* | 534 | /* |
486 | * this function is called upon all reports | 535 | * this function is called upon all reports |
487 | * so that we can filter contact point information, | 536 | * so that we can filter contact point information, |
488 | * decide whether we are in multi or single touch mode | 537 | * decide whether we are in multi or single touch mode |
489 | * and call input_mt_sync after each point if necessary | 538 | * and call input_mt_sync after each point if necessary |
490 | */ | 539 | */ |
491 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, | 540 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, |
492 | struct hid_usage *usage, __s32 value) | 541 | struct hid_usage *usage, __s32 value) |
493 | { | 542 | { |
494 | struct input_dev *input = field->hidinput->input; | 543 | struct input_dev *input = field->hidinput->input; |
495 | struct ntrig_data *nd = hid_get_drvdata(hid); | 544 | struct ntrig_data *nd = hid_get_drvdata(hid); |
496 | 545 | ||
497 | /* No special handling needed for the pen */ | 546 | /* No special handling needed for the pen */ |
498 | if (field->application == HID_DG_PEN) | 547 | if (field->application == HID_DG_PEN) |
499 | return 0; | 548 | return 0; |
500 | 549 | ||
501 | if (hid->claimed & HID_CLAIMED_INPUT) { | 550 | if (hid->claimed & HID_CLAIMED_INPUT) { |
502 | switch (usage->hid) { | 551 | switch (usage->hid) { |
503 | case 0xff000001: | 552 | case 0xff000001: |
504 | /* Tag indicating the start of a multitouch group */ | 553 | /* Tag indicating the start of a multitouch group */ |
505 | nd->reading_mt = 1; | 554 | nd->reading_mt = 1; |
506 | nd->first_contact_touch = 0; | 555 | nd->first_contact_touch = 0; |
507 | break; | 556 | break; |
508 | case HID_DG_TIPSWITCH: | 557 | case HID_DG_TIPSWITCH: |
509 | nd->tipswitch = value; | 558 | nd->tipswitch = value; |
510 | /* Prevent emission of touch until validated */ | 559 | /* Prevent emission of touch until validated */ |
511 | return 1; | 560 | return 1; |
512 | case HID_DG_CONFIDENCE: | 561 | case HID_DG_CONFIDENCE: |
513 | nd->confidence = value; | 562 | nd->confidence = value; |
514 | break; | 563 | break; |
515 | case HID_GD_X: | 564 | case HID_GD_X: |
516 | nd->x = value; | 565 | nd->x = value; |
517 | /* Clear the contact footer */ | 566 | /* Clear the contact footer */ |
518 | nd->mt_foot_count = 0; | 567 | nd->mt_foot_count = 0; |
519 | break; | 568 | break; |
520 | case HID_GD_Y: | 569 | case HID_GD_Y: |
521 | nd->y = value; | 570 | nd->y = value; |
522 | break; | 571 | break; |
523 | case HID_DG_CONTACTID: | 572 | case HID_DG_CONTACTID: |
524 | nd->id = value; | 573 | nd->id = value; |
525 | break; | 574 | break; |
526 | case HID_DG_WIDTH: | 575 | case HID_DG_WIDTH: |
527 | nd->w = value; | 576 | nd->w = value; |
528 | break; | 577 | break; |
529 | case HID_DG_HEIGHT: | 578 | case HID_DG_HEIGHT: |
530 | nd->h = value; | 579 | nd->h = value; |
531 | /* | 580 | /* |
532 | * when in single touch mode, this is the last | 581 | * when in single touch mode, this is the last |
533 | * report received in a finger event. We want | 582 | * report received in a finger event. We want |
534 | * to emit a normal (X, Y) position | 583 | * to emit a normal (X, Y) position |
535 | */ | 584 | */ |
536 | if (!nd->reading_mt) { | 585 | if (!nd->reading_mt) { |
537 | /* | 586 | /* |
538 | * TipSwitch indicates the presence of a | 587 | * TipSwitch indicates the presence of a |
539 | * finger in single touch mode. | 588 | * finger in single touch mode. |
540 | */ | 589 | */ |
541 | input_report_key(input, BTN_TOUCH, | 590 | input_report_key(input, BTN_TOUCH, |
542 | nd->tipswitch); | 591 | nd->tipswitch); |
543 | input_report_key(input, BTN_TOOL_DOUBLETAP, | 592 | input_report_key(input, BTN_TOOL_DOUBLETAP, |
544 | nd->tipswitch); | 593 | nd->tipswitch); |
545 | input_event(input, EV_ABS, ABS_X, nd->x); | 594 | input_event(input, EV_ABS, ABS_X, nd->x); |
546 | input_event(input, EV_ABS, ABS_Y, nd->y); | 595 | input_event(input, EV_ABS, ABS_Y, nd->y); |
547 | } | 596 | } |
548 | break; | 597 | break; |
549 | case 0xff000002: | 598 | case 0xff000002: |
550 | /* | 599 | /* |
551 | * we receive this when the device is in multitouch | 600 | * we receive this when the device is in multitouch |
552 | * mode. The first of the three values tagged with | 601 | * mode. The first of the three values tagged with |
553 | * this usage tells if the contact point is real | 602 | * this usage tells if the contact point is real |
554 | * or a placeholder | 603 | * or a placeholder |
555 | */ | 604 | */ |
556 | 605 | ||
557 | /* Shouldn't get more than 4 footer packets, so skip */ | 606 | /* Shouldn't get more than 4 footer packets, so skip */ |
558 | if (nd->mt_foot_count >= 4) | 607 | if (nd->mt_foot_count >= 4) |
559 | break; | 608 | break; |
560 | 609 | ||
561 | nd->mt_footer[nd->mt_foot_count++] = value; | 610 | nd->mt_footer[nd->mt_foot_count++] = value; |
562 | 611 | ||
563 | /* if the footer isn't complete break */ | 612 | /* if the footer isn't complete break */ |
564 | if (nd->mt_foot_count != 4) | 613 | if (nd->mt_foot_count != 4) |
565 | break; | 614 | break; |
566 | 615 | ||
567 | /* Pen activity signal. */ | 616 | /* Pen activity signal. */ |
568 | if (nd->mt_footer[2]) { | 617 | if (nd->mt_footer[2]) { |
569 | /* | 618 | /* |
570 | * When the pen deactivates touch, we see a | 619 | * When the pen deactivates touch, we see a |
571 | * bogus frame with ContactCount > 0. | 620 | * bogus frame with ContactCount > 0. |
572 | * We can | 621 | * We can |
573 | * save a bit of work by ensuring act_state < 0 | 622 | * save a bit of work by ensuring act_state < 0 |
574 | * even if deactivation slack is turned off. | 623 | * even if deactivation slack is turned off. |
575 | */ | 624 | */ |
576 | nd->act_state = deactivate_slack - 1; | 625 | nd->act_state = deactivate_slack - 1; |
577 | nd->confidence = 0; | 626 | nd->confidence = 0; |
578 | break; | 627 | break; |
579 | } | 628 | } |
580 | 629 | ||
581 | /* | 630 | /* |
582 | * The first footer value indicates the presence of a | 631 | * The first footer value indicates the presence of a |
583 | * finger. | 632 | * finger. |
584 | */ | 633 | */ |
585 | if (nd->mt_footer[0]) { | 634 | if (nd->mt_footer[0]) { |
586 | /* | 635 | /* |
587 | * We do not want to process contacts under | 636 | * We do not want to process contacts under |
588 | * the size threshold, but do not want to | 637 | * the size threshold, but do not want to |
589 | * ignore them for activation state | 638 | * ignore them for activation state |
590 | */ | 639 | */ |
591 | if (nd->w < nd->min_width || | 640 | if (nd->w < nd->min_width || |
592 | nd->h < nd->min_height) | 641 | nd->h < nd->min_height) |
593 | nd->confidence = 0; | 642 | nd->confidence = 0; |
594 | } else | 643 | } else |
595 | break; | 644 | break; |
596 | 645 | ||
597 | if (nd->act_state > 0) { | 646 | if (nd->act_state > 0) { |
598 | /* | 647 | /* |
599 | * Contact meets the activation size threshold | 648 | * Contact meets the activation size threshold |
600 | */ | 649 | */ |
601 | if (nd->w >= nd->activation_width && | 650 | if (nd->w >= nd->activation_width && |
602 | nd->h >= nd->activation_height) { | 651 | nd->h >= nd->activation_height) { |
603 | if (nd->id) | 652 | if (nd->id) |
604 | /* | 653 | /* |
605 | * first contact, activate now | 654 | * first contact, activate now |
606 | */ | 655 | */ |
607 | nd->act_state = 0; | 656 | nd->act_state = 0; |
608 | else { | 657 | else { |
609 | /* | 658 | /* |
610 | * avoid corrupting this frame | 659 | * avoid corrupting this frame |
611 | * but ensure next frame will | 660 | * but ensure next frame will |
612 | * be active | 661 | * be active |
613 | */ | 662 | */ |
614 | nd->act_state = 1; | 663 | nd->act_state = 1; |
615 | break; | 664 | break; |
616 | } | 665 | } |
617 | } else | 666 | } else |
618 | /* | 667 | /* |
619 | * Defer adjusting the activation state | 668 | * Defer adjusting the activation state |
620 | * until the end of the frame. | 669 | * until the end of the frame. |
621 | */ | 670 | */ |
622 | break; | 671 | break; |
623 | } | 672 | } |
624 | 673 | ||
625 | /* Discarding this contact */ | 674 | /* Discarding this contact */ |
626 | if (!nd->confidence) | 675 | if (!nd->confidence) |
627 | break; | 676 | break; |
628 | 677 | ||
629 | /* emit a normal (X, Y) for the first point only */ | 678 | /* emit a normal (X, Y) for the first point only */ |
630 | if (nd->id == 0) { | 679 | if (nd->id == 0) { |
631 | /* | 680 | /* |
632 | * TipSwitch is superfluous in multitouch | 681 | * TipSwitch is superfluous in multitouch |
633 | * mode. The footer events tell us | 682 | * mode. The footer events tell us |
634 | * if there is a finger on the screen or | 683 | * if there is a finger on the screen or |
635 | * not. | 684 | * not. |
636 | */ | 685 | */ |
637 | nd->first_contact_touch = nd->confidence; | 686 | nd->first_contact_touch = nd->confidence; |
638 | input_event(input, EV_ABS, ABS_X, nd->x); | 687 | input_event(input, EV_ABS, ABS_X, nd->x); |
639 | input_event(input, EV_ABS, ABS_Y, nd->y); | 688 | input_event(input, EV_ABS, ABS_Y, nd->y); |
640 | } | 689 | } |
641 | 690 | ||
642 | /* Emit MT events */ | 691 | /* Emit MT events */ |
643 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); | 692 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); |
644 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); | 693 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); |
645 | 694 | ||
646 | /* | 695 | /* |
647 | * Translate from height and width to size | 696 | * Translate from height and width to size |
648 | * and orientation. | 697 | * and orientation. |
649 | */ | 698 | */ |
650 | if (nd->w > nd->h) { | 699 | if (nd->w > nd->h) { |
651 | input_event(input, EV_ABS, | 700 | input_event(input, EV_ABS, |
652 | ABS_MT_ORIENTATION, 1); | 701 | ABS_MT_ORIENTATION, 1); |
653 | input_event(input, EV_ABS, | 702 | input_event(input, EV_ABS, |
654 | ABS_MT_TOUCH_MAJOR, nd->w); | 703 | ABS_MT_TOUCH_MAJOR, nd->w); |
655 | input_event(input, EV_ABS, | 704 | input_event(input, EV_ABS, |
656 | ABS_MT_TOUCH_MINOR, nd->h); | 705 | ABS_MT_TOUCH_MINOR, nd->h); |
657 | } else { | 706 | } else { |
658 | input_event(input, EV_ABS, | 707 | input_event(input, EV_ABS, |
659 | ABS_MT_ORIENTATION, 0); | 708 | ABS_MT_ORIENTATION, 0); |
660 | input_event(input, EV_ABS, | 709 | input_event(input, EV_ABS, |
661 | ABS_MT_TOUCH_MAJOR, nd->h); | 710 | ABS_MT_TOUCH_MAJOR, nd->h); |
662 | input_event(input, EV_ABS, | 711 | input_event(input, EV_ABS, |
663 | ABS_MT_TOUCH_MINOR, nd->w); | 712 | ABS_MT_TOUCH_MINOR, nd->w); |
664 | } | 713 | } |
665 | input_mt_sync(field->hidinput->input); | 714 | input_mt_sync(field->hidinput->input); |
666 | break; | 715 | break; |
667 | 716 | ||
668 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ | 717 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ |
669 | if (!nd->reading_mt) /* Just to be sure */ | 718 | if (!nd->reading_mt) /* Just to be sure */ |
670 | break; | 719 | break; |
671 | 720 | ||
672 | nd->reading_mt = 0; | 721 | nd->reading_mt = 0; |
673 | 722 | ||
674 | 723 | ||
675 | /* | 724 | /* |
676 | * Activation state machine logic: | 725 | * Activation state machine logic: |
677 | * | 726 | * |
678 | * Fundamental states: | 727 | * Fundamental states: |
679 | * state > 0: Inactive | 728 | * state > 0: Inactive |
680 | * state <= 0: Active | 729 | * state <= 0: Active |
681 | * state < -deactivate_slack: | 730 | * state < -deactivate_slack: |
682 | * Pen termination of touch | 731 | * Pen termination of touch |
683 | * | 732 | * |
684 | * Specific values of interest | 733 | * Specific values of interest |
685 | * state == activate_slack | 734 | * state == activate_slack |
686 | * no valid input since the last reset | 735 | * no valid input since the last reset |
687 | * | 736 | * |
688 | * state == 0 | 737 | * state == 0 |
689 | * general operational state | 738 | * general operational state |
690 | * | 739 | * |
691 | * state == -deactivate_slack | 740 | * state == -deactivate_slack |
692 | * read sufficient empty frames to accept | 741 | * read sufficient empty frames to accept |
693 | * the end of input and reset | 742 | * the end of input and reset |
694 | */ | 743 | */ |
695 | 744 | ||
696 | if (nd->act_state > 0) { /* Currently inactive */ | 745 | if (nd->act_state > 0) { /* Currently inactive */ |
697 | if (value) | 746 | if (value) |
698 | /* | 747 | /* |
699 | * Consider each live contact as | 748 | * Consider each live contact as |
700 | * evidence of intentional activity. | 749 | * evidence of intentional activity. |
701 | */ | 750 | */ |
702 | nd->act_state = (nd->act_state > value) | 751 | nd->act_state = (nd->act_state > value) |
703 | ? nd->act_state - value | 752 | ? nd->act_state - value |
704 | : 0; | 753 | : 0; |
705 | else | 754 | else |
706 | /* | 755 | /* |
707 | * Empty frame before we hit the | 756 | * Empty frame before we hit the |
708 | * activity threshold, reset. | 757 | * activity threshold, reset. |
709 | */ | 758 | */ |
710 | nd->act_state = nd->activate_slack; | 759 | nd->act_state = nd->activate_slack; |
711 | 760 | ||
712 | /* | 761 | /* |
713 | * Entered this block inactive and no | 762 | * Entered this block inactive and no |
714 | * coordinates sent this frame, so hold off | 763 | * coordinates sent this frame, so hold off |
715 | * on button state. | 764 | * on button state. |
716 | */ | 765 | */ |
717 | break; | 766 | break; |
718 | } else { /* Currently active */ | 767 | } else { /* Currently active */ |
719 | if (value && nd->act_state >= | 768 | if (value && nd->act_state >= |
720 | nd->deactivate_slack) | 769 | nd->deactivate_slack) |
721 | /* | 770 | /* |
722 | * Live point: clear accumulated | 771 | * Live point: clear accumulated |
723 | * deactivation count. | 772 | * deactivation count. |
724 | */ | 773 | */ |
725 | nd->act_state = 0; | 774 | nd->act_state = 0; |
726 | else if (nd->act_state <= nd->deactivate_slack) | 775 | else if (nd->act_state <= nd->deactivate_slack) |
727 | /* | 776 | /* |
728 | * We've consumed the deactivation | 777 | * We've consumed the deactivation |
729 | * slack, time to deactivate and reset. | 778 | * slack, time to deactivate and reset. |
730 | */ | 779 | */ |
731 | nd->act_state = | 780 | nd->act_state = |
732 | nd->activate_slack; | 781 | nd->activate_slack; |
733 | else { /* Move towards deactivation */ | 782 | else { /* Move towards deactivation */ |
734 | nd->act_state--; | 783 | nd->act_state--; |
735 | break; | 784 | break; |
736 | } | 785 | } |
737 | } | 786 | } |
738 | 787 | ||
739 | if (nd->first_contact_touch && nd->act_state <= 0) { | 788 | if (nd->first_contact_touch && nd->act_state <= 0) { |
740 | /* | 789 | /* |
741 | * Check to see if we're ready to start | 790 | * Check to see if we're ready to start |
742 | * emitting touch events. | 791 | * emitting touch events. |
743 | * | 792 | * |
744 | * Note: activation slack will decrease over | 793 | * Note: activation slack will decrease over |
745 | * the course of the frame, and it will be | 794 | * the course of the frame, and it will be |
746 | * inconsistent from the start to the end of | 795 | * inconsistent from the start to the end of |
747 | * the frame. However if the frame starts | 796 | * the frame. However if the frame starts |
748 | * with slack, first_contact_touch will still | 797 | * with slack, first_contact_touch will still |
749 | * be 0 and we will not get to this point. | 798 | * be 0 and we will not get to this point. |
750 | */ | 799 | */ |
751 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); | 800 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); |
752 | input_report_key(input, BTN_TOUCH, 1); | 801 | input_report_key(input, BTN_TOUCH, 1); |
753 | } else { | 802 | } else { |
754 | input_report_key(input, BTN_TOOL_DOUBLETAP, 0); | 803 | input_report_key(input, BTN_TOOL_DOUBLETAP, 0); |
755 | input_report_key(input, BTN_TOUCH, 0); | 804 | input_report_key(input, BTN_TOUCH, 0); |
756 | } | 805 | } |
757 | break; | 806 | break; |
758 | 807 | ||
759 | default: | 808 | default: |
760 | /* fall-back to the generic hidinput handling */ | 809 | /* fall-back to the generic hidinput handling */ |
761 | return 0; | 810 | return 0; |
762 | } | 811 | } |
763 | } | 812 | } |
764 | 813 | ||
765 | /* we have handled the hidinput part, now remains hiddev */ | 814 | /* we have handled the hidinput part, now remains hiddev */ |
766 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) | 815 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) |
767 | hid->hiddev_hid_event(hid, field, usage, value); | 816 | hid->hiddev_hid_event(hid, field, usage, value); |
768 | 817 | ||
769 | return 1; | 818 | return 1; |
770 | } | 819 | } |
771 | 820 | ||
772 | static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | 821 | static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) |
773 | { | 822 | { |
774 | int ret; | 823 | int ret; |
775 | struct ntrig_data *nd; | 824 | struct ntrig_data *nd; |
776 | struct hid_input *hidinput; | 825 | struct hid_input *hidinput; |
777 | struct input_dev *input; | 826 | struct input_dev *input; |
778 | struct hid_report *report; | 827 | struct hid_report *report; |
779 | 828 | ||
780 | if (id->driver_data) | 829 | if (id->driver_data) |
781 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | 830 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; |
782 | 831 | ||
783 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); | 832 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); |
784 | if (!nd) { | 833 | if (!nd) { |
785 | dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); | 834 | dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); |
786 | return -ENOMEM; | 835 | return -ENOMEM; |
787 | } | 836 | } |
788 | 837 | ||
789 | nd->reading_mt = 0; | 838 | nd->reading_mt = 0; |
790 | nd->min_width = 0; | 839 | nd->min_width = 0; |
791 | nd->min_height = 0; | 840 | nd->min_height = 0; |
792 | nd->activate_slack = activate_slack; | 841 | nd->activate_slack = activate_slack; |
793 | nd->act_state = activate_slack; | 842 | nd->act_state = activate_slack; |
794 | nd->deactivate_slack = -deactivate_slack; | 843 | nd->deactivate_slack = -deactivate_slack; |
795 | nd->sensor_logical_width = 0; | 844 | nd->sensor_logical_width = 0; |
796 | nd->sensor_logical_height = 0; | 845 | nd->sensor_logical_height = 0; |
797 | nd->sensor_physical_width = 0; | 846 | nd->sensor_physical_width = 0; |
798 | nd->sensor_physical_height = 0; | 847 | nd->sensor_physical_height = 0; |
799 | 848 | ||
800 | hid_set_drvdata(hdev, nd); | 849 | hid_set_drvdata(hdev, nd); |
801 | 850 | ||
802 | ret = hid_parse(hdev); | 851 | ret = hid_parse(hdev); |
803 | if (ret) { | 852 | if (ret) { |
804 | dev_err(&hdev->dev, "parse failed\n"); | 853 | dev_err(&hdev->dev, "parse failed\n"); |
805 | goto err_free; | 854 | goto err_free; |
806 | } | 855 | } |
807 | 856 | ||
808 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 857 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
809 | if (ret) { | 858 | if (ret) { |
810 | dev_err(&hdev->dev, "hw start failed\n"); | 859 | dev_err(&hdev->dev, "hw start failed\n"); |
811 | goto err_free; | 860 | goto err_free; |
812 | } | 861 | } |
813 | 862 | ||
814 | 863 | ||
815 | list_for_each_entry(hidinput, &hdev->inputs, list) { | 864 | list_for_each_entry(hidinput, &hdev->inputs, list) { |
816 | if (hidinput->report->maxfield < 1) | 865 | if (hidinput->report->maxfield < 1) |
817 | continue; | 866 | continue; |
818 | 867 | ||
819 | input = hidinput->input; | 868 | input = hidinput->input; |
820 | switch (hidinput->report->field[0]->application) { | 869 | switch (hidinput->report->field[0]->application) { |
821 | case HID_DG_PEN: | 870 | case HID_DG_PEN: |
822 | input->name = "N-Trig Pen"; | 871 | input->name = "N-Trig Pen"; |
823 | break; | 872 | break; |
824 | case HID_DG_TOUCHSCREEN: | 873 | case HID_DG_TOUCHSCREEN: |
825 | /* These keys are redundant for fingers, clear them | 874 | /* These keys are redundant for fingers, clear them |
826 | * to prevent incorrect identification */ | 875 | * to prevent incorrect identification */ |
827 | __clear_bit(BTN_TOOL_PEN, input->keybit); | 876 | __clear_bit(BTN_TOOL_PEN, input->keybit); |
828 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | 877 | __clear_bit(BTN_TOOL_FINGER, input->keybit); |
829 | __clear_bit(BTN_0, input->keybit); | 878 | __clear_bit(BTN_0, input->keybit); |
830 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | 879 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); |
831 | /* | 880 | /* |
832 | * The physical touchscreen (single touch) | 881 | * The physical touchscreen (single touch) |
833 | * input has a value for physical, whereas | 882 | * input has a value for physical, whereas |
834 | * the multitouch only has logical input | 883 | * the multitouch only has logical input |
835 | * fields. | 884 | * fields. |
836 | */ | 885 | */ |
837 | input->name = | 886 | input->name = |
838 | (hidinput->report->field[0] | 887 | (hidinput->report->field[0] |
839 | ->physical) ? | 888 | ->physical) ? |
840 | "N-Trig Touchscreen" : | 889 | "N-Trig Touchscreen" : |
841 | "N-Trig MultiTouch"; | 890 | "N-Trig MultiTouch"; |
842 | break; | 891 | break; |
843 | } | 892 | } |
844 | } | 893 | } |
845 | 894 | ||
846 | /* This is needed for devices with more recent firmware versions */ | 895 | /* This is needed for devices with more recent firmware versions */ |
847 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; | 896 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; |
848 | if (report) | 897 | if (report) |
849 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 898 | usbhid_submit_report(hdev, report, USB_DIR_OUT); |
850 | 899 | ||
900 | ntrig_report_version(hdev); | ||
901 | |||
851 | ret = sysfs_create_group(&hdev->dev.kobj, | 902 | ret = sysfs_create_group(&hdev->dev.kobj, |
852 | &ntrig_attribute_group); | 903 | &ntrig_attribute_group); |
853 | 904 | ||
854 | return 0; | 905 | return 0; |
855 | err_free: | 906 | err_free: |
856 | kfree(nd); | 907 | kfree(nd); |
857 | return ret; | 908 | return ret; |
858 | } | 909 | } |
859 | 910 | ||
860 | static void ntrig_remove(struct hid_device *hdev) | 911 | static void ntrig_remove(struct hid_device *hdev) |
861 | { | 912 | { |
862 | sysfs_remove_group(&hdev->dev.kobj, | 913 | sysfs_remove_group(&hdev->dev.kobj, |
863 | &ntrig_attribute_group); | 914 | &ntrig_attribute_group); |
864 | hid_hw_stop(hdev); | 915 | hid_hw_stop(hdev); |
865 | kfree(hid_get_drvdata(hdev)); | 916 | kfree(hid_get_drvdata(hdev)); |
866 | } | 917 | } |
867 | 918 | ||
868 | static const struct hid_device_id ntrig_devices[] = { | 919 | static const struct hid_device_id ntrig_devices[] = { |
869 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), | 920 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), |
870 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 921 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
871 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1), | 922 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1), |
872 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 923 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
873 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2), | 924 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2), |
874 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 925 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
875 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3), | 926 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3), |
876 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 927 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
877 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4), | 928 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4), |
878 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 929 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
879 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5), | 930 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5), |
880 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 931 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
881 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6), | 932 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6), |
882 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 933 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
883 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7), | 934 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7), |
884 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 935 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
885 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8), | 936 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8), |
886 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 937 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
887 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9), | 938 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9), |
888 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 939 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
889 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10), | 940 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10), |
890 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 941 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
891 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11), | 942 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11), |
892 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 943 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
893 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12), | 944 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12), |
894 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 945 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
895 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13), | 946 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13), |
896 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 947 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
897 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14), | 948 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14), |
898 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 949 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
899 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15), | 950 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15), |
900 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 951 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
901 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16), | 952 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16), |
902 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 953 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
903 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17), | 954 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17), |
904 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 955 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
905 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18), | 956 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18), |
906 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 957 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
907 | { } | 958 | { } |
908 | }; | 959 | }; |
909 | MODULE_DEVICE_TABLE(hid, ntrig_devices); | 960 | MODULE_DEVICE_TABLE(hid, ntrig_devices); |
910 | 961 | ||
911 | static const struct hid_usage_id ntrig_grabbed_usages[] = { | 962 | static const struct hid_usage_id ntrig_grabbed_usages[] = { |
912 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | 963 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, |
913 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } | 964 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } |
914 | }; | 965 | }; |
915 | 966 | ||
916 | static struct hid_driver ntrig_driver = { | 967 | static struct hid_driver ntrig_driver = { |
917 | .name = "ntrig", | 968 | .name = "ntrig", |
918 | .id_table = ntrig_devices, | 969 | .id_table = ntrig_devices, |
919 | .probe = ntrig_probe, | 970 | .probe = ntrig_probe, |
920 | .remove = ntrig_remove, | 971 | .remove = ntrig_remove, |
921 | .input_mapping = ntrig_input_mapping, | 972 | .input_mapping = ntrig_input_mapping, |
922 | .input_mapped = ntrig_input_mapped, | 973 | .input_mapped = ntrig_input_mapped, |
923 | .usage_table = ntrig_grabbed_usages, | 974 | .usage_table = ntrig_grabbed_usages, |
924 | .event = ntrig_event, | 975 | .event = ntrig_event, |
925 | }; | 976 | }; |
926 | 977 | ||
927 | static int __init ntrig_init(void) | 978 | static int __init ntrig_init(void) |
928 | { | 979 | { |
929 | return hid_register_driver(&ntrig_driver); | 980 | return hid_register_driver(&ntrig_driver); |
930 | } | 981 | } |
931 | 982 | ||
932 | static void __exit ntrig_exit(void) | 983 | static void __exit ntrig_exit(void) |
933 | { | 984 | { |
934 | hid_unregister_driver(&ntrig_driver); | 985 | hid_unregister_driver(&ntrig_driver); |
935 | } | 986 | } |
936 | 987 | ||
937 | module_init(ntrig_init); | 988 | module_init(ntrig_init); |
938 | module_exit(ntrig_exit); | 989 | module_exit(ntrig_exit); |
939 | MODULE_LICENSE("GPL"); | 990 | MODULE_LICENSE("GPL"); |
940 | 991 |
drivers/hid/hid-roccat-pyra.c
File was created | 1 | /* | |
2 | * Roccat Pyra driver for Linux | ||
3 | * | ||
4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.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 | /* | ||
15 | * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless | ||
16 | * variant. Wireless variant is not tested. | ||
17 | * Userland tools can be found at http://sourceforge.net/projects/roccat | ||
18 | */ | ||
19 | |||
20 | #include <linux/device.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/hid.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include "hid-ids.h" | ||
27 | #include "hid-roccat.h" | ||
28 | #include "hid-roccat-pyra.h" | ||
29 | |||
30 | static void profile_activated(struct pyra_device *pyra, | ||
31 | unsigned int new_profile) | ||
32 | { | ||
33 | pyra->actual_profile = new_profile; | ||
34 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; | ||
35 | } | ||
36 | |||
37 | static int pyra_send_control(struct usb_device *usb_dev, int value, | ||
38 | enum pyra_control_requests request) | ||
39 | { | ||
40 | int len; | ||
41 | struct pyra_control control; | ||
42 | |||
43 | if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || | ||
44 | request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && | ||
45 | (value < 0 || value > 4)) | ||
46 | return -EINVAL; | ||
47 | |||
48 | control.command = PYRA_COMMAND_CONTROL; | ||
49 | control.value = value; | ||
50 | control.request = request; | ||
51 | |||
52 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
53 | USB_REQ_SET_CONFIGURATION, | ||
54 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
55 | PYRA_USB_COMMAND_CONTROL, 0, (char *)&control, | ||
56 | sizeof(struct pyra_control), | ||
57 | USB_CTRL_SET_TIMEOUT); | ||
58 | |||
59 | if (len != sizeof(struct pyra_control)) | ||
60 | return len; | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int pyra_receive_control_status(struct usb_device *usb_dev) | ||
66 | { | ||
67 | int len; | ||
68 | struct pyra_control control; | ||
69 | |||
70 | do { | ||
71 | msleep(10); | ||
72 | |||
73 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
74 | USB_REQ_CLEAR_FEATURE, | ||
75 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | ||
76 | USB_DIR_IN, | ||
77 | PYRA_USB_COMMAND_CONTROL, 0, (char *)&control, | ||
78 | sizeof(struct pyra_control), | ||
79 | USB_CTRL_SET_TIMEOUT); | ||
80 | |||
81 | /* requested too early, try again */ | ||
82 | } while (len == -EPROTO); | ||
83 | |||
84 | if (len == sizeof(struct pyra_control) && | ||
85 | control.command == PYRA_COMMAND_CONTROL && | ||
86 | control.request == PYRA_CONTROL_REQUEST_STATUS && | ||
87 | control.value == 1) | ||
88 | return 0; | ||
89 | else { | ||
90 | dev_err(&usb_dev->dev, "receive control status: " | ||
91 | "unknown response 0x%x 0x%x\n", | ||
92 | control.request, control.value); | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static int pyra_get_profile_settings(struct usb_device *usb_dev, | ||
98 | struct pyra_profile_settings *buf, int number) | ||
99 | { | ||
100 | int retval; | ||
101 | |||
102 | retval = pyra_send_control(usb_dev, number, | ||
103 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
104 | |||
105 | if (retval) | ||
106 | return retval; | ||
107 | |||
108 | retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
109 | USB_REQ_CLEAR_FEATURE, | ||
110 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
111 | PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf, | ||
112 | sizeof(struct pyra_profile_settings), | ||
113 | USB_CTRL_SET_TIMEOUT); | ||
114 | |||
115 | if (retval != sizeof(struct pyra_profile_settings)) | ||
116 | return retval; | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static int pyra_get_profile_buttons(struct usb_device *usb_dev, | ||
122 | struct pyra_profile_buttons *buf, int number) | ||
123 | { | ||
124 | int retval; | ||
125 | |||
126 | retval = pyra_send_control(usb_dev, number, | ||
127 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
128 | |||
129 | if (retval) | ||
130 | return retval; | ||
131 | |||
132 | retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
133 | USB_REQ_CLEAR_FEATURE, | ||
134 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
135 | PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf, | ||
136 | sizeof(struct pyra_profile_buttons), | ||
137 | USB_CTRL_SET_TIMEOUT); | ||
138 | |||
139 | if (retval != sizeof(struct pyra_profile_buttons)) | ||
140 | return retval; | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int pyra_get_settings(struct usb_device *usb_dev, | ||
146 | struct pyra_settings *buf) | ||
147 | { | ||
148 | int len; | ||
149 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
150 | USB_REQ_CLEAR_FEATURE, | ||
151 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
152 | PYRA_USB_COMMAND_SETTINGS, 0, buf, | ||
153 | sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT); | ||
154 | if (len != sizeof(struct pyra_settings)) | ||
155 | return -EIO; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) | ||
160 | { | ||
161 | int len; | ||
162 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
163 | USB_REQ_CLEAR_FEATURE, | ||
164 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
165 | PYRA_USB_COMMAND_INFO, 0, buf, | ||
166 | sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT); | ||
167 | if (len != sizeof(struct pyra_info)) | ||
168 | return -EIO; | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int pyra_set_profile_settings(struct usb_device *usb_dev, | ||
173 | struct pyra_profile_settings const *settings) | ||
174 | { | ||
175 | int len; | ||
176 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
177 | USB_REQ_SET_CONFIGURATION, | ||
178 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
179 | PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings, | ||
180 | sizeof(struct pyra_profile_settings), | ||
181 | USB_CTRL_SET_TIMEOUT); | ||
182 | if (len != sizeof(struct pyra_profile_settings)) | ||
183 | return -EIO; | ||
184 | if (pyra_receive_control_status(usb_dev)) | ||
185 | return -EIO; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int pyra_set_profile_buttons(struct usb_device *usb_dev, | ||
190 | struct pyra_profile_buttons const *buttons) | ||
191 | { | ||
192 | int len; | ||
193 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
194 | USB_REQ_SET_CONFIGURATION, | ||
195 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
196 | PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons, | ||
197 | sizeof(struct pyra_profile_buttons), | ||
198 | USB_CTRL_SET_TIMEOUT); | ||
199 | if (len != sizeof(struct pyra_profile_buttons)) | ||
200 | return -EIO; | ||
201 | if (pyra_receive_control_status(usb_dev)) | ||
202 | return -EIO; | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int pyra_set_settings(struct usb_device *usb_dev, | ||
207 | struct pyra_settings const *settings) | ||
208 | { | ||
209 | int len; | ||
210 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
211 | USB_REQ_SET_CONFIGURATION, | ||
212 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
213 | PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings, | ||
214 | sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT); | ||
215 | if (len != sizeof(struct pyra_settings)) | ||
216 | return -EIO; | ||
217 | if (pyra_receive_control_status(usb_dev)) | ||
218 | return -EIO; | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, | ||
223 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
224 | loff_t off, size_t count, int number) | ||
225 | { | ||
226 | struct device *dev = container_of(kobj, struct device, kobj); | ||
227 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
228 | |||
229 | if (off >= sizeof(struct pyra_profile_settings)) | ||
230 | return 0; | ||
231 | |||
232 | if (off + count > sizeof(struct pyra_profile_settings)) | ||
233 | count = sizeof(struct pyra_profile_settings) - off; | ||
234 | |||
235 | mutex_lock(&pyra->pyra_lock); | ||
236 | memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off, | ||
237 | count); | ||
238 | mutex_unlock(&pyra->pyra_lock); | ||
239 | |||
240 | return count; | ||
241 | } | ||
242 | |||
243 | static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp, | ||
244 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
245 | loff_t off, size_t count) | ||
246 | { | ||
247 | return pyra_sysfs_read_profilex_settings(fp, kobj, | ||
248 | attr, buf, off, count, 0); | ||
249 | } | ||
250 | |||
251 | static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp, | ||
252 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
253 | loff_t off, size_t count) | ||
254 | { | ||
255 | return pyra_sysfs_read_profilex_settings(fp, kobj, | ||
256 | attr, buf, off, count, 1); | ||
257 | } | ||
258 | |||
259 | static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp, | ||
260 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
261 | loff_t off, size_t count) | ||
262 | { | ||
263 | return pyra_sysfs_read_profilex_settings(fp, kobj, | ||
264 | attr, buf, off, count, 2); | ||
265 | } | ||
266 | |||
267 | static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp, | ||
268 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
269 | loff_t off, size_t count) | ||
270 | { | ||
271 | return pyra_sysfs_read_profilex_settings(fp, kobj, | ||
272 | attr, buf, off, count, 3); | ||
273 | } | ||
274 | |||
275 | static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp, | ||
276 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
277 | loff_t off, size_t count) | ||
278 | { | ||
279 | return pyra_sysfs_read_profilex_settings(fp, kobj, | ||
280 | attr, buf, off, count, 4); | ||
281 | } | ||
282 | |||
283 | static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, | ||
284 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
285 | loff_t off, size_t count, int number) | ||
286 | { | ||
287 | struct device *dev = container_of(kobj, struct device, kobj); | ||
288 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
289 | |||
290 | if (off >= sizeof(struct pyra_profile_buttons)) | ||
291 | return 0; | ||
292 | |||
293 | if (off + count > sizeof(struct pyra_profile_buttons)) | ||
294 | count = sizeof(struct pyra_profile_buttons) - off; | ||
295 | |||
296 | mutex_lock(&pyra->pyra_lock); | ||
297 | memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off, | ||
298 | count); | ||
299 | mutex_unlock(&pyra->pyra_lock); | ||
300 | |||
301 | return count; | ||
302 | } | ||
303 | |||
304 | static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp, | ||
305 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
306 | loff_t off, size_t count) | ||
307 | { | ||
308 | return pyra_sysfs_read_profilex_buttons(fp, kobj, | ||
309 | attr, buf, off, count, 0); | ||
310 | } | ||
311 | |||
312 | static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp, | ||
313 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
314 | loff_t off, size_t count) | ||
315 | { | ||
316 | return pyra_sysfs_read_profilex_buttons(fp, kobj, | ||
317 | attr, buf, off, count, 1); | ||
318 | } | ||
319 | |||
320 | static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp, | ||
321 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
322 | loff_t off, size_t count) | ||
323 | { | ||
324 | return pyra_sysfs_read_profilex_buttons(fp, kobj, | ||
325 | attr, buf, off, count, 2); | ||
326 | } | ||
327 | |||
328 | static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp, | ||
329 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
330 | loff_t off, size_t count) | ||
331 | { | ||
332 | return pyra_sysfs_read_profilex_buttons(fp, kobj, | ||
333 | attr, buf, off, count, 3); | ||
334 | } | ||
335 | |||
336 | static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp, | ||
337 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
338 | loff_t off, size_t count) | ||
339 | { | ||
340 | return pyra_sysfs_read_profilex_buttons(fp, kobj, | ||
341 | attr, buf, off, count, 4); | ||
342 | } | ||
343 | |||
344 | static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, | ||
345 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
346 | loff_t off, size_t count) | ||
347 | { | ||
348 | struct device *dev = container_of(kobj, struct device, kobj); | ||
349 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
350 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
351 | int retval = 0; | ||
352 | int difference; | ||
353 | int profile_number; | ||
354 | struct pyra_profile_settings *profile_settings; | ||
355 | |||
356 | if (off != 0 || count != sizeof(struct pyra_profile_settings)) | ||
357 | return -EINVAL; | ||
358 | |||
359 | profile_number = ((struct pyra_profile_settings const *)buf)->number; | ||
360 | profile_settings = &pyra->profile_settings[profile_number]; | ||
361 | |||
362 | mutex_lock(&pyra->pyra_lock); | ||
363 | difference = memcmp(buf, profile_settings, | ||
364 | sizeof(struct pyra_profile_settings)); | ||
365 | if (difference) { | ||
366 | retval = pyra_set_profile_settings(usb_dev, | ||
367 | (struct pyra_profile_settings const *)buf); | ||
368 | if (!retval) | ||
369 | memcpy(profile_settings, buf, | ||
370 | sizeof(struct pyra_profile_settings)); | ||
371 | } | ||
372 | mutex_unlock(&pyra->pyra_lock); | ||
373 | |||
374 | if (retval) | ||
375 | return retval; | ||
376 | |||
377 | return sizeof(struct pyra_profile_settings); | ||
378 | } | ||
379 | |||
380 | static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, | ||
381 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
382 | loff_t off, size_t count) | ||
383 | { | ||
384 | struct device *dev = container_of(kobj, struct device, kobj); | ||
385 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
386 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
387 | int retval = 0; | ||
388 | int difference; | ||
389 | int profile_number; | ||
390 | struct pyra_profile_buttons *profile_buttons; | ||
391 | |||
392 | if (off != 0 || count != sizeof(struct pyra_profile_buttons)) | ||
393 | return -EINVAL; | ||
394 | |||
395 | profile_number = ((struct pyra_profile_buttons const *)buf)->number; | ||
396 | profile_buttons = &pyra->profile_buttons[profile_number]; | ||
397 | |||
398 | mutex_lock(&pyra->pyra_lock); | ||
399 | difference = memcmp(buf, profile_buttons, | ||
400 | sizeof(struct pyra_profile_buttons)); | ||
401 | if (difference) { | ||
402 | retval = pyra_set_profile_buttons(usb_dev, | ||
403 | (struct pyra_profile_buttons const *)buf); | ||
404 | if (!retval) | ||
405 | memcpy(profile_buttons, buf, | ||
406 | sizeof(struct pyra_profile_buttons)); | ||
407 | } | ||
408 | mutex_unlock(&pyra->pyra_lock); | ||
409 | |||
410 | if (retval) | ||
411 | return retval; | ||
412 | |||
413 | return sizeof(struct pyra_profile_buttons); | ||
414 | } | ||
415 | |||
416 | static ssize_t pyra_sysfs_read_settings(struct file *fp, | ||
417 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
418 | loff_t off, size_t count) | ||
419 | { | ||
420 | struct device *dev = container_of(kobj, struct device, kobj); | ||
421 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
422 | |||
423 | if (off >= sizeof(struct pyra_settings)) | ||
424 | return 0; | ||
425 | |||
426 | if (off + count > sizeof(struct pyra_settings)) | ||
427 | count = sizeof(struct pyra_settings) - off; | ||
428 | |||
429 | mutex_lock(&pyra->pyra_lock); | ||
430 | memcpy(buf, ((char const *)&pyra->settings) + off, count); | ||
431 | mutex_unlock(&pyra->pyra_lock); | ||
432 | |||
433 | return count; | ||
434 | } | ||
435 | |||
436 | static ssize_t pyra_sysfs_write_settings(struct file *fp, | ||
437 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
438 | loff_t off, size_t count) | ||
439 | { | ||
440 | struct device *dev = container_of(kobj, struct device, kobj); | ||
441 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
442 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
443 | int retval = 0; | ||
444 | int difference; | ||
445 | |||
446 | if (off != 0 || count != sizeof(struct pyra_settings)) | ||
447 | return -EINVAL; | ||
448 | |||
449 | mutex_lock(&pyra->pyra_lock); | ||
450 | difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings)); | ||
451 | if (difference) { | ||
452 | retval = pyra_set_settings(usb_dev, | ||
453 | (struct pyra_settings const *)buf); | ||
454 | if (!retval) | ||
455 | memcpy(&pyra->settings, buf, | ||
456 | sizeof(struct pyra_settings)); | ||
457 | } | ||
458 | mutex_unlock(&pyra->pyra_lock); | ||
459 | |||
460 | if (retval) | ||
461 | return retval; | ||
462 | |||
463 | profile_activated(pyra, pyra->settings.startup_profile); | ||
464 | |||
465 | return sizeof(struct pyra_settings); | ||
466 | } | ||
467 | |||
468 | |||
469 | static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, | ||
470 | struct device_attribute *attr, char *buf) | ||
471 | { | ||
472 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
473 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); | ||
474 | } | ||
475 | |||
476 | static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, | ||
477 | struct device_attribute *attr, char *buf) | ||
478 | { | ||
479 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
480 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); | ||
481 | } | ||
482 | |||
483 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, | ||
484 | struct device_attribute *attr, char *buf) | ||
485 | { | ||
486 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
487 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); | ||
488 | } | ||
489 | |||
490 | static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, | ||
491 | struct device_attribute *attr, char *buf) | ||
492 | { | ||
493 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
494 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); | ||
495 | } | ||
496 | |||
497 | static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL); | ||
498 | |||
499 | static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL); | ||
500 | |||
501 | static DEVICE_ATTR(firmware_version, 0440, | ||
502 | pyra_sysfs_show_firmware_version, NULL); | ||
503 | |||
504 | static DEVICE_ATTR(startup_profile, 0440, | ||
505 | pyra_sysfs_show_startup_profile, NULL); | ||
506 | |||
507 | static struct attribute *pyra_attributes[] = { | ||
508 | &dev_attr_actual_cpi.attr, | ||
509 | &dev_attr_actual_profile.attr, | ||
510 | &dev_attr_firmware_version.attr, | ||
511 | &dev_attr_startup_profile.attr, | ||
512 | NULL | ||
513 | }; | ||
514 | |||
515 | static struct attribute_group pyra_attribute_group = { | ||
516 | .attrs = pyra_attributes | ||
517 | }; | ||
518 | |||
519 | static struct bin_attribute pyra_profile_settings_attr = { | ||
520 | .attr = { .name = "profile_settings", .mode = 0220 }, | ||
521 | .size = sizeof(struct pyra_profile_settings), | ||
522 | .write = pyra_sysfs_write_profile_settings | ||
523 | }; | ||
524 | |||
525 | static struct bin_attribute pyra_profile1_settings_attr = { | ||
526 | .attr = { .name = "profile1_settings", .mode = 0440 }, | ||
527 | .size = sizeof(struct pyra_profile_settings), | ||
528 | .read = pyra_sysfs_read_profile1_settings | ||
529 | }; | ||
530 | |||
531 | static struct bin_attribute pyra_profile2_settings_attr = { | ||
532 | .attr = { .name = "profile2_settings", .mode = 0440 }, | ||
533 | .size = sizeof(struct pyra_profile_settings), | ||
534 | .read = pyra_sysfs_read_profile2_settings | ||
535 | }; | ||
536 | |||
537 | static struct bin_attribute pyra_profile3_settings_attr = { | ||
538 | .attr = { .name = "profile3_settings", .mode = 0440 }, | ||
539 | .size = sizeof(struct pyra_profile_settings), | ||
540 | .read = pyra_sysfs_read_profile3_settings | ||
541 | }; | ||
542 | |||
543 | static struct bin_attribute pyra_profile4_settings_attr = { | ||
544 | .attr = { .name = "profile4_settings", .mode = 0440 }, | ||
545 | .size = sizeof(struct pyra_profile_settings), | ||
546 | .read = pyra_sysfs_read_profile4_settings | ||
547 | }; | ||
548 | |||
549 | static struct bin_attribute pyra_profile5_settings_attr = { | ||
550 | .attr = { .name = "profile5_settings", .mode = 0440 }, | ||
551 | .size = sizeof(struct pyra_profile_settings), | ||
552 | .read = pyra_sysfs_read_profile5_settings | ||
553 | }; | ||
554 | |||
555 | static struct bin_attribute pyra_profile_buttons_attr = { | ||
556 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
557 | .size = sizeof(struct pyra_profile_buttons), | ||
558 | .write = pyra_sysfs_write_profile_buttons | ||
559 | }; | ||
560 | |||
561 | static struct bin_attribute pyra_profile1_buttons_attr = { | ||
562 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | ||
563 | .size = sizeof(struct pyra_profile_buttons), | ||
564 | .read = pyra_sysfs_read_profile1_buttons | ||
565 | }; | ||
566 | |||
567 | static struct bin_attribute pyra_profile2_buttons_attr = { | ||
568 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | ||
569 | .size = sizeof(struct pyra_profile_buttons), | ||
570 | .read = pyra_sysfs_read_profile2_buttons | ||
571 | }; | ||
572 | |||
573 | static struct bin_attribute pyra_profile3_buttons_attr = { | ||
574 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | ||
575 | .size = sizeof(struct pyra_profile_buttons), | ||
576 | .read = pyra_sysfs_read_profile3_buttons | ||
577 | }; | ||
578 | |||
579 | static struct bin_attribute pyra_profile4_buttons_attr = { | ||
580 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | ||
581 | .size = sizeof(struct pyra_profile_buttons), | ||
582 | .read = pyra_sysfs_read_profile4_buttons | ||
583 | }; | ||
584 | |||
585 | static struct bin_attribute pyra_profile5_buttons_attr = { | ||
586 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | ||
587 | .size = sizeof(struct pyra_profile_buttons), | ||
588 | .read = pyra_sysfs_read_profile5_buttons | ||
589 | }; | ||
590 | |||
591 | static struct bin_attribute pyra_settings_attr = { | ||
592 | .attr = { .name = "settings", .mode = 0660 }, | ||
593 | .size = sizeof(struct pyra_settings), | ||
594 | .read = pyra_sysfs_read_settings, | ||
595 | .write = pyra_sysfs_write_settings | ||
596 | }; | ||
597 | |||
598 | static int pyra_create_sysfs_attributes(struct usb_interface *intf) | ||
599 | { | ||
600 | int retval; | ||
601 | |||
602 | retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group); | ||
603 | if (retval) | ||
604 | goto exit_1; | ||
605 | |||
606 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
607 | &pyra_profile_settings_attr); | ||
608 | if (retval) | ||
609 | goto exit_2; | ||
610 | |||
611 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
612 | &pyra_profile1_settings_attr); | ||
613 | if (retval) | ||
614 | goto exit_3; | ||
615 | |||
616 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
617 | &pyra_profile2_settings_attr); | ||
618 | if (retval) | ||
619 | goto exit_4; | ||
620 | |||
621 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
622 | &pyra_profile3_settings_attr); | ||
623 | if (retval) | ||
624 | goto exit_5; | ||
625 | |||
626 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
627 | &pyra_profile4_settings_attr); | ||
628 | if (retval) | ||
629 | goto exit_6; | ||
630 | |||
631 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
632 | &pyra_profile5_settings_attr); | ||
633 | if (retval) | ||
634 | goto exit_7; | ||
635 | |||
636 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
637 | &pyra_profile_buttons_attr); | ||
638 | if (retval) | ||
639 | goto exit_8; | ||
640 | |||
641 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
642 | &pyra_profile1_buttons_attr); | ||
643 | if (retval) | ||
644 | goto exit_9; | ||
645 | |||
646 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
647 | &pyra_profile2_buttons_attr); | ||
648 | if (retval) | ||
649 | goto exit_10; | ||
650 | |||
651 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
652 | &pyra_profile3_buttons_attr); | ||
653 | if (retval) | ||
654 | goto exit_11; | ||
655 | |||
656 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
657 | &pyra_profile4_buttons_attr); | ||
658 | if (retval) | ||
659 | goto exit_12; | ||
660 | |||
661 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
662 | &pyra_profile5_buttons_attr); | ||
663 | if (retval) | ||
664 | goto exit_13; | ||
665 | |||
666 | retval = sysfs_create_bin_file(&intf->dev.kobj, | ||
667 | &pyra_settings_attr); | ||
668 | if (retval) | ||
669 | goto exit_14; | ||
670 | |||
671 | return 0; | ||
672 | |||
673 | exit_14: | ||
674 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr); | ||
675 | exit_13: | ||
676 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr); | ||
677 | exit_12: | ||
678 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr); | ||
679 | exit_11: | ||
680 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr); | ||
681 | exit_10: | ||
682 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr); | ||
683 | exit_9: | ||
684 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr); | ||
685 | exit_8: | ||
686 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr); | ||
687 | exit_7: | ||
688 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr); | ||
689 | exit_6: | ||
690 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr); | ||
691 | exit_5: | ||
692 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr); | ||
693 | exit_4: | ||
694 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr); | ||
695 | exit_3: | ||
696 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr); | ||
697 | exit_2: | ||
698 | sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group); | ||
699 | exit_1: | ||
700 | return retval; | ||
701 | } | ||
702 | |||
703 | static void pyra_remove_sysfs_attributes(struct usb_interface *intf) | ||
704 | { | ||
705 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr); | ||
706 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr); | ||
707 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr); | ||
708 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr); | ||
709 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr); | ||
710 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr); | ||
711 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr); | ||
712 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr); | ||
713 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr); | ||
714 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr); | ||
715 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr); | ||
716 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr); | ||
717 | sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr); | ||
718 | sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group); | ||
719 | } | ||
720 | |||
721 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, | ||
722 | struct pyra_device *pyra) | ||
723 | { | ||
724 | struct pyra_info *info; | ||
725 | int retval, i; | ||
726 | |||
727 | mutex_init(&pyra->pyra_lock); | ||
728 | |||
729 | info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL); | ||
730 | if (!info) | ||
731 | return -ENOMEM; | ||
732 | retval = pyra_get_info(usb_dev, info); | ||
733 | if (retval) { | ||
734 | kfree(info); | ||
735 | return retval; | ||
736 | } | ||
737 | pyra->firmware_version = info->firmware_version; | ||
738 | kfree(info); | ||
739 | |||
740 | retval = pyra_get_settings(usb_dev, &pyra->settings); | ||
741 | if (retval) | ||
742 | return retval; | ||
743 | |||
744 | for (i = 0; i < 5; ++i) { | ||
745 | retval = pyra_get_profile_settings(usb_dev, | ||
746 | &pyra->profile_settings[i], i); | ||
747 | if (retval) | ||
748 | return retval; | ||
749 | |||
750 | retval = pyra_get_profile_buttons(usb_dev, | ||
751 | &pyra->profile_buttons[i], i); | ||
752 | if (retval) | ||
753 | return retval; | ||
754 | } | ||
755 | |||
756 | profile_activated(pyra, pyra->settings.startup_profile); | ||
757 | |||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | static int pyra_init_specials(struct hid_device *hdev) | ||
762 | { | ||
763 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
764 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
765 | struct pyra_device *pyra; | ||
766 | int retval; | ||
767 | |||
768 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
769 | == USB_INTERFACE_PROTOCOL_MOUSE) { | ||
770 | |||
771 | pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); | ||
772 | if (!pyra) { | ||
773 | dev_err(&hdev->dev, "can't alloc device descriptor\n"); | ||
774 | return -ENOMEM; | ||
775 | } | ||
776 | hid_set_drvdata(hdev, pyra); | ||
777 | |||
778 | retval = pyra_init_pyra_device_struct(usb_dev, pyra); | ||
779 | if (retval) { | ||
780 | dev_err(&hdev->dev, | ||
781 | "couldn't init struct pyra_device\n"); | ||
782 | goto exit_free; | ||
783 | } | ||
784 | |||
785 | retval = roccat_connect(hdev); | ||
786 | if (retval < 0) { | ||
787 | dev_err(&hdev->dev, "couldn't init char dev\n"); | ||
788 | } else { | ||
789 | pyra->chrdev_minor = retval; | ||
790 | pyra->roccat_claimed = 1; | ||
791 | } | ||
792 | |||
793 | retval = pyra_create_sysfs_attributes(intf); | ||
794 | if (retval) { | ||
795 | dev_err(&hdev->dev, "cannot create sysfs files\n"); | ||
796 | goto exit_free; | ||
797 | } | ||
798 | } else { | ||
799 | hid_set_drvdata(hdev, NULL); | ||
800 | } | ||
801 | |||
802 | return 0; | ||
803 | exit_free: | ||
804 | kfree(pyra); | ||
805 | return retval; | ||
806 | } | ||
807 | |||
808 | static void pyra_remove_specials(struct hid_device *hdev) | ||
809 | { | ||
810 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
811 | struct pyra_device *pyra; | ||
812 | |||
813 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
814 | == USB_INTERFACE_PROTOCOL_MOUSE) { | ||
815 | pyra_remove_sysfs_attributes(intf); | ||
816 | pyra = hid_get_drvdata(hdev); | ||
817 | if (pyra->roccat_claimed) | ||
818 | roccat_disconnect(pyra->chrdev_minor); | ||
819 | kfree(hid_get_drvdata(hdev)); | ||
820 | } | ||
821 | } | ||
822 | |||
823 | static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
824 | { | ||
825 | int retval; | ||
826 | |||
827 | retval = hid_parse(hdev); | ||
828 | if (retval) { | ||
829 | dev_err(&hdev->dev, "parse failed\n"); | ||
830 | goto exit; | ||
831 | } | ||
832 | |||
833 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
834 | if (retval) { | ||
835 | dev_err(&hdev->dev, "hw start failed\n"); | ||
836 | goto exit; | ||
837 | } | ||
838 | |||
839 | retval = pyra_init_specials(hdev); | ||
840 | if (retval) { | ||
841 | dev_err(&hdev->dev, "couldn't install mouse\n"); | ||
842 | goto exit_stop; | ||
843 | } | ||
844 | return 0; | ||
845 | |||
846 | exit_stop: | ||
847 | hid_hw_stop(hdev); | ||
848 | exit: | ||
849 | return retval; | ||
850 | } | ||
851 | |||
852 | static void pyra_remove(struct hid_device *hdev) | ||
853 | { | ||
854 | pyra_remove_specials(hdev); | ||
855 | hid_hw_stop(hdev); | ||
856 | } | ||
857 | |||
858 | static void pyra_keep_values_up_to_date(struct pyra_device *pyra, | ||
859 | u8 const *data) | ||
860 | { | ||
861 | struct pyra_mouse_event_button const *button_event; | ||
862 | |||
863 | switch (data[0]) { | ||
864 | case PYRA_MOUSE_REPORT_NUMBER_BUTTON: | ||
865 | button_event = (struct pyra_mouse_event_button const *)data; | ||
866 | switch (button_event->type) { | ||
867 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: | ||
868 | profile_activated(pyra, button_event->data1 - 1); | ||
869 | break; | ||
870 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: | ||
871 | pyra->actual_cpi = button_event->data1; | ||
872 | break; | ||
873 | } | ||
874 | break; | ||
875 | } | ||
876 | } | ||
877 | |||
878 | static void pyra_report_to_chrdev(struct pyra_device const *pyra, | ||
879 | u8 const *data) | ||
880 | { | ||
881 | struct pyra_roccat_report roccat_report; | ||
882 | struct pyra_mouse_event_button const *button_event; | ||
883 | |||
884 | if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON) | ||
885 | return; | ||
886 | |||
887 | button_event = (struct pyra_mouse_event_button const *)data; | ||
888 | |||
889 | switch (button_event->type) { | ||
890 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: | ||
891 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: | ||
892 | roccat_report.type = button_event->type; | ||
893 | roccat_report.value = button_event->data1; | ||
894 | roccat_report.key = 0; | ||
895 | roccat_report_event(pyra->chrdev_minor, | ||
896 | (uint8_t const *)&roccat_report, | ||
897 | sizeof(struct pyra_roccat_report)); | ||
898 | break; | ||
899 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: | ||
900 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: | ||
901 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH: | ||
902 | if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) { | ||
903 | roccat_report.type = button_event->type; | ||
904 | roccat_report.key = button_event->data1; | ||
905 | /* | ||
906 | * pyra reports profile numbers with range 1-5. | ||
907 | * Keeping this behaviour. | ||
908 | */ | ||
909 | roccat_report.value = pyra->actual_profile + 1; | ||
910 | roccat_report_event(pyra->chrdev_minor, | ||
911 | (uint8_t const *)&roccat_report, | ||
912 | sizeof(struct pyra_roccat_report)); | ||
913 | } | ||
914 | break; | ||
915 | } | ||
916 | } | ||
917 | |||
918 | static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, | ||
919 | u8 *data, int size) | ||
920 | { | ||
921 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
922 | struct pyra_device *pyra = hid_get_drvdata(hdev); | ||
923 | |||
924 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
925 | != USB_INTERFACE_PROTOCOL_MOUSE) | ||
926 | return 0; | ||
927 | |||
928 | pyra_keep_values_up_to_date(pyra, data); | ||
929 | |||
930 | if (pyra->roccat_claimed) | ||
931 | pyra_report_to_chrdev(pyra, data); | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | static const struct hid_device_id pyra_devices[] = { | ||
937 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, | ||
938 | USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, | ||
939 | /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */ | ||
940 | { } | ||
941 | }; | ||
942 | |||
943 | MODULE_DEVICE_TABLE(hid, pyra_devices); | ||
944 | |||
945 | static struct hid_driver pyra_driver = { | ||
946 | .name = "pyra", | ||
947 | .id_table = pyra_devices, | ||
948 | .probe = pyra_probe, | ||
949 | .remove = pyra_remove, | ||
950 | .raw_event = pyra_raw_event | ||
951 | }; | ||
952 | |||
953 | static int __init pyra_init(void) | ||
954 | { | ||
955 | return hid_register_driver(&pyra_driver); | ||
956 | } | ||
957 | |||
958 | static void __exit pyra_exit(void) | ||
959 | { | ||
960 | hid_unregister_driver(&pyra_driver); | ||
961 | } | ||
962 | |||
963 | module_init(pyra_init); | ||
964 | module_exit(pyra_exit); | ||
965 | |||
966 | MODULE_AUTHOR("Stefan Achatz"); | ||
967 | MODULE_DESCRIPTION("USB Roccat Pyra driver"); | ||
968 | MODULE_LICENSE("GPL v2"); | ||
969 |
drivers/hid/hid-roccat-pyra.h
File was created | 1 | #ifndef __HID_ROCCAT_PYRA_H | |
2 | #define __HID_ROCCAT_PYRA_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | #pragma pack(push) | ||
18 | #pragma pack(1) | ||
19 | |||
20 | struct pyra_b { | ||
21 | uint8_t command; /* PYRA_COMMAND_B */ | ||
22 | uint8_t size; /* always 3 */ | ||
23 | uint8_t unknown; /* 1 */ | ||
24 | }; | ||
25 | |||
26 | struct pyra_control { | ||
27 | uint8_t command; /* PYRA_COMMAND_CONTROL */ | ||
28 | /* | ||
29 | * value is profile number for request_settings and request_buttons | ||
30 | * 1 if status ok for request_status | ||
31 | */ | ||
32 | uint8_t value; /* Range 0-4 */ | ||
33 | uint8_t request; | ||
34 | }; | ||
35 | |||
36 | enum pyra_control_requests { | ||
37 | PYRA_CONTROL_REQUEST_STATUS = 0x00, | ||
38 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | ||
39 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 | ||
40 | }; | ||
41 | |||
42 | struct pyra_settings { | ||
43 | uint8_t command; /* PYRA_COMMAND_SETTINGS */ | ||
44 | uint8_t size; /* always 3 */ | ||
45 | uint8_t startup_profile; /* Range 0-4! */ | ||
46 | }; | ||
47 | |||
48 | struct pyra_profile_settings { | ||
49 | uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */ | ||
50 | uint8_t size; /* always 0xd */ | ||
51 | uint8_t number; /* Range 0-4 */ | ||
52 | uint8_t xysync; | ||
53 | uint8_t x_sensitivity; /* 0x1-0xa */ | ||
54 | uint8_t y_sensitivity; | ||
55 | uint8_t x_cpi; /* unused */ | ||
56 | uint8_t y_cpi; /* this value is for x and y */ | ||
57 | uint8_t lightswitch; /* 0 = off, 1 = on */ | ||
58 | uint8_t light_effect; | ||
59 | uint8_t handedness; | ||
60 | uint16_t checksum; /* byte sum */ | ||
61 | }; | ||
62 | |||
63 | struct pyra_profile_buttons { | ||
64 | uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */ | ||
65 | uint8_t size; /* always 0x13 */ | ||
66 | uint8_t number; /* Range 0-4 */ | ||
67 | uint8_t buttons[14]; | ||
68 | uint16_t checksum; /* byte sum */ | ||
69 | }; | ||
70 | |||
71 | struct pyra_info { | ||
72 | uint8_t command; /* PYRA_COMMAND_INFO */ | ||
73 | uint8_t size; /* always 6 */ | ||
74 | uint8_t firmware_version; | ||
75 | uint8_t unknown1; /* always 0 */ | ||
76 | uint8_t unknown2; /* always 1 */ | ||
77 | uint8_t unknown3; /* always 0 */ | ||
78 | }; | ||
79 | |||
80 | enum pyra_commands { | ||
81 | PYRA_COMMAND_CONTROL = 0x4, | ||
82 | PYRA_COMMAND_SETTINGS = 0x5, | ||
83 | PYRA_COMMAND_PROFILE_SETTINGS = 0x6, | ||
84 | PYRA_COMMAND_PROFILE_BUTTONS = 0x7, | ||
85 | PYRA_COMMAND_INFO = 0x9, | ||
86 | PYRA_COMMAND_B = 0xb | ||
87 | }; | ||
88 | |||
89 | enum pyra_usb_commands { | ||
90 | PYRA_USB_COMMAND_CONTROL = 0x304, | ||
91 | PYRA_USB_COMMAND_SETTINGS = 0x305, | ||
92 | PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306, | ||
93 | PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307, | ||
94 | PYRA_USB_COMMAND_INFO = 0x309, | ||
95 | PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */ | ||
96 | }; | ||
97 | |||
98 | enum pyra_mouse_report_numbers { | ||
99 | PYRA_MOUSE_REPORT_NUMBER_HID = 1, | ||
100 | PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2, | ||
101 | PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3, | ||
102 | }; | ||
103 | |||
104 | struct pyra_mouse_event_button { | ||
105 | uint8_t report_number; /* always 3 */ | ||
106 | uint8_t unknown; /* always 0 */ | ||
107 | uint8_t type; | ||
108 | uint8_t data1; | ||
109 | uint8_t data2; | ||
110 | }; | ||
111 | |||
112 | struct pyra_mouse_event_audio { | ||
113 | uint8_t report_number; /* always 2 */ | ||
114 | uint8_t type; | ||
115 | uint8_t unused; /* always 0 */ | ||
116 | }; | ||
117 | |||
118 | /* hid audio controls */ | ||
119 | enum pyra_mouse_event_audio_types { | ||
120 | PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2, | ||
121 | PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9, | ||
122 | PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea, | ||
123 | }; | ||
124 | |||
125 | enum pyra_mouse_event_button_types { | ||
126 | /* | ||
127 | * Mouse sends tilt events on report_number 1 and 3 | ||
128 | * Tilt events are sent repeatedly with 0.94s between first and second | ||
129 | * event and 0.22s on subsequent | ||
130 | */ | ||
131 | PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10, | ||
132 | |||
133 | /* | ||
134 | * These are sent sequentially | ||
135 | * data1 contains new profile number in range 1-5 | ||
136 | */ | ||
137 | PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20, | ||
138 | PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30, | ||
139 | |||
140 | /* | ||
141 | * data1 = button_number (rmp index) | ||
142 | * data2 = pressed/released | ||
143 | */ | ||
144 | PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40, | ||
145 | PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50, | ||
146 | |||
147 | /* | ||
148 | * data1 = button_number (rmp index) | ||
149 | */ | ||
150 | PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60, | ||
151 | |||
152 | /* data1 = new cpi */ | ||
153 | PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0, | ||
154 | |||
155 | /* data1 and data2 = new sensitivity */ | ||
156 | PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0, | ||
157 | |||
158 | PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0, | ||
159 | }; | ||
160 | |||
161 | enum { | ||
162 | PYRA_MOUSE_EVENT_BUTTON_PRESS = 0, | ||
163 | PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1, | ||
164 | }; | ||
165 | |||
166 | struct pyra_roccat_report { | ||
167 | uint8_t type; | ||
168 | uint8_t value; | ||
169 | uint8_t key; | ||
170 | }; | ||
171 | |||
172 | #pragma pack(pop) | ||
173 | |||
174 | struct pyra_device { | ||
175 | int actual_profile; | ||
176 | int actual_cpi; | ||
177 | int firmware_version; | ||
178 | int roccat_claimed; | ||
179 | int chrdev_minor; | ||
180 | struct mutex pyra_lock; | ||
181 | struct pyra_settings settings; | ||
182 | struct pyra_profile_settings profile_settings[5]; | ||
183 | struct pyra_profile_buttons profile_buttons[5]; | ||
184 | }; | ||
185 | |||
186 | #endif | ||
187 |
drivers/hid/usbhid/hid-core.c
1 | /* | 1 | /* |
2 | * USB HID support for Linux | 2 | * USB HID support for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2007-2008 Oliver Neukum | 7 | * Copyright (c) 2007-2008 Oliver Neukum |
8 | * Copyright (c) 2006-2010 Jiri Kosina | 8 | * Copyright (c) 2006-2010 Jiri Kosina |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 14 | * Software Foundation; either version 2 of the License, or (at your option) |
15 | * any later version. | 15 | * any later version. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/wait.h> | 29 | #include <linux/wait.h> |
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | 31 | ||
32 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
33 | 33 | ||
34 | #include <linux/hid.h> | 34 | #include <linux/hid.h> |
35 | #include <linux/hiddev.h> | 35 | #include <linux/hiddev.h> |
36 | #include <linux/hid-debug.h> | 36 | #include <linux/hid-debug.h> |
37 | #include <linux/hidraw.h> | 37 | #include <linux/hidraw.h> |
38 | #include "usbhid.h" | 38 | #include "usbhid.h" |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Version Information | 41 | * Version Information |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define DRIVER_DESC "USB HID core driver" | 44 | #define DRIVER_DESC "USB HID core driver" |
45 | #define DRIVER_LICENSE "GPL" | 45 | #define DRIVER_LICENSE "GPL" |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Module parameters. | 48 | * Module parameters. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | static unsigned int hid_mousepoll_interval; | 51 | static unsigned int hid_mousepoll_interval; |
52 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); | 52 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); |
53 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | 53 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); |
54 | 54 | ||
55 | static unsigned int ignoreled; | 55 | static unsigned int ignoreled; |
56 | module_param_named(ignoreled, ignoreled, uint, 0644); | 56 | module_param_named(ignoreled, ignoreled, uint, 0644); |
57 | MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); | 57 | MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); |
58 | 58 | ||
59 | /* Quirks specified at module load time */ | 59 | /* Quirks specified at module load time */ |
60 | static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; | 60 | static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; |
61 | module_param_array_named(quirks, quirks_param, charp, NULL, 0444); | 61 | module_param_array_named(quirks, quirks_param, charp, NULL, 0444); |
62 | MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " | 62 | MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " |
63 | " quirks=vendorID:productID:quirks" | 63 | " quirks=vendorID:productID:quirks" |
64 | " where vendorID, productID, and quirks are all in" | 64 | " where vendorID, productID, and quirks are all in" |
65 | " 0x-prefixed hex"); | 65 | " 0x-prefixed hex"); |
66 | /* | 66 | /* |
67 | * Input submission and I/O error handler. | 67 | * Input submission and I/O error handler. |
68 | */ | 68 | */ |
69 | static DEFINE_MUTEX(hid_open_mut); | 69 | static DEFINE_MUTEX(hid_open_mut); |
70 | static struct workqueue_struct *resumption_waker; | 70 | static struct workqueue_struct *resumption_waker; |
71 | 71 | ||
72 | static void hid_io_error(struct hid_device *hid); | 72 | static void hid_io_error(struct hid_device *hid); |
73 | static int hid_submit_out(struct hid_device *hid); | 73 | static int hid_submit_out(struct hid_device *hid); |
74 | static int hid_submit_ctrl(struct hid_device *hid); | 74 | static int hid_submit_ctrl(struct hid_device *hid); |
75 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid); | 75 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid); |
76 | 76 | ||
77 | /* Start up the input URB */ | 77 | /* Start up the input URB */ |
78 | static int hid_start_in(struct hid_device *hid) | 78 | static int hid_start_in(struct hid_device *hid) |
79 | { | 79 | { |
80 | unsigned long flags; | 80 | unsigned long flags; |
81 | int rc = 0; | 81 | int rc = 0; |
82 | struct usbhid_device *usbhid = hid->driver_data; | 82 | struct usbhid_device *usbhid = hid->driver_data; |
83 | 83 | ||
84 | spin_lock_irqsave(&usbhid->lock, flags); | 84 | spin_lock_irqsave(&usbhid->lock, flags); |
85 | if (hid->open > 0 && | 85 | if (hid->open > 0 && |
86 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && | 86 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && |
87 | !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && | 87 | !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && |
88 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { | 88 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { |
89 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); | 89 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); |
90 | if (rc != 0) | 90 | if (rc != 0) |
91 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 91 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
92 | } | 92 | } |
93 | spin_unlock_irqrestore(&usbhid->lock, flags); | 93 | spin_unlock_irqrestore(&usbhid->lock, flags); |
94 | return rc; | 94 | return rc; |
95 | } | 95 | } |
96 | 96 | ||
97 | /* I/O retry timer routine */ | 97 | /* I/O retry timer routine */ |
98 | static void hid_retry_timeout(unsigned long _hid) | 98 | static void hid_retry_timeout(unsigned long _hid) |
99 | { | 99 | { |
100 | struct hid_device *hid = (struct hid_device *) _hid; | 100 | struct hid_device *hid = (struct hid_device *) _hid; |
101 | struct usbhid_device *usbhid = hid->driver_data; | 101 | struct usbhid_device *usbhid = hid->driver_data; |
102 | 102 | ||
103 | dev_dbg(&usbhid->intf->dev, "retrying intr urb\n"); | 103 | dev_dbg(&usbhid->intf->dev, "retrying intr urb\n"); |
104 | if (hid_start_in(hid)) | 104 | if (hid_start_in(hid)) |
105 | hid_io_error(hid); | 105 | hid_io_error(hid); |
106 | } | 106 | } |
107 | 107 | ||
108 | /* Workqueue routine to reset the device or clear a halt */ | 108 | /* Workqueue routine to reset the device or clear a halt */ |
109 | static void hid_reset(struct work_struct *work) | 109 | static void hid_reset(struct work_struct *work) |
110 | { | 110 | { |
111 | struct usbhid_device *usbhid = | 111 | struct usbhid_device *usbhid = |
112 | container_of(work, struct usbhid_device, reset_work); | 112 | container_of(work, struct usbhid_device, reset_work); |
113 | struct hid_device *hid = usbhid->hid; | 113 | struct hid_device *hid = usbhid->hid; |
114 | int rc = 0; | 114 | int rc = 0; |
115 | 115 | ||
116 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { | 116 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { |
117 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); | 117 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); |
118 | rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); | 118 | rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); |
119 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); | 119 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); |
120 | hid_start_in(hid); | 120 | hid_start_in(hid); |
121 | } | 121 | } |
122 | 122 | ||
123 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { | 123 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
124 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); | 124 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); |
125 | rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); | 125 | rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); |
126 | if (rc == 0) { | 126 | if (rc == 0) { |
127 | rc = usb_reset_device(hid_to_usb_dev(hid)); | 127 | rc = usb_reset_device(hid_to_usb_dev(hid)); |
128 | usb_unlock_device(hid_to_usb_dev(hid)); | 128 | usb_unlock_device(hid_to_usb_dev(hid)); |
129 | } | 129 | } |
130 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 130 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
131 | } | 131 | } |
132 | 132 | ||
133 | switch (rc) { | 133 | switch (rc) { |
134 | case 0: | 134 | case 0: |
135 | if (!test_bit(HID_IN_RUNNING, &usbhid->iofl)) | 135 | if (!test_bit(HID_IN_RUNNING, &usbhid->iofl)) |
136 | hid_io_error(hid); | 136 | hid_io_error(hid); |
137 | break; | 137 | break; |
138 | default: | 138 | default: |
139 | err_hid("can't reset device, %s-%s/input%d, status %d", | 139 | err_hid("can't reset device, %s-%s/input%d, status %d", |
140 | hid_to_usb_dev(hid)->bus->bus_name, | 140 | hid_to_usb_dev(hid)->bus->bus_name, |
141 | hid_to_usb_dev(hid)->devpath, | 141 | hid_to_usb_dev(hid)->devpath, |
142 | usbhid->ifnum, rc); | 142 | usbhid->ifnum, rc); |
143 | /* FALLTHROUGH */ | 143 | /* FALLTHROUGH */ |
144 | case -EHOSTUNREACH: | 144 | case -EHOSTUNREACH: |
145 | case -ENODEV: | 145 | case -ENODEV: |
146 | case -EINTR: | 146 | case -EINTR: |
147 | break; | 147 | break; |
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
151 | /* Main I/O error handler */ | 151 | /* Main I/O error handler */ |
152 | static void hid_io_error(struct hid_device *hid) | 152 | static void hid_io_error(struct hid_device *hid) |
153 | { | 153 | { |
154 | unsigned long flags; | 154 | unsigned long flags; |
155 | struct usbhid_device *usbhid = hid->driver_data; | 155 | struct usbhid_device *usbhid = hid->driver_data; |
156 | 156 | ||
157 | spin_lock_irqsave(&usbhid->lock, flags); | 157 | spin_lock_irqsave(&usbhid->lock, flags); |
158 | 158 | ||
159 | /* Stop when disconnected */ | 159 | /* Stop when disconnected */ |
160 | if (test_bit(HID_DISCONNECTED, &usbhid->iofl)) | 160 | if (test_bit(HID_DISCONNECTED, &usbhid->iofl)) |
161 | goto done; | 161 | goto done; |
162 | 162 | ||
163 | /* If it has been a while since the last error, we'll assume | 163 | /* If it has been a while since the last error, we'll assume |
164 | * this a brand new error and reset the retry timeout. */ | 164 | * this a brand new error and reset the retry timeout. */ |
165 | if (time_after(jiffies, usbhid->stop_retry + HZ/2)) | 165 | if (time_after(jiffies, usbhid->stop_retry + HZ/2)) |
166 | usbhid->retry_delay = 0; | 166 | usbhid->retry_delay = 0; |
167 | 167 | ||
168 | /* When an error occurs, retry at increasing intervals */ | 168 | /* When an error occurs, retry at increasing intervals */ |
169 | if (usbhid->retry_delay == 0) { | 169 | if (usbhid->retry_delay == 0) { |
170 | usbhid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */ | 170 | usbhid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */ |
171 | usbhid->stop_retry = jiffies + msecs_to_jiffies(1000); | 171 | usbhid->stop_retry = jiffies + msecs_to_jiffies(1000); |
172 | } else if (usbhid->retry_delay < 100) | 172 | } else if (usbhid->retry_delay < 100) |
173 | usbhid->retry_delay *= 2; | 173 | usbhid->retry_delay *= 2; |
174 | 174 | ||
175 | if (time_after(jiffies, usbhid->stop_retry)) { | 175 | if (time_after(jiffies, usbhid->stop_retry)) { |
176 | 176 | ||
177 | /* Retries failed, so do a port reset */ | 177 | /* Retries failed, so do a port reset */ |
178 | if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { | 178 | if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
179 | schedule_work(&usbhid->reset_work); | 179 | schedule_work(&usbhid->reset_work); |
180 | goto done; | 180 | goto done; |
181 | } | 181 | } |
182 | } | 182 | } |
183 | 183 | ||
184 | mod_timer(&usbhid->io_retry, | 184 | mod_timer(&usbhid->io_retry, |
185 | jiffies + msecs_to_jiffies(usbhid->retry_delay)); | 185 | jiffies + msecs_to_jiffies(usbhid->retry_delay)); |
186 | done: | 186 | done: |
187 | spin_unlock_irqrestore(&usbhid->lock, flags); | 187 | spin_unlock_irqrestore(&usbhid->lock, flags); |
188 | } | 188 | } |
189 | 189 | ||
190 | static void usbhid_mark_busy(struct usbhid_device *usbhid) | 190 | static void usbhid_mark_busy(struct usbhid_device *usbhid) |
191 | { | 191 | { |
192 | struct usb_interface *intf = usbhid->intf; | 192 | struct usb_interface *intf = usbhid->intf; |
193 | 193 | ||
194 | usb_mark_last_busy(interface_to_usbdev(intf)); | 194 | usb_mark_last_busy(interface_to_usbdev(intf)); |
195 | } | 195 | } |
196 | 196 | ||
197 | static int usbhid_restart_out_queue(struct usbhid_device *usbhid) | 197 | static int usbhid_restart_out_queue(struct usbhid_device *usbhid) |
198 | { | 198 | { |
199 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); | 199 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); |
200 | int kicked; | 200 | int kicked; |
201 | 201 | ||
202 | if (!hid) | 202 | if (!hid) |
203 | return 0; | 203 | return 0; |
204 | 204 | ||
205 | if ((kicked = (usbhid->outhead != usbhid->outtail))) { | 205 | if ((kicked = (usbhid->outhead != usbhid->outtail))) { |
206 | dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); | 206 | dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); |
207 | if (hid_submit_out(hid)) { | 207 | if (hid_submit_out(hid)) { |
208 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 208 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
209 | wake_up(&usbhid->wait); | 209 | wake_up(&usbhid->wait); |
210 | } | 210 | } |
211 | } | 211 | } |
212 | return kicked; | 212 | return kicked; |
213 | } | 213 | } |
214 | 214 | ||
215 | static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid) | 215 | static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid) |
216 | { | 216 | { |
217 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); | 217 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); |
218 | int kicked; | 218 | int kicked; |
219 | 219 | ||
220 | WARN_ON(hid == NULL); | 220 | WARN_ON(hid == NULL); |
221 | if (!hid) | 221 | if (!hid) |
222 | return 0; | 222 | return 0; |
223 | 223 | ||
224 | if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { | 224 | if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { |
225 | dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); | 225 | dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); |
226 | if (hid_submit_ctrl(hid)) { | 226 | if (hid_submit_ctrl(hid)) { |
227 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 227 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
228 | wake_up(&usbhid->wait); | 228 | wake_up(&usbhid->wait); |
229 | } | 229 | } |
230 | } | 230 | } |
231 | return kicked; | 231 | return kicked; |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | 234 | /* |
235 | * Input interrupt completion handler. | 235 | * Input interrupt completion handler. |
236 | */ | 236 | */ |
237 | 237 | ||
238 | static void hid_irq_in(struct urb *urb) | 238 | static void hid_irq_in(struct urb *urb) |
239 | { | 239 | { |
240 | struct hid_device *hid = urb->context; | 240 | struct hid_device *hid = urb->context; |
241 | struct usbhid_device *usbhid = hid->driver_data; | 241 | struct usbhid_device *usbhid = hid->driver_data; |
242 | int status; | 242 | int status; |
243 | 243 | ||
244 | switch (urb->status) { | 244 | switch (urb->status) { |
245 | case 0: /* success */ | 245 | case 0: /* success */ |
246 | usbhid_mark_busy(usbhid); | 246 | usbhid_mark_busy(usbhid); |
247 | usbhid->retry_delay = 0; | 247 | usbhid->retry_delay = 0; |
248 | hid_input_report(urb->context, HID_INPUT_REPORT, | 248 | hid_input_report(urb->context, HID_INPUT_REPORT, |
249 | urb->transfer_buffer, | 249 | urb->transfer_buffer, |
250 | urb->actual_length, 1); | 250 | urb->actual_length, 1); |
251 | /* | 251 | /* |
252 | * autosuspend refused while keys are pressed | 252 | * autosuspend refused while keys are pressed |
253 | * because most keyboards don't wake up when | 253 | * because most keyboards don't wake up when |
254 | * a key is released | 254 | * a key is released |
255 | */ | 255 | */ |
256 | if (hid_check_keys_pressed(hid)) | 256 | if (hid_check_keys_pressed(hid)) |
257 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 257 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); |
258 | else | 258 | else |
259 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 259 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); |
260 | break; | 260 | break; |
261 | case -EPIPE: /* stall */ | 261 | case -EPIPE: /* stall */ |
262 | usbhid_mark_busy(usbhid); | 262 | usbhid_mark_busy(usbhid); |
263 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 263 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
264 | set_bit(HID_CLEAR_HALT, &usbhid->iofl); | 264 | set_bit(HID_CLEAR_HALT, &usbhid->iofl); |
265 | schedule_work(&usbhid->reset_work); | 265 | schedule_work(&usbhid->reset_work); |
266 | return; | 266 | return; |
267 | case -ECONNRESET: /* unlink */ | 267 | case -ECONNRESET: /* unlink */ |
268 | case -ENOENT: | 268 | case -ENOENT: |
269 | case -ESHUTDOWN: /* unplug */ | 269 | case -ESHUTDOWN: /* unplug */ |
270 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 270 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
271 | return; | 271 | return; |
272 | case -EILSEQ: /* protocol error or unplug */ | 272 | case -EILSEQ: /* protocol error or unplug */ |
273 | case -EPROTO: /* protocol error or unplug */ | 273 | case -EPROTO: /* protocol error or unplug */ |
274 | case -ETIME: /* protocol error or unplug */ | 274 | case -ETIME: /* protocol error or unplug */ |
275 | case -ETIMEDOUT: /* Should never happen, but... */ | 275 | case -ETIMEDOUT: /* Should never happen, but... */ |
276 | usbhid_mark_busy(usbhid); | 276 | usbhid_mark_busy(usbhid); |
277 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 277 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
278 | hid_io_error(hid); | 278 | hid_io_error(hid); |
279 | return; | 279 | return; |
280 | default: /* error */ | 280 | default: /* error */ |
281 | dev_warn(&urb->dev->dev, "input irq status %d " | 281 | dev_warn(&urb->dev->dev, "input irq status %d " |
282 | "received\n", urb->status); | 282 | "received\n", urb->status); |
283 | } | 283 | } |
284 | 284 | ||
285 | status = usb_submit_urb(urb, GFP_ATOMIC); | 285 | status = usb_submit_urb(urb, GFP_ATOMIC); |
286 | if (status) { | 286 | if (status) { |
287 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 287 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
288 | if (status != -EPERM) { | 288 | if (status != -EPERM) { |
289 | err_hid("can't resubmit intr, %s-%s/input%d, status %d", | 289 | err_hid("can't resubmit intr, %s-%s/input%d, status %d", |
290 | hid_to_usb_dev(hid)->bus->bus_name, | 290 | hid_to_usb_dev(hid)->bus->bus_name, |
291 | hid_to_usb_dev(hid)->devpath, | 291 | hid_to_usb_dev(hid)->devpath, |
292 | usbhid->ifnum, status); | 292 | usbhid->ifnum, status); |
293 | hid_io_error(hid); | 293 | hid_io_error(hid); |
294 | } | 294 | } |
295 | } | 295 | } |
296 | } | 296 | } |
297 | 297 | ||
298 | static int hid_submit_out(struct hid_device *hid) | 298 | static int hid_submit_out(struct hid_device *hid) |
299 | { | 299 | { |
300 | struct hid_report *report; | 300 | struct hid_report *report; |
301 | char *raw_report; | 301 | char *raw_report; |
302 | struct usbhid_device *usbhid = hid->driver_data; | 302 | struct usbhid_device *usbhid = hid->driver_data; |
303 | 303 | ||
304 | report = usbhid->out[usbhid->outtail].report; | 304 | report = usbhid->out[usbhid->outtail].report; |
305 | raw_report = usbhid->out[usbhid->outtail].raw_report; | 305 | raw_report = usbhid->out[usbhid->outtail].raw_report; |
306 | 306 | ||
307 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { | 307 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { |
308 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 308 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
309 | usbhid->urbout->dev = hid_to_usb_dev(hid); | 309 | usbhid->urbout->dev = hid_to_usb_dev(hid); |
310 | memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length); | 310 | memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length); |
311 | kfree(raw_report); | 311 | kfree(raw_report); |
312 | 312 | ||
313 | dbg_hid("submitting out urb\n"); | 313 | dbg_hid("submitting out urb\n"); |
314 | 314 | ||
315 | if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { | 315 | if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { |
316 | err_hid("usb_submit_urb(out) failed"); | 316 | err_hid("usb_submit_urb(out) failed"); |
317 | return -1; | 317 | return -1; |
318 | } | 318 | } |
319 | usbhid->last_out = jiffies; | 319 | usbhid->last_out = jiffies; |
320 | } else { | 320 | } else { |
321 | /* | 321 | /* |
322 | * queue work to wake up the device. | 322 | * queue work to wake up the device. |
323 | * as the work queue is freezeable, this is safe | 323 | * as the work queue is freezeable, this is safe |
324 | * with respect to STD and STR | 324 | * with respect to STD and STR |
325 | */ | 325 | */ |
326 | queue_work(resumption_waker, &usbhid->restart_work); | 326 | queue_work(resumption_waker, &usbhid->restart_work); |
327 | } | 327 | } |
328 | 328 | ||
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | 331 | ||
332 | static int hid_submit_ctrl(struct hid_device *hid) | 332 | static int hid_submit_ctrl(struct hid_device *hid) |
333 | { | 333 | { |
334 | struct hid_report *report; | 334 | struct hid_report *report; |
335 | unsigned char dir; | 335 | unsigned char dir; |
336 | char *raw_report; | 336 | char *raw_report; |
337 | int len; | 337 | int len; |
338 | struct usbhid_device *usbhid = hid->driver_data; | 338 | struct usbhid_device *usbhid = hid->driver_data; |
339 | 339 | ||
340 | report = usbhid->ctrl[usbhid->ctrltail].report; | 340 | report = usbhid->ctrl[usbhid->ctrltail].report; |
341 | raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; | 341 | raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; |
342 | dir = usbhid->ctrl[usbhid->ctrltail].dir; | 342 | dir = usbhid->ctrl[usbhid->ctrltail].dir; |
343 | 343 | ||
344 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { | 344 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { |
345 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 345 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
346 | if (dir == USB_DIR_OUT) { | 346 | if (dir == USB_DIR_OUT) { |
347 | usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); | 347 | usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); |
348 | usbhid->urbctrl->transfer_buffer_length = len; | 348 | usbhid->urbctrl->transfer_buffer_length = len; |
349 | memcpy(usbhid->ctrlbuf, raw_report, len); | 349 | memcpy(usbhid->ctrlbuf, raw_report, len); |
350 | kfree(raw_report); | 350 | kfree(raw_report); |
351 | } else { | 351 | } else { |
352 | int maxpacket, padlen; | 352 | int maxpacket, padlen; |
353 | 353 | ||
354 | usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); | 354 | usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); |
355 | maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); | 355 | maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); |
356 | if (maxpacket > 0) { | 356 | if (maxpacket > 0) { |
357 | padlen = DIV_ROUND_UP(len, maxpacket); | 357 | padlen = DIV_ROUND_UP(len, maxpacket); |
358 | padlen *= maxpacket; | 358 | padlen *= maxpacket; |
359 | if (padlen > usbhid->bufsize) | 359 | if (padlen > usbhid->bufsize) |
360 | padlen = usbhid->bufsize; | 360 | padlen = usbhid->bufsize; |
361 | } else | 361 | } else |
362 | padlen = 0; | 362 | padlen = 0; |
363 | usbhid->urbctrl->transfer_buffer_length = padlen; | 363 | usbhid->urbctrl->transfer_buffer_length = padlen; |
364 | } | 364 | } |
365 | usbhid->urbctrl->dev = hid_to_usb_dev(hid); | 365 | usbhid->urbctrl->dev = hid_to_usb_dev(hid); |
366 | 366 | ||
367 | usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; | 367 | usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; |
368 | usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; | 368 | usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; |
369 | usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); | 369 | usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); |
370 | usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); | 370 | usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); |
371 | usbhid->cr->wLength = cpu_to_le16(len); | 371 | usbhid->cr->wLength = cpu_to_le16(len); |
372 | 372 | ||
373 | dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n", | 373 | dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n", |
374 | usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", | 374 | usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", |
375 | usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); | 375 | usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); |
376 | 376 | ||
377 | if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { | 377 | if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { |
378 | err_hid("usb_submit_urb(ctrl) failed"); | 378 | err_hid("usb_submit_urb(ctrl) failed"); |
379 | return -1; | 379 | return -1; |
380 | } | 380 | } |
381 | usbhid->last_ctrl = jiffies; | 381 | usbhid->last_ctrl = jiffies; |
382 | } else { | 382 | } else { |
383 | /* | 383 | /* |
384 | * queue work to wake up the device. | 384 | * queue work to wake up the device. |
385 | * as the work queue is freezeable, this is safe | 385 | * as the work queue is freezeable, this is safe |
386 | * with respect to STD and STR | 386 | * with respect to STD and STR |
387 | */ | 387 | */ |
388 | queue_work(resumption_waker, &usbhid->restart_work); | 388 | queue_work(resumption_waker, &usbhid->restart_work); |
389 | } | 389 | } |
390 | 390 | ||
391 | return 0; | 391 | return 0; |
392 | } | 392 | } |
393 | 393 | ||
394 | /* | 394 | /* |
395 | * Output interrupt completion handler. | 395 | * Output interrupt completion handler. |
396 | */ | 396 | */ |
397 | 397 | ||
398 | static void hid_irq_out(struct urb *urb) | 398 | static void hid_irq_out(struct urb *urb) |
399 | { | 399 | { |
400 | struct hid_device *hid = urb->context; | 400 | struct hid_device *hid = urb->context; |
401 | struct usbhid_device *usbhid = hid->driver_data; | 401 | struct usbhid_device *usbhid = hid->driver_data; |
402 | unsigned long flags; | 402 | unsigned long flags; |
403 | int unplug = 0; | 403 | int unplug = 0; |
404 | 404 | ||
405 | switch (urb->status) { | 405 | switch (urb->status) { |
406 | case 0: /* success */ | 406 | case 0: /* success */ |
407 | break; | 407 | break; |
408 | case -ESHUTDOWN: /* unplug */ | 408 | case -ESHUTDOWN: /* unplug */ |
409 | unplug = 1; | 409 | unplug = 1; |
410 | case -EILSEQ: /* protocol error or unplug */ | 410 | case -EILSEQ: /* protocol error or unplug */ |
411 | case -EPROTO: /* protocol error or unplug */ | 411 | case -EPROTO: /* protocol error or unplug */ |
412 | case -ECONNRESET: /* unlink */ | 412 | case -ECONNRESET: /* unlink */ |
413 | case -ENOENT: | 413 | case -ENOENT: |
414 | break; | 414 | break; |
415 | default: /* error */ | 415 | default: /* error */ |
416 | dev_warn(&urb->dev->dev, "output irq status %d " | 416 | dev_warn(&urb->dev->dev, "output irq status %d " |
417 | "received\n", urb->status); | 417 | "received\n", urb->status); |
418 | } | 418 | } |
419 | 419 | ||
420 | spin_lock_irqsave(&usbhid->lock, flags); | 420 | spin_lock_irqsave(&usbhid->lock, flags); |
421 | 421 | ||
422 | if (unplug) | 422 | if (unplug) |
423 | usbhid->outtail = usbhid->outhead; | 423 | usbhid->outtail = usbhid->outhead; |
424 | else | 424 | else |
425 | usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); | 425 | usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); |
426 | 426 | ||
427 | if (usbhid->outhead != usbhid->outtail) { | 427 | if (usbhid->outhead != usbhid->outtail) { |
428 | if (hid_submit_out(hid)) { | 428 | if (hid_submit_out(hid)) { |
429 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 429 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
430 | wake_up(&usbhid->wait); | 430 | wake_up(&usbhid->wait); |
431 | } | 431 | } |
432 | spin_unlock_irqrestore(&usbhid->lock, flags); | 432 | spin_unlock_irqrestore(&usbhid->lock, flags); |
433 | return; | 433 | return; |
434 | } | 434 | } |
435 | 435 | ||
436 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 436 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
437 | spin_unlock_irqrestore(&usbhid->lock, flags); | 437 | spin_unlock_irqrestore(&usbhid->lock, flags); |
438 | wake_up(&usbhid->wait); | 438 | wake_up(&usbhid->wait); |
439 | } | 439 | } |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Control pipe completion handler. | 442 | * Control pipe completion handler. |
443 | */ | 443 | */ |
444 | 444 | ||
445 | static void hid_ctrl(struct urb *urb) | 445 | static void hid_ctrl(struct urb *urb) |
446 | { | 446 | { |
447 | struct hid_device *hid = urb->context; | 447 | struct hid_device *hid = urb->context; |
448 | struct usbhid_device *usbhid = hid->driver_data; | 448 | struct usbhid_device *usbhid = hid->driver_data; |
449 | int unplug = 0, status = urb->status; | 449 | int unplug = 0, status = urb->status; |
450 | 450 | ||
451 | spin_lock(&usbhid->lock); | 451 | spin_lock(&usbhid->lock); |
452 | 452 | ||
453 | switch (status) { | 453 | switch (status) { |
454 | case 0: /* success */ | 454 | case 0: /* success */ |
455 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) | 455 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) |
456 | hid_input_report(urb->context, | 456 | hid_input_report(urb->context, |
457 | usbhid->ctrl[usbhid->ctrltail].report->type, | 457 | usbhid->ctrl[usbhid->ctrltail].report->type, |
458 | urb->transfer_buffer, urb->actual_length, 0); | 458 | urb->transfer_buffer, urb->actual_length, 0); |
459 | break; | 459 | break; |
460 | case -ESHUTDOWN: /* unplug */ | 460 | case -ESHUTDOWN: /* unplug */ |
461 | unplug = 1; | 461 | unplug = 1; |
462 | case -EILSEQ: /* protocol error or unplug */ | 462 | case -EILSEQ: /* protocol error or unplug */ |
463 | case -EPROTO: /* protocol error or unplug */ | 463 | case -EPROTO: /* protocol error or unplug */ |
464 | case -ECONNRESET: /* unlink */ | 464 | case -ECONNRESET: /* unlink */ |
465 | case -ENOENT: | 465 | case -ENOENT: |
466 | case -EPIPE: /* report not available */ | 466 | case -EPIPE: /* report not available */ |
467 | break; | 467 | break; |
468 | default: /* error */ | 468 | default: /* error */ |
469 | dev_warn(&urb->dev->dev, "ctrl urb status %d " | 469 | dev_warn(&urb->dev->dev, "ctrl urb status %d " |
470 | "received\n", status); | 470 | "received\n", status); |
471 | } | 471 | } |
472 | 472 | ||
473 | if (unplug) | 473 | if (unplug) |
474 | usbhid->ctrltail = usbhid->ctrlhead; | 474 | usbhid->ctrltail = usbhid->ctrlhead; |
475 | else | 475 | else |
476 | usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); | 476 | usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); |
477 | 477 | ||
478 | if (usbhid->ctrlhead != usbhid->ctrltail) { | 478 | if (usbhid->ctrlhead != usbhid->ctrltail) { |
479 | if (hid_submit_ctrl(hid)) { | 479 | if (hid_submit_ctrl(hid)) { |
480 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 480 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
481 | wake_up(&usbhid->wait); | 481 | wake_up(&usbhid->wait); |
482 | } | 482 | } |
483 | spin_unlock(&usbhid->lock); | 483 | spin_unlock(&usbhid->lock); |
484 | return; | 484 | return; |
485 | } | 485 | } |
486 | 486 | ||
487 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 487 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
488 | spin_unlock(&usbhid->lock); | 488 | spin_unlock(&usbhid->lock); |
489 | wake_up(&usbhid->wait); | 489 | wake_up(&usbhid->wait); |
490 | } | 490 | } |
491 | 491 | ||
492 | static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, | 492 | static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, |
493 | unsigned char dir) | 493 | unsigned char dir) |
494 | { | 494 | { |
495 | int head; | 495 | int head; |
496 | struct usbhid_device *usbhid = hid->driver_data; | 496 | struct usbhid_device *usbhid = hid->driver_data; |
497 | int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 497 | int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
498 | 498 | ||
499 | if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) | 499 | if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) |
500 | return; | 500 | return; |
501 | 501 | ||
502 | if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { | 502 | if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { |
503 | if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { | 503 | if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { |
504 | dev_warn(&hid->dev, "output queue full\n"); | 504 | dev_warn(&hid->dev, "output queue full\n"); |
505 | return; | 505 | return; |
506 | } | 506 | } |
507 | 507 | ||
508 | usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); | 508 | usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); |
509 | if (!usbhid->out[usbhid->outhead].raw_report) { | 509 | if (!usbhid->out[usbhid->outhead].raw_report) { |
510 | dev_warn(&hid->dev, "output queueing failed\n"); | 510 | dev_warn(&hid->dev, "output queueing failed\n"); |
511 | return; | 511 | return; |
512 | } | 512 | } |
513 | hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); | 513 | hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); |
514 | usbhid->out[usbhid->outhead].report = report; | 514 | usbhid->out[usbhid->outhead].report = report; |
515 | usbhid->outhead = head; | 515 | usbhid->outhead = head; |
516 | 516 | ||
517 | if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) { | 517 | if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) { |
518 | if (hid_submit_out(hid)) | 518 | if (hid_submit_out(hid)) |
519 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 519 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
520 | } else { | 520 | } else { |
521 | /* | 521 | /* |
522 | * the queue is known to run | 522 | * the queue is known to run |
523 | * but an earlier request may be stuck | 523 | * but an earlier request may be stuck |
524 | * we may need to time out | 524 | * we may need to time out |
525 | * no race because this is called under | 525 | * no race because this is called under |
526 | * spinlock | 526 | * spinlock |
527 | */ | 527 | */ |
528 | if (time_after(jiffies, usbhid->last_out + HZ * 5)) | 528 | if (time_after(jiffies, usbhid->last_out + HZ * 5)) |
529 | usb_unlink_urb(usbhid->urbout); | 529 | usb_unlink_urb(usbhid->urbout); |
530 | } | 530 | } |
531 | return; | 531 | return; |
532 | } | 532 | } |
533 | 533 | ||
534 | if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { | 534 | if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { |
535 | dev_warn(&hid->dev, "control queue full\n"); | 535 | dev_warn(&hid->dev, "control queue full\n"); |
536 | return; | 536 | return; |
537 | } | 537 | } |
538 | 538 | ||
539 | if (dir == USB_DIR_OUT) { | 539 | if (dir == USB_DIR_OUT) { |
540 | usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); | 540 | usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); |
541 | if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { | 541 | if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { |
542 | dev_warn(&hid->dev, "control queueing failed\n"); | 542 | dev_warn(&hid->dev, "control queueing failed\n"); |
543 | return; | 543 | return; |
544 | } | 544 | } |
545 | hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); | 545 | hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); |
546 | } | 546 | } |
547 | usbhid->ctrl[usbhid->ctrlhead].report = report; | 547 | usbhid->ctrl[usbhid->ctrlhead].report = report; |
548 | usbhid->ctrl[usbhid->ctrlhead].dir = dir; | 548 | usbhid->ctrl[usbhid->ctrlhead].dir = dir; |
549 | usbhid->ctrlhead = head; | 549 | usbhid->ctrlhead = head; |
550 | 550 | ||
551 | if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) { | 551 | if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) { |
552 | if (hid_submit_ctrl(hid)) | 552 | if (hid_submit_ctrl(hid)) |
553 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 553 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
554 | } else { | 554 | } else { |
555 | /* | 555 | /* |
556 | * the queue is known to run | 556 | * the queue is known to run |
557 | * but an earlier request may be stuck | 557 | * but an earlier request may be stuck |
558 | * we may need to time out | 558 | * we may need to time out |
559 | * no race because this is called under | 559 | * no race because this is called under |
560 | * spinlock | 560 | * spinlock |
561 | */ | 561 | */ |
562 | if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) | 562 | if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) |
563 | usb_unlink_urb(usbhid->urbctrl); | 563 | usb_unlink_urb(usbhid->urbctrl); |
564 | } | 564 | } |
565 | } | 565 | } |
566 | 566 | ||
567 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | 567 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) |
568 | { | 568 | { |
569 | struct usbhid_device *usbhid = hid->driver_data; | 569 | struct usbhid_device *usbhid = hid->driver_data; |
570 | unsigned long flags; | 570 | unsigned long flags; |
571 | 571 | ||
572 | spin_lock_irqsave(&usbhid->lock, flags); | 572 | spin_lock_irqsave(&usbhid->lock, flags); |
573 | __usbhid_submit_report(hid, report, dir); | 573 | __usbhid_submit_report(hid, report, dir); |
574 | spin_unlock_irqrestore(&usbhid->lock, flags); | 574 | spin_unlock_irqrestore(&usbhid->lock, flags); |
575 | } | 575 | } |
576 | EXPORT_SYMBOL_GPL(usbhid_submit_report); | 576 | EXPORT_SYMBOL_GPL(usbhid_submit_report); |
577 | 577 | ||
578 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 578 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
579 | { | 579 | { |
580 | struct hid_device *hid = input_get_drvdata(dev); | 580 | struct hid_device *hid = input_get_drvdata(dev); |
581 | struct usbhid_device *usbhid = hid->driver_data; | 581 | struct usbhid_device *usbhid = hid->driver_data; |
582 | struct hid_field *field; | 582 | struct hid_field *field; |
583 | unsigned long flags; | 583 | unsigned long flags; |
584 | int offset; | 584 | int offset; |
585 | 585 | ||
586 | if (type == EV_FF) | 586 | if (type == EV_FF) |
587 | return input_ff_event(dev, type, code, value); | 587 | return input_ff_event(dev, type, code, value); |
588 | 588 | ||
589 | if (type != EV_LED) | 589 | if (type != EV_LED) |
590 | return -1; | 590 | return -1; |
591 | 591 | ||
592 | if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { | 592 | if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { |
593 | dev_warn(&dev->dev, "event field not found\n"); | 593 | dev_warn(&dev->dev, "event field not found\n"); |
594 | return -1; | 594 | return -1; |
595 | } | 595 | } |
596 | 596 | ||
597 | hid_set_field(field, offset, value); | 597 | hid_set_field(field, offset, value); |
598 | if (value) { | 598 | if (value) { |
599 | spin_lock_irqsave(&usbhid->lock, flags); | 599 | spin_lock_irqsave(&usbhid->lock, flags); |
600 | usbhid->ledcount++; | 600 | usbhid->ledcount++; |
601 | spin_unlock_irqrestore(&usbhid->lock, flags); | 601 | spin_unlock_irqrestore(&usbhid->lock, flags); |
602 | } else { | 602 | } else { |
603 | spin_lock_irqsave(&usbhid->lock, flags); | 603 | spin_lock_irqsave(&usbhid->lock, flags); |
604 | usbhid->ledcount--; | 604 | usbhid->ledcount--; |
605 | spin_unlock_irqrestore(&usbhid->lock, flags); | 605 | spin_unlock_irqrestore(&usbhid->lock, flags); |
606 | } | 606 | } |
607 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); | 607 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); |
608 | 608 | ||
609 | return 0; | 609 | return 0; |
610 | } | 610 | } |
611 | 611 | ||
612 | int usbhid_wait_io(struct hid_device *hid) | 612 | int usbhid_wait_io(struct hid_device *hid) |
613 | { | 613 | { |
614 | struct usbhid_device *usbhid = hid->driver_data; | 614 | struct usbhid_device *usbhid = hid->driver_data; |
615 | 615 | ||
616 | if (!wait_event_timeout(usbhid->wait, | 616 | if (!wait_event_timeout(usbhid->wait, |
617 | (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && | 617 | (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && |
618 | !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), | 618 | !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), |
619 | 10*HZ)) { | 619 | 10*HZ)) { |
620 | dbg_hid("timeout waiting for ctrl or out queue to clear\n"); | 620 | dbg_hid("timeout waiting for ctrl or out queue to clear\n"); |
621 | return -1; | 621 | return -1; |
622 | } | 622 | } |
623 | 623 | ||
624 | return 0; | 624 | return 0; |
625 | } | 625 | } |
626 | EXPORT_SYMBOL_GPL(usbhid_wait_io); | 626 | EXPORT_SYMBOL_GPL(usbhid_wait_io); |
627 | 627 | ||
628 | static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) | 628 | static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) |
629 | { | 629 | { |
630 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 630 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
631 | HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, | 631 | HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, |
632 | ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); | 632 | ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); |
633 | } | 633 | } |
634 | 634 | ||
635 | static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | 635 | static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, |
636 | unsigned char type, void *buf, int size) | 636 | unsigned char type, void *buf, int size) |
637 | { | 637 | { |
638 | int result, retries = 4; | 638 | int result, retries = 4; |
639 | 639 | ||
640 | memset(buf, 0, size); | 640 | memset(buf, 0, size); |
641 | 641 | ||
642 | do { | 642 | do { |
643 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 643 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
644 | USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, | 644 | USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, |
645 | (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); | 645 | (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); |
646 | retries--; | 646 | retries--; |
647 | } while (result < size && retries); | 647 | } while (result < size && retries); |
648 | return result; | 648 | return result; |
649 | } | 649 | } |
650 | 650 | ||
651 | int usbhid_open(struct hid_device *hid) | 651 | int usbhid_open(struct hid_device *hid) |
652 | { | 652 | { |
653 | struct usbhid_device *usbhid = hid->driver_data; | 653 | struct usbhid_device *usbhid = hid->driver_data; |
654 | int res; | 654 | int res; |
655 | 655 | ||
656 | mutex_lock(&hid_open_mut); | 656 | mutex_lock(&hid_open_mut); |
657 | if (!hid->open++) { | 657 | if (!hid->open++) { |
658 | res = usb_autopm_get_interface(usbhid->intf); | 658 | res = usb_autopm_get_interface(usbhid->intf); |
659 | /* the device must be awake to reliable request remote wakeup */ | 659 | /* the device must be awake to reliable request remote wakeup */ |
660 | if (res < 0) { | 660 | if (res < 0) { |
661 | hid->open--; | 661 | hid->open--; |
662 | mutex_unlock(&hid_open_mut); | 662 | mutex_unlock(&hid_open_mut); |
663 | return -EIO; | 663 | return -EIO; |
664 | } | 664 | } |
665 | usbhid->intf->needs_remote_wakeup = 1; | 665 | usbhid->intf->needs_remote_wakeup = 1; |
666 | if (hid_start_in(hid)) | 666 | if (hid_start_in(hid)) |
667 | hid_io_error(hid); | 667 | hid_io_error(hid); |
668 | 668 | ||
669 | usb_autopm_put_interface(usbhid->intf); | 669 | usb_autopm_put_interface(usbhid->intf); |
670 | } | 670 | } |
671 | mutex_unlock(&hid_open_mut); | 671 | mutex_unlock(&hid_open_mut); |
672 | return 0; | 672 | return 0; |
673 | } | 673 | } |
674 | 674 | ||
675 | void usbhid_close(struct hid_device *hid) | 675 | void usbhid_close(struct hid_device *hid) |
676 | { | 676 | { |
677 | struct usbhid_device *usbhid = hid->driver_data; | 677 | struct usbhid_device *usbhid = hid->driver_data; |
678 | 678 | ||
679 | mutex_lock(&hid_open_mut); | 679 | mutex_lock(&hid_open_mut); |
680 | 680 | ||
681 | /* protecting hid->open to make sure we don't restart | 681 | /* protecting hid->open to make sure we don't restart |
682 | * data acquistion due to a resumption we no longer | 682 | * data acquistion due to a resumption we no longer |
683 | * care about | 683 | * care about |
684 | */ | 684 | */ |
685 | spin_lock_irq(&usbhid->lock); | 685 | spin_lock_irq(&usbhid->lock); |
686 | if (!--hid->open) { | 686 | if (!--hid->open) { |
687 | spin_unlock_irq(&usbhid->lock); | 687 | spin_unlock_irq(&usbhid->lock); |
688 | hid_cancel_delayed_stuff(usbhid); | 688 | hid_cancel_delayed_stuff(usbhid); |
689 | usb_kill_urb(usbhid->urbin); | 689 | usb_kill_urb(usbhid->urbin); |
690 | usbhid->intf->needs_remote_wakeup = 0; | 690 | usbhid->intf->needs_remote_wakeup = 0; |
691 | } else { | 691 | } else { |
692 | spin_unlock_irq(&usbhid->lock); | 692 | spin_unlock_irq(&usbhid->lock); |
693 | } | 693 | } |
694 | mutex_unlock(&hid_open_mut); | 694 | mutex_unlock(&hid_open_mut); |
695 | } | 695 | } |
696 | 696 | ||
697 | /* | 697 | /* |
698 | * Initialize all reports | 698 | * Initialize all reports |
699 | */ | 699 | */ |
700 | 700 | ||
701 | void usbhid_init_reports(struct hid_device *hid) | 701 | void usbhid_init_reports(struct hid_device *hid) |
702 | { | 702 | { |
703 | struct hid_report *report; | 703 | struct hid_report *report; |
704 | struct usbhid_device *usbhid = hid->driver_data; | 704 | struct usbhid_device *usbhid = hid->driver_data; |
705 | int err, ret; | 705 | int err, ret; |
706 | 706 | ||
707 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) | 707 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) |
708 | usbhid_submit_report(hid, report, USB_DIR_IN); | 708 | usbhid_submit_report(hid, report, USB_DIR_IN); |
709 | 709 | ||
710 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | 710 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) |
711 | usbhid_submit_report(hid, report, USB_DIR_IN); | 711 | usbhid_submit_report(hid, report, USB_DIR_IN); |
712 | 712 | ||
713 | err = 0; | 713 | err = 0; |
714 | ret = usbhid_wait_io(hid); | 714 | ret = usbhid_wait_io(hid); |
715 | while (ret) { | 715 | while (ret) { |
716 | err |= ret; | 716 | err |= ret; |
717 | if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) | 717 | if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) |
718 | usb_kill_urb(usbhid->urbctrl); | 718 | usb_kill_urb(usbhid->urbctrl); |
719 | if (test_bit(HID_OUT_RUNNING, &usbhid->iofl)) | 719 | if (test_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
720 | usb_kill_urb(usbhid->urbout); | 720 | usb_kill_urb(usbhid->urbout); |
721 | ret = usbhid_wait_io(hid); | 721 | ret = usbhid_wait_io(hid); |
722 | } | 722 | } |
723 | 723 | ||
724 | if (err) | 724 | if (err) |
725 | dev_warn(&hid->dev, "timeout initializing reports\n"); | 725 | dev_warn(&hid->dev, "timeout initializing reports\n"); |
726 | } | 726 | } |
727 | 727 | ||
728 | /* | 728 | /* |
729 | * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01). | 729 | * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01). |
730 | */ | 730 | */ |
731 | static int hid_find_field_early(struct hid_device *hid, unsigned int page, | 731 | static int hid_find_field_early(struct hid_device *hid, unsigned int page, |
732 | unsigned int hid_code, struct hid_field **pfield) | 732 | unsigned int hid_code, struct hid_field **pfield) |
733 | { | 733 | { |
734 | struct hid_report *report; | 734 | struct hid_report *report; |
735 | struct hid_field *field; | 735 | struct hid_field *field; |
736 | struct hid_usage *usage; | 736 | struct hid_usage *usage; |
737 | int i, j; | 737 | int i, j; |
738 | 738 | ||
739 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { | 739 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { |
740 | for (i = 0; i < report->maxfield; i++) { | 740 | for (i = 0; i < report->maxfield; i++) { |
741 | field = report->field[i]; | 741 | field = report->field[i]; |
742 | for (j = 0; j < field->maxusage; j++) { | 742 | for (j = 0; j < field->maxusage; j++) { |
743 | usage = &field->usage[j]; | 743 | usage = &field->usage[j]; |
744 | if ((usage->hid & HID_USAGE_PAGE) == page && | 744 | if ((usage->hid & HID_USAGE_PAGE) == page && |
745 | (usage->hid & 0xFFFF) == hid_code) { | 745 | (usage->hid & 0xFFFF) == hid_code) { |
746 | *pfield = field; | 746 | *pfield = field; |
747 | return j; | 747 | return j; |
748 | } | 748 | } |
749 | } | 749 | } |
750 | } | 750 | } |
751 | } | 751 | } |
752 | return -1; | 752 | return -1; |
753 | } | 753 | } |
754 | 754 | ||
755 | void usbhid_set_leds(struct hid_device *hid) | 755 | void usbhid_set_leds(struct hid_device *hid) |
756 | { | 756 | { |
757 | struct hid_field *field; | 757 | struct hid_field *field; |
758 | int offset; | 758 | int offset; |
759 | 759 | ||
760 | if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) { | 760 | if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) { |
761 | hid_set_field(field, offset, 0); | 761 | hid_set_field(field, offset, 0); |
762 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); | 762 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); |
763 | } | 763 | } |
764 | } | 764 | } |
765 | EXPORT_SYMBOL_GPL(usbhid_set_leds); | 765 | EXPORT_SYMBOL_GPL(usbhid_set_leds); |
766 | 766 | ||
767 | /* | 767 | /* |
768 | * Traverse the supplied list of reports and find the longest | 768 | * Traverse the supplied list of reports and find the longest |
769 | */ | 769 | */ |
770 | static void hid_find_max_report(struct hid_device *hid, unsigned int type, | 770 | static void hid_find_max_report(struct hid_device *hid, unsigned int type, |
771 | unsigned int *max) | 771 | unsigned int *max) |
772 | { | 772 | { |
773 | struct hid_report *report; | 773 | struct hid_report *report; |
774 | unsigned int size; | 774 | unsigned int size; |
775 | 775 | ||
776 | list_for_each_entry(report, &hid->report_enum[type].report_list, list) { | 776 | list_for_each_entry(report, &hid->report_enum[type].report_list, list) { |
777 | size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered; | 777 | size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered; |
778 | if (*max < size) | 778 | if (*max < size) |
779 | *max = size; | 779 | *max = size; |
780 | } | 780 | } |
781 | } | 781 | } |
782 | 782 | ||
783 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | 783 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) |
784 | { | 784 | { |
785 | struct usbhid_device *usbhid = hid->driver_data; | 785 | struct usbhid_device *usbhid = hid->driver_data; |
786 | 786 | ||
787 | usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, | 787 | usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, |
788 | &usbhid->inbuf_dma); | 788 | &usbhid->inbuf_dma); |
789 | usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, | 789 | usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, |
790 | &usbhid->outbuf_dma); | 790 | &usbhid->outbuf_dma); |
791 | usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL); | 791 | usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL); |
792 | usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, | 792 | usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, |
793 | &usbhid->ctrlbuf_dma); | 793 | &usbhid->ctrlbuf_dma); |
794 | if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr || | 794 | if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr || |
795 | !usbhid->ctrlbuf) | 795 | !usbhid->ctrlbuf) |
796 | return -1; | 796 | return -1; |
797 | 797 | ||
798 | return 0; | 798 | return 0; |
799 | } | 799 | } |
800 | 800 | ||
801 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, | 801 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, |
802 | unsigned char report_type) | 802 | unsigned char report_type) |
803 | { | 803 | { |
804 | struct usbhid_device *usbhid = hid->driver_data; | 804 | struct usbhid_device *usbhid = hid->driver_data; |
805 | struct usb_device *dev = hid_to_usb_dev(hid); | 805 | struct usb_device *dev = hid_to_usb_dev(hid); |
806 | struct usb_interface *intf = usbhid->intf; | 806 | struct usb_interface *intf = usbhid->intf; |
807 | struct usb_host_interface *interface = intf->cur_altsetting; | 807 | struct usb_host_interface *interface = intf->cur_altsetting; |
808 | int ret; | 808 | int ret; |
809 | 809 | ||
810 | if (usbhid->urbout) { | 810 | if (usbhid->urbout && report_type != HID_FEATURE_REPORT) { |
811 | int actual_length; | 811 | int actual_length; |
812 | int skipped_report_id = 0; | 812 | int skipped_report_id = 0; |
813 | 813 | ||
814 | if (buf[0] == 0x0) { | 814 | if (buf[0] == 0x0) { |
815 | /* Don't send the Report ID */ | 815 | /* Don't send the Report ID */ |
816 | buf++; | 816 | buf++; |
817 | count--; | 817 | count--; |
818 | skipped_report_id = 1; | 818 | skipped_report_id = 1; |
819 | } | 819 | } |
820 | ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, | 820 | ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, |
821 | buf, count, &actual_length, | 821 | buf, count, &actual_length, |
822 | USB_CTRL_SET_TIMEOUT); | 822 | USB_CTRL_SET_TIMEOUT); |
823 | /* return the number of bytes transferred */ | 823 | /* return the number of bytes transferred */ |
824 | if (ret == 0) { | 824 | if (ret == 0) { |
825 | ret = actual_length; | 825 | ret = actual_length; |
826 | /* count also the report id */ | 826 | /* count also the report id */ |
827 | if (skipped_report_id) | 827 | if (skipped_report_id) |
828 | ret++; | 828 | ret++; |
829 | } | 829 | } |
830 | } else { | 830 | } else { |
831 | int skipped_report_id = 0; | 831 | int skipped_report_id = 0; |
832 | int report_id = buf[0]; | 832 | int report_id = buf[0]; |
833 | if (buf[0] == 0x0) { | 833 | if (buf[0] == 0x0) { |
834 | /* Don't send the Report ID */ | 834 | /* Don't send the Report ID */ |
835 | buf++; | 835 | buf++; |
836 | count--; | 836 | count--; |
837 | skipped_report_id = 1; | 837 | skipped_report_id = 1; |
838 | } | 838 | } |
839 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 839 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
840 | HID_REQ_SET_REPORT, | 840 | HID_REQ_SET_REPORT, |
841 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 841 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
842 | ((report_type + 1) << 8) | report_id, | 842 | ((report_type + 1) << 8) | report_id, |
843 | interface->desc.bInterfaceNumber, buf, count, | 843 | interface->desc.bInterfaceNumber, buf, count, |
844 | USB_CTRL_SET_TIMEOUT); | 844 | USB_CTRL_SET_TIMEOUT); |
845 | /* count also the report id, if this was a numbered report. */ | 845 | /* count also the report id, if this was a numbered report. */ |
846 | if (ret > 0 && skipped_report_id) | 846 | if (ret > 0 && skipped_report_id) |
847 | ret++; | 847 | ret++; |
848 | } | 848 | } |
849 | 849 | ||
850 | return ret; | 850 | return ret; |
851 | } | 851 | } |
852 | 852 | ||
853 | static void usbhid_restart_queues(struct usbhid_device *usbhid) | 853 | static void usbhid_restart_queues(struct usbhid_device *usbhid) |
854 | { | 854 | { |
855 | if (usbhid->urbout) | 855 | if (usbhid->urbout) |
856 | usbhid_restart_out_queue(usbhid); | 856 | usbhid_restart_out_queue(usbhid); |
857 | usbhid_restart_ctrl_queue(usbhid); | 857 | usbhid_restart_ctrl_queue(usbhid); |
858 | } | 858 | } |
859 | 859 | ||
860 | static void __usbhid_restart_queues(struct work_struct *work) | 860 | static void __usbhid_restart_queues(struct work_struct *work) |
861 | { | 861 | { |
862 | struct usbhid_device *usbhid = | 862 | struct usbhid_device *usbhid = |
863 | container_of(work, struct usbhid_device, restart_work); | 863 | container_of(work, struct usbhid_device, restart_work); |
864 | int r; | 864 | int r; |
865 | 865 | ||
866 | r = usb_autopm_get_interface(usbhid->intf); | 866 | r = usb_autopm_get_interface(usbhid->intf); |
867 | if (r < 0) | 867 | if (r < 0) |
868 | return; | 868 | return; |
869 | usb_autopm_put_interface(usbhid->intf); | 869 | usb_autopm_put_interface(usbhid->intf); |
870 | } | 870 | } |
871 | 871 | ||
872 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | 872 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
873 | { | 873 | { |
874 | struct usbhid_device *usbhid = hid->driver_data; | 874 | struct usbhid_device *usbhid = hid->driver_data; |
875 | 875 | ||
876 | usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); | 876 | usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); |
877 | usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); | 877 | usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); |
878 | kfree(usbhid->cr); | 878 | kfree(usbhid->cr); |
879 | usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); | 879 | usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); |
880 | } | 880 | } |
881 | 881 | ||
882 | static int usbhid_parse(struct hid_device *hid) | 882 | static int usbhid_parse(struct hid_device *hid) |
883 | { | 883 | { |
884 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | 884 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); |
885 | struct usb_host_interface *interface = intf->cur_altsetting; | 885 | struct usb_host_interface *interface = intf->cur_altsetting; |
886 | struct usb_device *dev = interface_to_usbdev (intf); | 886 | struct usb_device *dev = interface_to_usbdev (intf); |
887 | struct hid_descriptor *hdesc; | 887 | struct hid_descriptor *hdesc; |
888 | u32 quirks = 0; | 888 | u32 quirks = 0; |
889 | unsigned int rsize = 0; | 889 | unsigned int rsize = 0; |
890 | char *rdesc; | 890 | char *rdesc; |
891 | int ret, n; | 891 | int ret, n; |
892 | 892 | ||
893 | quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | 893 | quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), |
894 | le16_to_cpu(dev->descriptor.idProduct)); | 894 | le16_to_cpu(dev->descriptor.idProduct)); |
895 | 895 | ||
896 | if (quirks & HID_QUIRK_IGNORE) | 896 | if (quirks & HID_QUIRK_IGNORE) |
897 | return -ENODEV; | 897 | return -ENODEV; |
898 | 898 | ||
899 | /* Many keyboards and mice don't like to be polled for reports, | 899 | /* Many keyboards and mice don't like to be polled for reports, |
900 | * so we will always set the HID_QUIRK_NOGET flag for them. */ | 900 | * so we will always set the HID_QUIRK_NOGET flag for them. */ |
901 | if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { | 901 | if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { |
902 | if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD || | 902 | if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD || |
903 | interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) | 903 | interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) |
904 | quirks |= HID_QUIRK_NOGET; | 904 | quirks |= HID_QUIRK_NOGET; |
905 | } | 905 | } |
906 | 906 | ||
907 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && | 907 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && |
908 | (!interface->desc.bNumEndpoints || | 908 | (!interface->desc.bNumEndpoints || |
909 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { | 909 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { |
910 | dbg_hid("class descriptor not present\n"); | 910 | dbg_hid("class descriptor not present\n"); |
911 | return -ENODEV; | 911 | return -ENODEV; |
912 | } | 912 | } |
913 | 913 | ||
914 | hid->version = le16_to_cpu(hdesc->bcdHID); | 914 | hid->version = le16_to_cpu(hdesc->bcdHID); |
915 | hid->country = hdesc->bCountryCode; | 915 | hid->country = hdesc->bCountryCode; |
916 | 916 | ||
917 | for (n = 0; n < hdesc->bNumDescriptors; n++) | 917 | for (n = 0; n < hdesc->bNumDescriptors; n++) |
918 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) | 918 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) |
919 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); | 919 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); |
920 | 920 | ||
921 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { | 921 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { |
922 | dbg_hid("weird size of report descriptor (%u)\n", rsize); | 922 | dbg_hid("weird size of report descriptor (%u)\n", rsize); |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | } | 924 | } |
925 | 925 | ||
926 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { | 926 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { |
927 | dbg_hid("couldn't allocate rdesc memory\n"); | 927 | dbg_hid("couldn't allocate rdesc memory\n"); |
928 | return -ENOMEM; | 928 | return -ENOMEM; |
929 | } | 929 | } |
930 | 930 | ||
931 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); | 931 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); |
932 | 932 | ||
933 | ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, | 933 | ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, |
934 | HID_DT_REPORT, rdesc, rsize); | 934 | HID_DT_REPORT, rdesc, rsize); |
935 | if (ret < 0) { | 935 | if (ret < 0) { |
936 | dbg_hid("reading report descriptor failed\n"); | 936 | dbg_hid("reading report descriptor failed\n"); |
937 | kfree(rdesc); | 937 | kfree(rdesc); |
938 | goto err; | 938 | goto err; |
939 | } | 939 | } |
940 | 940 | ||
941 | ret = hid_parse_report(hid, rdesc, rsize); | 941 | ret = hid_parse_report(hid, rdesc, rsize); |
942 | kfree(rdesc); | 942 | kfree(rdesc); |
943 | if (ret) { | 943 | if (ret) { |
944 | dbg_hid("parsing report descriptor failed\n"); | 944 | dbg_hid("parsing report descriptor failed\n"); |
945 | goto err; | 945 | goto err; |
946 | } | 946 | } |
947 | 947 | ||
948 | hid->quirks |= quirks; | 948 | hid->quirks |= quirks; |
949 | 949 | ||
950 | return 0; | 950 | return 0; |
951 | err: | 951 | err: |
952 | return ret; | 952 | return ret; |
953 | } | 953 | } |
954 | 954 | ||
955 | static int usbhid_start(struct hid_device *hid) | 955 | static int usbhid_start(struct hid_device *hid) |
956 | { | 956 | { |
957 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | 957 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); |
958 | struct usb_host_interface *interface = intf->cur_altsetting; | 958 | struct usb_host_interface *interface = intf->cur_altsetting; |
959 | struct usb_device *dev = interface_to_usbdev(intf); | 959 | struct usb_device *dev = interface_to_usbdev(intf); |
960 | struct usbhid_device *usbhid = hid->driver_data; | 960 | struct usbhid_device *usbhid = hid->driver_data; |
961 | unsigned int n, insize = 0; | 961 | unsigned int n, insize = 0; |
962 | int ret; | 962 | int ret; |
963 | 963 | ||
964 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); | 964 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); |
965 | 965 | ||
966 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; | 966 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; |
967 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); | 967 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); |
968 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); | 968 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); |
969 | hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize); | 969 | hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize); |
970 | 970 | ||
971 | if (usbhid->bufsize > HID_MAX_BUFFER_SIZE) | 971 | if (usbhid->bufsize > HID_MAX_BUFFER_SIZE) |
972 | usbhid->bufsize = HID_MAX_BUFFER_SIZE; | 972 | usbhid->bufsize = HID_MAX_BUFFER_SIZE; |
973 | 973 | ||
974 | hid_find_max_report(hid, HID_INPUT_REPORT, &insize); | 974 | hid_find_max_report(hid, HID_INPUT_REPORT, &insize); |
975 | 975 | ||
976 | if (insize > HID_MAX_BUFFER_SIZE) | 976 | if (insize > HID_MAX_BUFFER_SIZE) |
977 | insize = HID_MAX_BUFFER_SIZE; | 977 | insize = HID_MAX_BUFFER_SIZE; |
978 | 978 | ||
979 | if (hid_alloc_buffers(dev, hid)) { | 979 | if (hid_alloc_buffers(dev, hid)) { |
980 | ret = -ENOMEM; | 980 | ret = -ENOMEM; |
981 | goto fail; | 981 | goto fail; |
982 | } | 982 | } |
983 | 983 | ||
984 | for (n = 0; n < interface->desc.bNumEndpoints; n++) { | 984 | for (n = 0; n < interface->desc.bNumEndpoints; n++) { |
985 | struct usb_endpoint_descriptor *endpoint; | 985 | struct usb_endpoint_descriptor *endpoint; |
986 | int pipe; | 986 | int pipe; |
987 | int interval; | 987 | int interval; |
988 | 988 | ||
989 | endpoint = &interface->endpoint[n].desc; | 989 | endpoint = &interface->endpoint[n].desc; |
990 | if (!usb_endpoint_xfer_int(endpoint)) | 990 | if (!usb_endpoint_xfer_int(endpoint)) |
991 | continue; | 991 | continue; |
992 | 992 | ||
993 | interval = endpoint->bInterval; | 993 | interval = endpoint->bInterval; |
994 | 994 | ||
995 | /* Some vendors give fullspeed interval on highspeed devides */ | 995 | /* Some vendors give fullspeed interval on highspeed devides */ |
996 | if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && | 996 | if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && |
997 | dev->speed == USB_SPEED_HIGH) { | 997 | dev->speed == USB_SPEED_HIGH) { |
998 | interval = fls(endpoint->bInterval*8); | 998 | interval = fls(endpoint->bInterval*8); |
999 | printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", | 999 | printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", |
1000 | hid->name, endpoint->bInterval, interval); | 1000 | hid->name, endpoint->bInterval, interval); |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | /* Change the polling interval of mice. */ | 1003 | /* Change the polling interval of mice. */ |
1004 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) | 1004 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) |
1005 | interval = hid_mousepoll_interval; | 1005 | interval = hid_mousepoll_interval; |
1006 | 1006 | ||
1007 | ret = -ENOMEM; | 1007 | ret = -ENOMEM; |
1008 | if (usb_endpoint_dir_in(endpoint)) { | 1008 | if (usb_endpoint_dir_in(endpoint)) { |
1009 | if (usbhid->urbin) | 1009 | if (usbhid->urbin) |
1010 | continue; | 1010 | continue; |
1011 | if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL))) | 1011 | if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL))) |
1012 | goto fail; | 1012 | goto fail; |
1013 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 1013 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
1014 | usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize, | 1014 | usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize, |
1015 | hid_irq_in, hid, interval); | 1015 | hid_irq_in, hid, interval); |
1016 | usbhid->urbin->transfer_dma = usbhid->inbuf_dma; | 1016 | usbhid->urbin->transfer_dma = usbhid->inbuf_dma; |
1017 | usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1017 | usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1018 | } else { | 1018 | } else { |
1019 | if (usbhid->urbout) | 1019 | if (usbhid->urbout) |
1020 | continue; | 1020 | continue; |
1021 | if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL))) | 1021 | if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL))) |
1022 | goto fail; | 1022 | goto fail; |
1023 | pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); | 1023 | pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); |
1024 | usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0, | 1024 | usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0, |
1025 | hid_irq_out, hid, interval); | 1025 | hid_irq_out, hid, interval); |
1026 | usbhid->urbout->transfer_dma = usbhid->outbuf_dma; | 1026 | usbhid->urbout->transfer_dma = usbhid->outbuf_dma; |
1027 | usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1027 | usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1028 | } | 1028 | } |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); | 1031 | usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); |
1032 | if (!usbhid->urbctrl) { | 1032 | if (!usbhid->urbctrl) { |
1033 | ret = -ENOMEM; | 1033 | ret = -ENOMEM; |
1034 | goto fail; | 1034 | goto fail; |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, | 1037 | usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, |
1038 | usbhid->ctrlbuf, 1, hid_ctrl, hid); | 1038 | usbhid->ctrlbuf, 1, hid_ctrl, hid); |
1039 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; | 1039 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
1040 | usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1040 | usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1041 | 1041 | ||
1042 | if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS)) | 1042 | if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS)) |
1043 | usbhid_init_reports(hid); | 1043 | usbhid_init_reports(hid); |
1044 | 1044 | ||
1045 | set_bit(HID_STARTED, &usbhid->iofl); | 1045 | set_bit(HID_STARTED, &usbhid->iofl); |
1046 | 1046 | ||
1047 | /* Some keyboards don't work until their LEDs have been set. | 1047 | /* Some keyboards don't work until their LEDs have been set. |
1048 | * Since BIOSes do set the LEDs, it must be safe for any device | 1048 | * Since BIOSes do set the LEDs, it must be safe for any device |
1049 | * that supports the keyboard boot protocol. | 1049 | * that supports the keyboard boot protocol. |
1050 | * In addition, enable remote wakeup by default for all keyboard | 1050 | * In addition, enable remote wakeup by default for all keyboard |
1051 | * devices supporting the boot protocol. | 1051 | * devices supporting the boot protocol. |
1052 | */ | 1052 | */ |
1053 | if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT && | 1053 | if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT && |
1054 | interface->desc.bInterfaceProtocol == | 1054 | interface->desc.bInterfaceProtocol == |
1055 | USB_INTERFACE_PROTOCOL_KEYBOARD) { | 1055 | USB_INTERFACE_PROTOCOL_KEYBOARD) { |
1056 | usbhid_set_leds(hid); | 1056 | usbhid_set_leds(hid); |
1057 | device_set_wakeup_enable(&dev->dev, 1); | 1057 | device_set_wakeup_enable(&dev->dev, 1); |
1058 | } | 1058 | } |
1059 | return 0; | 1059 | return 0; |
1060 | 1060 | ||
1061 | fail: | 1061 | fail: |
1062 | usb_free_urb(usbhid->urbin); | 1062 | usb_free_urb(usbhid->urbin); |
1063 | usb_free_urb(usbhid->urbout); | 1063 | usb_free_urb(usbhid->urbout); |
1064 | usb_free_urb(usbhid->urbctrl); | 1064 | usb_free_urb(usbhid->urbctrl); |
1065 | usbhid->urbin = NULL; | 1065 | usbhid->urbin = NULL; |
1066 | usbhid->urbout = NULL; | 1066 | usbhid->urbout = NULL; |
1067 | usbhid->urbctrl = NULL; | 1067 | usbhid->urbctrl = NULL; |
1068 | hid_free_buffers(dev, hid); | 1068 | hid_free_buffers(dev, hid); |
1069 | return ret; | 1069 | return ret; |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | static void usbhid_stop(struct hid_device *hid) | 1072 | static void usbhid_stop(struct hid_device *hid) |
1073 | { | 1073 | { |
1074 | struct usbhid_device *usbhid = hid->driver_data; | 1074 | struct usbhid_device *usbhid = hid->driver_data; |
1075 | 1075 | ||
1076 | if (WARN_ON(!usbhid)) | 1076 | if (WARN_ON(!usbhid)) |
1077 | return; | 1077 | return; |
1078 | 1078 | ||
1079 | clear_bit(HID_STARTED, &usbhid->iofl); | 1079 | clear_bit(HID_STARTED, &usbhid->iofl); |
1080 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ | 1080 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
1081 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 1081 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
1082 | spin_unlock_irq(&usbhid->lock); | 1082 | spin_unlock_irq(&usbhid->lock); |
1083 | usb_kill_urb(usbhid->urbin); | 1083 | usb_kill_urb(usbhid->urbin); |
1084 | usb_kill_urb(usbhid->urbout); | 1084 | usb_kill_urb(usbhid->urbout); |
1085 | usb_kill_urb(usbhid->urbctrl); | 1085 | usb_kill_urb(usbhid->urbctrl); |
1086 | 1086 | ||
1087 | hid_cancel_delayed_stuff(usbhid); | 1087 | hid_cancel_delayed_stuff(usbhid); |
1088 | 1088 | ||
1089 | hid->claimed = 0; | 1089 | hid->claimed = 0; |
1090 | 1090 | ||
1091 | usb_free_urb(usbhid->urbin); | 1091 | usb_free_urb(usbhid->urbin); |
1092 | usb_free_urb(usbhid->urbctrl); | 1092 | usb_free_urb(usbhid->urbctrl); |
1093 | usb_free_urb(usbhid->urbout); | 1093 | usb_free_urb(usbhid->urbout); |
1094 | usbhid->urbin = NULL; /* don't mess up next start */ | 1094 | usbhid->urbin = NULL; /* don't mess up next start */ |
1095 | usbhid->urbctrl = NULL; | 1095 | usbhid->urbctrl = NULL; |
1096 | usbhid->urbout = NULL; | 1096 | usbhid->urbout = NULL; |
1097 | 1097 | ||
1098 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 1098 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
1099 | } | 1099 | } |
1100 | 1100 | ||
1101 | static int usbhid_power(struct hid_device *hid, int lvl) | 1101 | static int usbhid_power(struct hid_device *hid, int lvl) |
1102 | { | 1102 | { |
1103 | int r = 0; | 1103 | int r = 0; |
1104 | 1104 | ||
1105 | switch (lvl) { | 1105 | switch (lvl) { |
1106 | case PM_HINT_FULLON: | 1106 | case PM_HINT_FULLON: |
1107 | r = usbhid_get_power(hid); | 1107 | r = usbhid_get_power(hid); |
1108 | break; | 1108 | break; |
1109 | case PM_HINT_NORMAL: | 1109 | case PM_HINT_NORMAL: |
1110 | usbhid_put_power(hid); | 1110 | usbhid_put_power(hid); |
1111 | break; | 1111 | break; |
1112 | } | 1112 | } |
1113 | return r; | 1113 | return r; |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | static struct hid_ll_driver usb_hid_driver = { | 1116 | static struct hid_ll_driver usb_hid_driver = { |
1117 | .parse = usbhid_parse, | 1117 | .parse = usbhid_parse, |
1118 | .start = usbhid_start, | 1118 | .start = usbhid_start, |
1119 | .stop = usbhid_stop, | 1119 | .stop = usbhid_stop, |
1120 | .open = usbhid_open, | 1120 | .open = usbhid_open, |
1121 | .close = usbhid_close, | 1121 | .close = usbhid_close, |
1122 | .power = usbhid_power, | 1122 | .power = usbhid_power, |
1123 | .hidinput_input_event = usb_hidinput_input_event, | 1123 | .hidinput_input_event = usb_hidinput_input_event, |
1124 | }; | 1124 | }; |
1125 | 1125 | ||
1126 | static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1126 | static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
1127 | { | 1127 | { |
1128 | struct usb_host_interface *interface = intf->cur_altsetting; | 1128 | struct usb_host_interface *interface = intf->cur_altsetting; |
1129 | struct usb_device *dev = interface_to_usbdev(intf); | 1129 | struct usb_device *dev = interface_to_usbdev(intf); |
1130 | struct usbhid_device *usbhid; | 1130 | struct usbhid_device *usbhid; |
1131 | struct hid_device *hid; | 1131 | struct hid_device *hid; |
1132 | unsigned int n, has_in = 0; | 1132 | unsigned int n, has_in = 0; |
1133 | size_t len; | 1133 | size_t len; |
1134 | int ret; | 1134 | int ret; |
1135 | 1135 | ||
1136 | dbg_hid("HID probe called for ifnum %d\n", | 1136 | dbg_hid("HID probe called for ifnum %d\n", |
1137 | intf->altsetting->desc.bInterfaceNumber); | 1137 | intf->altsetting->desc.bInterfaceNumber); |
1138 | 1138 | ||
1139 | for (n = 0; n < interface->desc.bNumEndpoints; n++) | 1139 | for (n = 0; n < interface->desc.bNumEndpoints; n++) |
1140 | if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) | 1140 | if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) |
1141 | has_in++; | 1141 | has_in++; |
1142 | if (!has_in) { | 1142 | if (!has_in) { |
1143 | dev_err(&intf->dev, "couldn't find an input interrupt " | 1143 | dev_err(&intf->dev, "couldn't find an input interrupt " |
1144 | "endpoint\n"); | 1144 | "endpoint\n"); |
1145 | return -ENODEV; | 1145 | return -ENODEV; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | hid = hid_allocate_device(); | 1148 | hid = hid_allocate_device(); |
1149 | if (IS_ERR(hid)) | 1149 | if (IS_ERR(hid)) |
1150 | return PTR_ERR(hid); | 1150 | return PTR_ERR(hid); |
1151 | 1151 | ||
1152 | usb_set_intfdata(intf, hid); | 1152 | usb_set_intfdata(intf, hid); |
1153 | hid->ll_driver = &usb_hid_driver; | 1153 | hid->ll_driver = &usb_hid_driver; |
1154 | hid->hid_output_raw_report = usbhid_output_raw_report; | 1154 | hid->hid_output_raw_report = usbhid_output_raw_report; |
1155 | hid->ff_init = hid_pidff_init; | 1155 | hid->ff_init = hid_pidff_init; |
1156 | #ifdef CONFIG_USB_HIDDEV | 1156 | #ifdef CONFIG_USB_HIDDEV |
1157 | hid->hiddev_connect = hiddev_connect; | 1157 | hid->hiddev_connect = hiddev_connect; |
1158 | hid->hiddev_disconnect = hiddev_disconnect; | 1158 | hid->hiddev_disconnect = hiddev_disconnect; |
1159 | hid->hiddev_hid_event = hiddev_hid_event; | 1159 | hid->hiddev_hid_event = hiddev_hid_event; |
1160 | hid->hiddev_report_event = hiddev_report_event; | 1160 | hid->hiddev_report_event = hiddev_report_event; |
1161 | #endif | 1161 | #endif |
1162 | hid->dev.parent = &intf->dev; | 1162 | hid->dev.parent = &intf->dev; |
1163 | hid->bus = BUS_USB; | 1163 | hid->bus = BUS_USB; |
1164 | hid->vendor = le16_to_cpu(dev->descriptor.idVendor); | 1164 | hid->vendor = le16_to_cpu(dev->descriptor.idVendor); |
1165 | hid->product = le16_to_cpu(dev->descriptor.idProduct); | 1165 | hid->product = le16_to_cpu(dev->descriptor.idProduct); |
1166 | hid->name[0] = 0; | 1166 | hid->name[0] = 0; |
1167 | hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product); | 1167 | hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product); |
1168 | if (intf->cur_altsetting->desc.bInterfaceProtocol == | 1168 | if (intf->cur_altsetting->desc.bInterfaceProtocol == |
1169 | USB_INTERFACE_PROTOCOL_MOUSE) | 1169 | USB_INTERFACE_PROTOCOL_MOUSE) |
1170 | hid->type = HID_TYPE_USBMOUSE; | 1170 | hid->type = HID_TYPE_USBMOUSE; |
1171 | 1171 | ||
1172 | if (dev->manufacturer) | 1172 | if (dev->manufacturer) |
1173 | strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); | 1173 | strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); |
1174 | 1174 | ||
1175 | if (dev->product) { | 1175 | if (dev->product) { |
1176 | if (dev->manufacturer) | 1176 | if (dev->manufacturer) |
1177 | strlcat(hid->name, " ", sizeof(hid->name)); | 1177 | strlcat(hid->name, " ", sizeof(hid->name)); |
1178 | strlcat(hid->name, dev->product, sizeof(hid->name)); | 1178 | strlcat(hid->name, dev->product, sizeof(hid->name)); |
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | if (!strlen(hid->name)) | 1181 | if (!strlen(hid->name)) |
1182 | snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", | 1182 | snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", |
1183 | le16_to_cpu(dev->descriptor.idVendor), | 1183 | le16_to_cpu(dev->descriptor.idVendor), |
1184 | le16_to_cpu(dev->descriptor.idProduct)); | 1184 | le16_to_cpu(dev->descriptor.idProduct)); |
1185 | 1185 | ||
1186 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); | 1186 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); |
1187 | strlcat(hid->phys, "/input", sizeof(hid->phys)); | 1187 | strlcat(hid->phys, "/input", sizeof(hid->phys)); |
1188 | len = strlen(hid->phys); | 1188 | len = strlen(hid->phys); |
1189 | if (len < sizeof(hid->phys) - 1) | 1189 | if (len < sizeof(hid->phys) - 1) |
1190 | snprintf(hid->phys + len, sizeof(hid->phys) - len, | 1190 | snprintf(hid->phys + len, sizeof(hid->phys) - len, |
1191 | "%d", intf->altsetting[0].desc.bInterfaceNumber); | 1191 | "%d", intf->altsetting[0].desc.bInterfaceNumber); |
1192 | 1192 | ||
1193 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) | 1193 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) |
1194 | hid->uniq[0] = 0; | 1194 | hid->uniq[0] = 0; |
1195 | 1195 | ||
1196 | usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL); | 1196 | usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL); |
1197 | if (usbhid == NULL) { | 1197 | if (usbhid == NULL) { |
1198 | ret = -ENOMEM; | 1198 | ret = -ENOMEM; |
1199 | goto err; | 1199 | goto err; |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | hid->driver_data = usbhid; | 1202 | hid->driver_data = usbhid; |
1203 | usbhid->hid = hid; | 1203 | usbhid->hid = hid; |
1204 | usbhid->intf = intf; | 1204 | usbhid->intf = intf; |
1205 | usbhid->ifnum = interface->desc.bInterfaceNumber; | 1205 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
1206 | 1206 | ||
1207 | init_waitqueue_head(&usbhid->wait); | 1207 | init_waitqueue_head(&usbhid->wait); |
1208 | INIT_WORK(&usbhid->reset_work, hid_reset); | 1208 | INIT_WORK(&usbhid->reset_work, hid_reset); |
1209 | INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); | 1209 | INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); |
1210 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 1210 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
1211 | spin_lock_init(&usbhid->lock); | 1211 | spin_lock_init(&usbhid->lock); |
1212 | 1212 | ||
1213 | ret = hid_add_device(hid); | 1213 | ret = hid_add_device(hid); |
1214 | if (ret) { | 1214 | if (ret) { |
1215 | if (ret != -ENODEV) | 1215 | if (ret != -ENODEV) |
1216 | dev_err(&intf->dev, "can't add hid device: %d\n", ret); | 1216 | dev_err(&intf->dev, "can't add hid device: %d\n", ret); |
1217 | goto err_free; | 1217 | goto err_free; |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | return 0; | 1220 | return 0; |
1221 | err_free: | 1221 | err_free: |
1222 | kfree(usbhid); | 1222 | kfree(usbhid); |
1223 | err: | 1223 | err: |
1224 | hid_destroy_device(hid); | 1224 | hid_destroy_device(hid); |
1225 | return ret; | 1225 | return ret; |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | static void usbhid_disconnect(struct usb_interface *intf) | 1228 | static void usbhid_disconnect(struct usb_interface *intf) |
1229 | { | 1229 | { |
1230 | struct hid_device *hid = usb_get_intfdata(intf); | 1230 | struct hid_device *hid = usb_get_intfdata(intf); |
1231 | struct usbhid_device *usbhid; | 1231 | struct usbhid_device *usbhid; |
1232 | 1232 | ||
1233 | if (WARN_ON(!hid)) | 1233 | if (WARN_ON(!hid)) |
1234 | return; | 1234 | return; |
1235 | 1235 | ||
1236 | usbhid = hid->driver_data; | 1236 | usbhid = hid->driver_data; |
1237 | hid_destroy_device(hid); | 1237 | hid_destroy_device(hid); |
1238 | kfree(usbhid); | 1238 | kfree(usbhid); |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) | 1241 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) |
1242 | { | 1242 | { |
1243 | del_timer_sync(&usbhid->io_retry); | 1243 | del_timer_sync(&usbhid->io_retry); |
1244 | cancel_work_sync(&usbhid->restart_work); | 1244 | cancel_work_sync(&usbhid->restart_work); |
1245 | cancel_work_sync(&usbhid->reset_work); | 1245 | cancel_work_sync(&usbhid->reset_work); |
1246 | } | 1246 | } |
1247 | 1247 | ||
1248 | static void hid_cease_io(struct usbhid_device *usbhid) | 1248 | static void hid_cease_io(struct usbhid_device *usbhid) |
1249 | { | 1249 | { |
1250 | del_timer(&usbhid->io_retry); | 1250 | del_timer(&usbhid->io_retry); |
1251 | usb_kill_urb(usbhid->urbin); | 1251 | usb_kill_urb(usbhid->urbin); |
1252 | usb_kill_urb(usbhid->urbctrl); | 1252 | usb_kill_urb(usbhid->urbctrl); |
1253 | usb_kill_urb(usbhid->urbout); | 1253 | usb_kill_urb(usbhid->urbout); |
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | /* Treat USB reset pretty much the same as suspend/resume */ | 1256 | /* Treat USB reset pretty much the same as suspend/resume */ |
1257 | static int hid_pre_reset(struct usb_interface *intf) | 1257 | static int hid_pre_reset(struct usb_interface *intf) |
1258 | { | 1258 | { |
1259 | struct hid_device *hid = usb_get_intfdata(intf); | 1259 | struct hid_device *hid = usb_get_intfdata(intf); |
1260 | struct usbhid_device *usbhid = hid->driver_data; | 1260 | struct usbhid_device *usbhid = hid->driver_data; |
1261 | 1261 | ||
1262 | spin_lock_irq(&usbhid->lock); | 1262 | spin_lock_irq(&usbhid->lock); |
1263 | set_bit(HID_RESET_PENDING, &usbhid->iofl); | 1263 | set_bit(HID_RESET_PENDING, &usbhid->iofl); |
1264 | spin_unlock_irq(&usbhid->lock); | 1264 | spin_unlock_irq(&usbhid->lock); |
1265 | cancel_work_sync(&usbhid->restart_work); | 1265 | cancel_work_sync(&usbhid->restart_work); |
1266 | hid_cease_io(usbhid); | 1266 | hid_cease_io(usbhid); |
1267 | 1267 | ||
1268 | return 0; | 1268 | return 0; |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | /* Same routine used for post_reset and reset_resume */ | 1271 | /* Same routine used for post_reset and reset_resume */ |
1272 | static int hid_post_reset(struct usb_interface *intf) | 1272 | static int hid_post_reset(struct usb_interface *intf) |
1273 | { | 1273 | { |
1274 | struct usb_device *dev = interface_to_usbdev (intf); | 1274 | struct usb_device *dev = interface_to_usbdev (intf); |
1275 | struct hid_device *hid = usb_get_intfdata(intf); | 1275 | struct hid_device *hid = usb_get_intfdata(intf); |
1276 | struct usbhid_device *usbhid = hid->driver_data; | 1276 | struct usbhid_device *usbhid = hid->driver_data; |
1277 | int status; | 1277 | int status; |
1278 | 1278 | ||
1279 | spin_lock_irq(&usbhid->lock); | 1279 | spin_lock_irq(&usbhid->lock); |
1280 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 1280 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
1281 | spin_unlock_irq(&usbhid->lock); | 1281 | spin_unlock_irq(&usbhid->lock); |
1282 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); | 1282 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); |
1283 | status = hid_start_in(hid); | 1283 | status = hid_start_in(hid); |
1284 | if (status < 0) | 1284 | if (status < 0) |
1285 | hid_io_error(hid); | 1285 | hid_io_error(hid); |
1286 | usbhid_restart_queues(usbhid); | 1286 | usbhid_restart_queues(usbhid); |
1287 | 1287 | ||
1288 | return 0; | 1288 | return 0; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | int usbhid_get_power(struct hid_device *hid) | 1291 | int usbhid_get_power(struct hid_device *hid) |
1292 | { | 1292 | { |
1293 | struct usbhid_device *usbhid = hid->driver_data; | 1293 | struct usbhid_device *usbhid = hid->driver_data; |
1294 | 1294 | ||
1295 | return usb_autopm_get_interface(usbhid->intf); | 1295 | return usb_autopm_get_interface(usbhid->intf); |
1296 | } | 1296 | } |
1297 | 1297 | ||
1298 | void usbhid_put_power(struct hid_device *hid) | 1298 | void usbhid_put_power(struct hid_device *hid) |
1299 | { | 1299 | { |
1300 | struct usbhid_device *usbhid = hid->driver_data; | 1300 | struct usbhid_device *usbhid = hid->driver_data; |
1301 | 1301 | ||
1302 | usb_autopm_put_interface(usbhid->intf); | 1302 | usb_autopm_put_interface(usbhid->intf); |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | 1305 | ||
1306 | #ifdef CONFIG_PM | 1306 | #ifdef CONFIG_PM |
1307 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1307 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
1308 | { | 1308 | { |
1309 | struct hid_device *hid = usb_get_intfdata(intf); | 1309 | struct hid_device *hid = usb_get_intfdata(intf); |
1310 | struct usbhid_device *usbhid = hid->driver_data; | 1310 | struct usbhid_device *usbhid = hid->driver_data; |
1311 | int status; | 1311 | int status; |
1312 | 1312 | ||
1313 | if (message.event & PM_EVENT_AUTO) { | 1313 | if (message.event & PM_EVENT_AUTO) { |
1314 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ | 1314 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
1315 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) | 1315 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) |
1316 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) | 1316 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) |
1317 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) | 1317 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) |
1318 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) | 1318 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) |
1319 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) | 1319 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) |
1320 | && (!usbhid->ledcount || ignoreled)) | 1320 | && (!usbhid->ledcount || ignoreled)) |
1321 | { | 1321 | { |
1322 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); | 1322 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1323 | spin_unlock_irq(&usbhid->lock); | 1323 | spin_unlock_irq(&usbhid->lock); |
1324 | if (hid->driver && hid->driver->suspend) { | 1324 | if (hid->driver && hid->driver->suspend) { |
1325 | status = hid->driver->suspend(hid, message); | 1325 | status = hid->driver->suspend(hid, message); |
1326 | if (status < 0) | 1326 | if (status < 0) |
1327 | return status; | 1327 | return status; |
1328 | } | 1328 | } |
1329 | } else { | 1329 | } else { |
1330 | usbhid_mark_busy(usbhid); | 1330 | usbhid_mark_busy(usbhid); |
1331 | spin_unlock_irq(&usbhid->lock); | 1331 | spin_unlock_irq(&usbhid->lock); |
1332 | return -EBUSY; | 1332 | return -EBUSY; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | } else { | 1335 | } else { |
1336 | if (hid->driver && hid->driver->suspend) { | 1336 | if (hid->driver && hid->driver->suspend) { |
1337 | status = hid->driver->suspend(hid, message); | 1337 | status = hid->driver->suspend(hid, message); |
1338 | if (status < 0) | 1338 | if (status < 0) |
1339 | return status; | 1339 | return status; |
1340 | } | 1340 | } |
1341 | spin_lock_irq(&usbhid->lock); | 1341 | spin_lock_irq(&usbhid->lock); |
1342 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); | 1342 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1343 | spin_unlock_irq(&usbhid->lock); | 1343 | spin_unlock_irq(&usbhid->lock); |
1344 | if (usbhid_wait_io(hid) < 0) | 1344 | if (usbhid_wait_io(hid) < 0) |
1345 | return -EIO; | 1345 | return -EIO; |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | if (!ignoreled && (message.event & PM_EVENT_AUTO)) { | 1348 | if (!ignoreled && (message.event & PM_EVENT_AUTO)) { |
1349 | spin_lock_irq(&usbhid->lock); | 1349 | spin_lock_irq(&usbhid->lock); |
1350 | if (test_bit(HID_LED_ON, &usbhid->iofl)) { | 1350 | if (test_bit(HID_LED_ON, &usbhid->iofl)) { |
1351 | spin_unlock_irq(&usbhid->lock); | 1351 | spin_unlock_irq(&usbhid->lock); |
1352 | usbhid_mark_busy(usbhid); | 1352 | usbhid_mark_busy(usbhid); |
1353 | return -EBUSY; | 1353 | return -EBUSY; |
1354 | } | 1354 | } |
1355 | spin_unlock_irq(&usbhid->lock); | 1355 | spin_unlock_irq(&usbhid->lock); |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | hid_cancel_delayed_stuff(usbhid); | 1358 | hid_cancel_delayed_stuff(usbhid); |
1359 | hid_cease_io(usbhid); | 1359 | hid_cease_io(usbhid); |
1360 | 1360 | ||
1361 | if ((message.event & PM_EVENT_AUTO) && | 1361 | if ((message.event & PM_EVENT_AUTO) && |
1362 | test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { | 1362 | test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { |
1363 | /* lost race against keypresses */ | 1363 | /* lost race against keypresses */ |
1364 | status = hid_start_in(hid); | 1364 | status = hid_start_in(hid); |
1365 | if (status < 0) | 1365 | if (status < 0) |
1366 | hid_io_error(hid); | 1366 | hid_io_error(hid); |
1367 | usbhid_mark_busy(usbhid); | 1367 | usbhid_mark_busy(usbhid); |
1368 | return -EBUSY; | 1368 | return -EBUSY; |
1369 | } | 1369 | } |
1370 | dev_dbg(&intf->dev, "suspend\n"); | 1370 | dev_dbg(&intf->dev, "suspend\n"); |
1371 | return 0; | 1371 | return 0; |
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | static int hid_resume(struct usb_interface *intf) | 1374 | static int hid_resume(struct usb_interface *intf) |
1375 | { | 1375 | { |
1376 | struct hid_device *hid = usb_get_intfdata (intf); | 1376 | struct hid_device *hid = usb_get_intfdata (intf); |
1377 | struct usbhid_device *usbhid = hid->driver_data; | 1377 | struct usbhid_device *usbhid = hid->driver_data; |
1378 | int status; | 1378 | int status; |
1379 | 1379 | ||
1380 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | 1380 | if (!test_bit(HID_STARTED, &usbhid->iofl)) |
1381 | return 0; | 1381 | return 0; |
1382 | 1382 | ||
1383 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); | 1383 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1384 | usbhid_mark_busy(usbhid); | 1384 | usbhid_mark_busy(usbhid); |
1385 | 1385 | ||
1386 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || | 1386 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || |
1387 | test_bit(HID_RESET_PENDING, &usbhid->iofl)) | 1387 | test_bit(HID_RESET_PENDING, &usbhid->iofl)) |
1388 | schedule_work(&usbhid->reset_work); | 1388 | schedule_work(&usbhid->reset_work); |
1389 | usbhid->retry_delay = 0; | 1389 | usbhid->retry_delay = 0; |
1390 | status = hid_start_in(hid); | 1390 | status = hid_start_in(hid); |
1391 | if (status < 0) | 1391 | if (status < 0) |
1392 | hid_io_error(hid); | 1392 | hid_io_error(hid); |
1393 | usbhid_restart_queues(usbhid); | 1393 | usbhid_restart_queues(usbhid); |
1394 | 1394 | ||
1395 | if (status >= 0 && hid->driver && hid->driver->resume) { | 1395 | if (status >= 0 && hid->driver && hid->driver->resume) { |
1396 | int ret = hid->driver->resume(hid); | 1396 | int ret = hid->driver->resume(hid); |
1397 | if (ret < 0) | 1397 | if (ret < 0) |
1398 | status = ret; | 1398 | status = ret; |
1399 | } | 1399 | } |
1400 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1400 | dev_dbg(&intf->dev, "resume status %d\n", status); |
1401 | return 0; | 1401 | return 0; |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | static int hid_reset_resume(struct usb_interface *intf) | 1404 | static int hid_reset_resume(struct usb_interface *intf) |
1405 | { | 1405 | { |
1406 | struct hid_device *hid = usb_get_intfdata(intf); | 1406 | struct hid_device *hid = usb_get_intfdata(intf); |
1407 | struct usbhid_device *usbhid = hid->driver_data; | 1407 | struct usbhid_device *usbhid = hid->driver_data; |
1408 | int status; | 1408 | int status; |
1409 | 1409 | ||
1410 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); | 1410 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1411 | status = hid_post_reset(intf); | 1411 | status = hid_post_reset(intf); |
1412 | if (status >= 0 && hid->driver && hid->driver->reset_resume) { | 1412 | if (status >= 0 && hid->driver && hid->driver->reset_resume) { |
1413 | int ret = hid->driver->reset_resume(hid); | 1413 | int ret = hid->driver->reset_resume(hid); |
1414 | if (ret < 0) | 1414 | if (ret < 0) |
1415 | status = ret; | 1415 | status = ret; |
1416 | } | 1416 | } |
1417 | return status; | 1417 | return status; |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | #endif /* CONFIG_PM */ | 1420 | #endif /* CONFIG_PM */ |
1421 | 1421 | ||
1422 | static const struct usb_device_id hid_usb_ids[] = { | 1422 | static const struct usb_device_id hid_usb_ids[] = { |
1423 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, | 1423 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
1424 | .bInterfaceClass = USB_INTERFACE_CLASS_HID }, | 1424 | .bInterfaceClass = USB_INTERFACE_CLASS_HID }, |
1425 | { } /* Terminating entry */ | 1425 | { } /* Terminating entry */ |
1426 | }; | 1426 | }; |
1427 | 1427 | ||
1428 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); | 1428 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); |
1429 | 1429 | ||
1430 | static struct usb_driver hid_driver = { | 1430 | static struct usb_driver hid_driver = { |
1431 | .name = "usbhid", | 1431 | .name = "usbhid", |
1432 | .probe = usbhid_probe, | 1432 | .probe = usbhid_probe, |
1433 | .disconnect = usbhid_disconnect, | 1433 | .disconnect = usbhid_disconnect, |
1434 | #ifdef CONFIG_PM | 1434 | #ifdef CONFIG_PM |
1435 | .suspend = hid_suspend, | 1435 | .suspend = hid_suspend, |
1436 | .resume = hid_resume, | 1436 | .resume = hid_resume, |
1437 | .reset_resume = hid_reset_resume, | 1437 | .reset_resume = hid_reset_resume, |
1438 | #endif | 1438 | #endif |
1439 | .pre_reset = hid_pre_reset, | 1439 | .pre_reset = hid_pre_reset, |
1440 | .post_reset = hid_post_reset, | 1440 | .post_reset = hid_post_reset, |
1441 | .id_table = hid_usb_ids, | 1441 | .id_table = hid_usb_ids, |
1442 | .supports_autosuspend = 1, | 1442 | .supports_autosuspend = 1, |
1443 | }; | 1443 | }; |
1444 | 1444 | ||
1445 | static const struct hid_device_id hid_usb_table[] = { | 1445 | static const struct hid_device_id hid_usb_table[] = { |
1446 | { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | 1446 | { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, |
1447 | { } | 1447 | { } |
1448 | }; | 1448 | }; |
1449 | 1449 | ||
1450 | struct usb_interface *usbhid_find_interface(int minor) | 1450 | struct usb_interface *usbhid_find_interface(int minor) |
1451 | { | 1451 | { |
1452 | return usb_find_interface(&hid_driver, minor); | 1452 | return usb_find_interface(&hid_driver, minor); |
1453 | } | 1453 | } |
1454 | 1454 | ||
1455 | static struct hid_driver hid_usb_driver = { | 1455 | static struct hid_driver hid_usb_driver = { |
1456 | .name = "generic-usb", | 1456 | .name = "generic-usb", |
1457 | .id_table = hid_usb_table, | 1457 | .id_table = hid_usb_table, |
1458 | }; | 1458 | }; |
1459 | 1459 | ||
1460 | static int __init hid_init(void) | 1460 | static int __init hid_init(void) |
1461 | { | 1461 | { |
1462 | int retval = -ENOMEM; | 1462 | int retval = -ENOMEM; |
1463 | 1463 | ||
1464 | resumption_waker = create_freezeable_workqueue("usbhid_resumer"); | 1464 | resumption_waker = create_freezeable_workqueue("usbhid_resumer"); |
1465 | if (!resumption_waker) | 1465 | if (!resumption_waker) |
1466 | goto no_queue; | 1466 | goto no_queue; |
1467 | retval = hid_register_driver(&hid_usb_driver); | 1467 | retval = hid_register_driver(&hid_usb_driver); |
1468 | if (retval) | 1468 | if (retval) |
1469 | goto hid_register_fail; | 1469 | goto hid_register_fail; |
1470 | retval = usbhid_quirks_init(quirks_param); | 1470 | retval = usbhid_quirks_init(quirks_param); |
1471 | if (retval) | 1471 | if (retval) |
1472 | goto usbhid_quirks_init_fail; | 1472 | goto usbhid_quirks_init_fail; |
1473 | retval = usb_register(&hid_driver); | 1473 | retval = usb_register(&hid_driver); |
1474 | if (retval) | 1474 | if (retval) |
1475 | goto usb_register_fail; | 1475 | goto usb_register_fail; |
1476 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); | 1476 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); |
1477 | 1477 | ||
1478 | return 0; | 1478 | return 0; |
1479 | usb_register_fail: | 1479 | usb_register_fail: |
1480 | usbhid_quirks_exit(); | 1480 | usbhid_quirks_exit(); |
1481 | usbhid_quirks_init_fail: | 1481 | usbhid_quirks_init_fail: |
1482 | hid_unregister_driver(&hid_usb_driver); | 1482 | hid_unregister_driver(&hid_usb_driver); |
1483 | hid_register_fail: | 1483 | hid_register_fail: |
1484 | destroy_workqueue(resumption_waker); | 1484 | destroy_workqueue(resumption_waker); |
1485 | no_queue: | 1485 | no_queue: |
1486 | return retval; | 1486 | return retval; |
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | static void __exit hid_exit(void) | 1489 | static void __exit hid_exit(void) |
1490 | { | 1490 | { |
1491 | usb_deregister(&hid_driver); | 1491 | usb_deregister(&hid_driver); |
1492 | usbhid_quirks_exit(); | 1492 | usbhid_quirks_exit(); |
1493 | hid_unregister_driver(&hid_usb_driver); | 1493 | hid_unregister_driver(&hid_usb_driver); |
1494 | destroy_workqueue(resumption_waker); | 1494 | destroy_workqueue(resumption_waker); |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | module_init(hid_init); | 1497 | module_init(hid_init); |
1498 | module_exit(hid_exit); | 1498 | module_exit(hid_exit); |
1499 | 1499 | ||
1500 | MODULE_AUTHOR("Andreas Gal"); | 1500 | MODULE_AUTHOR("Andreas Gal"); |
1501 | MODULE_AUTHOR("Vojtech Pavlik"); | 1501 | MODULE_AUTHOR("Vojtech Pavlik"); |
1502 | MODULE_AUTHOR("Jiri Kosina"); | 1502 | MODULE_AUTHOR("Jiri Kosina"); |
1503 | MODULE_DESCRIPTION(DRIVER_DESC); | 1503 | MODULE_DESCRIPTION(DRIVER_DESC); |
1504 | MODULE_LICENSE(DRIVER_LICENSE); | 1504 | MODULE_LICENSE(DRIVER_LICENSE); |
1505 | 1505 |
drivers/hid/usbhid/hid-quirks.c
1 | /* | 1 | /* |
2 | * USB HID quirks support for Linux | 2 | * USB HID quirks support for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006-2007 Jiri Kosina | 7 | * Copyright (c) 2006-2007 Jiri Kosina |
8 | * Copyright (c) 2007 Paul Walmsley | 8 | * Copyright (c) 2007 Paul Walmsley |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 14 | * Software Foundation; either version 2 of the License, or (at your option) |
15 | * any later version. | 15 | * any later version. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/hid.h> | 18 | #include <linux/hid.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include "../hid-ids.h" | 21 | #include "../hid-ids.h" |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Alphabetically sorted blacklist by quirk type. | 24 | * Alphabetically sorted blacklist by quirk type. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | static const struct hid_blacklist { | 27 | static const struct hid_blacklist { |
28 | __u16 idVendor; | 28 | __u16 idVendor; |
29 | __u16 idProduct; | 29 | __u16 idProduct; |
30 | __u32 quirks; | 30 | __u32 quirks; |
31 | } hid_blacklist[] = { | 31 | } hid_blacklist[] = { |
32 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, | 32 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, |
33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, | 33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, |
34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |
35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, | 36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, |
37 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, | ||
38 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, | 37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, |
39 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, | 38 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, |
40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
41 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
42 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 41 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
43 | { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD }, | 42 | { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD }, |
44 | { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, | 43 | { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, |
45 | { USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT}, | 44 | { USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT}, |
46 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, | 45 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, |
47 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, | 46 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, |
48 | 47 | ||
49 | { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, | 48 | { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, |
50 | 49 | ||
51 | { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, | 50 | { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, |
52 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 51 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
53 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 52 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
54 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, | 53 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, |
55 | 54 | ||
56 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 55 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
57 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 56 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 57 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, | 58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, |
60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, | 59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, |
61 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, | 60 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, |
62 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, | 61 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, |
63 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET }, | 62 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET }, |
64 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET }, | 63 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET }, |
65 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, | 64 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, |
66 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | 65 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
67 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 66 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
68 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 67 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
69 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 68 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
70 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, | 69 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
73 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 72 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
74 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | 73 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, |
75 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, | 74 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, |
76 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 75 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
77 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 76 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
78 | 77 | ||
79 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 78 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
80 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 79 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
81 | 80 | ||
82 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, | 81 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, |
83 | 82 | ||
84 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, | 83 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, |
85 | 84 | ||
86 | { 0, 0 } | 85 | { 0, 0 } |
87 | }; | 86 | }; |
88 | 87 | ||
89 | /* Dynamic HID quirks list - specified at runtime */ | 88 | /* Dynamic HID quirks list - specified at runtime */ |
90 | struct quirks_list_struct { | 89 | struct quirks_list_struct { |
91 | struct hid_blacklist hid_bl_item; | 90 | struct hid_blacklist hid_bl_item; |
92 | struct list_head node; | 91 | struct list_head node; |
93 | }; | 92 | }; |
94 | 93 | ||
95 | static LIST_HEAD(dquirks_list); | 94 | static LIST_HEAD(dquirks_list); |
96 | static DECLARE_RWSEM(dquirks_rwsem); | 95 | static DECLARE_RWSEM(dquirks_rwsem); |
97 | 96 | ||
98 | /* Runtime ("dynamic") quirks manipulation functions */ | 97 | /* Runtime ("dynamic") quirks manipulation functions */ |
99 | 98 | ||
100 | /** | 99 | /** |
101 | * usbhid_exists_dquirk: find any dynamic quirks for a USB HID device | 100 | * usbhid_exists_dquirk: find any dynamic quirks for a USB HID device |
102 | * @idVendor: the 16-bit USB vendor ID, in native byteorder | 101 | * @idVendor: the 16-bit USB vendor ID, in native byteorder |
103 | * @idProduct: the 16-bit USB product ID, in native byteorder | 102 | * @idProduct: the 16-bit USB product ID, in native byteorder |
104 | * | 103 | * |
105 | * Description: | 104 | * Description: |
106 | * Scans dquirks_list for a matching dynamic quirk and returns | 105 | * Scans dquirks_list for a matching dynamic quirk and returns |
107 | * the pointer to the relevant struct hid_blacklist if found. | 106 | * the pointer to the relevant struct hid_blacklist if found. |
108 | * Must be called with a read lock held on dquirks_rwsem. | 107 | * Must be called with a read lock held on dquirks_rwsem. |
109 | * | 108 | * |
110 | * Returns: NULL if no quirk found, struct hid_blacklist * if found. | 109 | * Returns: NULL if no quirk found, struct hid_blacklist * if found. |
111 | */ | 110 | */ |
112 | static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor, | 111 | static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor, |
113 | const u16 idProduct) | 112 | const u16 idProduct) |
114 | { | 113 | { |
115 | struct quirks_list_struct *q; | 114 | struct quirks_list_struct *q; |
116 | struct hid_blacklist *bl_entry = NULL; | 115 | struct hid_blacklist *bl_entry = NULL; |
117 | 116 | ||
118 | list_for_each_entry(q, &dquirks_list, node) { | 117 | list_for_each_entry(q, &dquirks_list, node) { |
119 | if (q->hid_bl_item.idVendor == idVendor && | 118 | if (q->hid_bl_item.idVendor == idVendor && |
120 | q->hid_bl_item.idProduct == idProduct) { | 119 | q->hid_bl_item.idProduct == idProduct) { |
121 | bl_entry = &q->hid_bl_item; | 120 | bl_entry = &q->hid_bl_item; |
122 | break; | 121 | break; |
123 | } | 122 | } |
124 | } | 123 | } |
125 | 124 | ||
126 | if (bl_entry != NULL) | 125 | if (bl_entry != NULL) |
127 | dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", | 126 | dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", |
128 | bl_entry->quirks, bl_entry->idVendor, | 127 | bl_entry->quirks, bl_entry->idVendor, |
129 | bl_entry->idProduct); | 128 | bl_entry->idProduct); |
130 | 129 | ||
131 | return bl_entry; | 130 | return bl_entry; |
132 | } | 131 | } |
133 | 132 | ||
134 | 133 | ||
135 | /** | 134 | /** |
136 | * usbhid_modify_dquirk: add/replace a HID quirk | 135 | * usbhid_modify_dquirk: add/replace a HID quirk |
137 | * @idVendor: the 16-bit USB vendor ID, in native byteorder | 136 | * @idVendor: the 16-bit USB vendor ID, in native byteorder |
138 | * @idProduct: the 16-bit USB product ID, in native byteorder | 137 | * @idProduct: the 16-bit USB product ID, in native byteorder |
139 | * @quirks: the u32 quirks value to add/replace | 138 | * @quirks: the u32 quirks value to add/replace |
140 | * | 139 | * |
141 | * Description: | 140 | * Description: |
142 | * If an dynamic quirk exists in memory for this (idVendor, | 141 | * If an dynamic quirk exists in memory for this (idVendor, |
143 | * idProduct) pair, replace its quirks value with what was | 142 | * idProduct) pair, replace its quirks value with what was |
144 | * provided. Otherwise, add the quirk to the dynamic quirks list. | 143 | * provided. Otherwise, add the quirk to the dynamic quirks list. |
145 | * | 144 | * |
146 | * Returns: 0 OK, -error on failure. | 145 | * Returns: 0 OK, -error on failure. |
147 | */ | 146 | */ |
148 | static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, | 147 | static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, |
149 | const u32 quirks) | 148 | const u32 quirks) |
150 | { | 149 | { |
151 | struct quirks_list_struct *q_new, *q; | 150 | struct quirks_list_struct *q_new, *q; |
152 | int list_edited = 0; | 151 | int list_edited = 0; |
153 | 152 | ||
154 | if (!idVendor) { | 153 | if (!idVendor) { |
155 | dbg_hid("Cannot add a quirk with idVendor = 0\n"); | 154 | dbg_hid("Cannot add a quirk with idVendor = 0\n"); |
156 | return -EINVAL; | 155 | return -EINVAL; |
157 | } | 156 | } |
158 | 157 | ||
159 | q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); | 158 | q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); |
160 | if (!q_new) { | 159 | if (!q_new) { |
161 | dbg_hid("Could not allocate quirks_list_struct\n"); | 160 | dbg_hid("Could not allocate quirks_list_struct\n"); |
162 | return -ENOMEM; | 161 | return -ENOMEM; |
163 | } | 162 | } |
164 | 163 | ||
165 | q_new->hid_bl_item.idVendor = idVendor; | 164 | q_new->hid_bl_item.idVendor = idVendor; |
166 | q_new->hid_bl_item.idProduct = idProduct; | 165 | q_new->hid_bl_item.idProduct = idProduct; |
167 | q_new->hid_bl_item.quirks = quirks; | 166 | q_new->hid_bl_item.quirks = quirks; |
168 | 167 | ||
169 | down_write(&dquirks_rwsem); | 168 | down_write(&dquirks_rwsem); |
170 | 169 | ||
171 | list_for_each_entry(q, &dquirks_list, node) { | 170 | list_for_each_entry(q, &dquirks_list, node) { |
172 | 171 | ||
173 | if (q->hid_bl_item.idVendor == idVendor && | 172 | if (q->hid_bl_item.idVendor == idVendor && |
174 | q->hid_bl_item.idProduct == idProduct) { | 173 | q->hid_bl_item.idProduct == idProduct) { |
175 | 174 | ||
176 | list_replace(&q->node, &q_new->node); | 175 | list_replace(&q->node, &q_new->node); |
177 | kfree(q); | 176 | kfree(q); |
178 | list_edited = 1; | 177 | list_edited = 1; |
179 | break; | 178 | break; |
180 | 179 | ||
181 | } | 180 | } |
182 | 181 | ||
183 | } | 182 | } |
184 | 183 | ||
185 | if (!list_edited) | 184 | if (!list_edited) |
186 | list_add_tail(&q_new->node, &dquirks_list); | 185 | list_add_tail(&q_new->node, &dquirks_list); |
187 | 186 | ||
188 | up_write(&dquirks_rwsem); | 187 | up_write(&dquirks_rwsem); |
189 | 188 | ||
190 | return 0; | 189 | return 0; |
191 | } | 190 | } |
192 | 191 | ||
193 | /** | 192 | /** |
194 | * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory | 193 | * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory |
195 | * | 194 | * |
196 | * Description: | 195 | * Description: |
197 | * Free all memory associated with dynamic quirks - called before | 196 | * Free all memory associated with dynamic quirks - called before |
198 | * module unload. | 197 | * module unload. |
199 | * | 198 | * |
200 | */ | 199 | */ |
201 | static void usbhid_remove_all_dquirks(void) | 200 | static void usbhid_remove_all_dquirks(void) |
202 | { | 201 | { |
203 | struct quirks_list_struct *q, *temp; | 202 | struct quirks_list_struct *q, *temp; |
204 | 203 | ||
205 | down_write(&dquirks_rwsem); | 204 | down_write(&dquirks_rwsem); |
206 | list_for_each_entry_safe(q, temp, &dquirks_list, node) { | 205 | list_for_each_entry_safe(q, temp, &dquirks_list, node) { |
207 | list_del(&q->node); | 206 | list_del(&q->node); |
208 | kfree(q); | 207 | kfree(q); |
209 | } | 208 | } |
210 | up_write(&dquirks_rwsem); | 209 | up_write(&dquirks_rwsem); |
211 | 210 | ||
212 | } | 211 | } |
213 | 212 | ||
214 | /** | 213 | /** |
215 | * usbhid_quirks_init: apply USB HID quirks specified at module load time | 214 | * usbhid_quirks_init: apply USB HID quirks specified at module load time |
216 | */ | 215 | */ |
217 | int usbhid_quirks_init(char **quirks_param) | 216 | int usbhid_quirks_init(char **quirks_param) |
218 | { | 217 | { |
219 | u16 idVendor, idProduct; | 218 | u16 idVendor, idProduct; |
220 | u32 quirks; | 219 | u32 quirks; |
221 | int n = 0, m; | 220 | int n = 0, m; |
222 | 221 | ||
223 | for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) { | 222 | for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) { |
224 | 223 | ||
225 | m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", | 224 | m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", |
226 | &idVendor, &idProduct, &quirks); | 225 | &idVendor, &idProduct, &quirks); |
227 | 226 | ||
228 | if (m != 3 || | 227 | if (m != 3 || |
229 | usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) { | 228 | usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) { |
230 | printk(KERN_WARNING | 229 | printk(KERN_WARNING |
231 | "Could not parse HID quirk module param %s\n", | 230 | "Could not parse HID quirk module param %s\n", |
232 | quirks_param[n]); | 231 | quirks_param[n]); |
233 | } | 232 | } |
234 | } | 233 | } |
235 | 234 | ||
236 | return 0; | 235 | return 0; |
237 | } | 236 | } |
238 | 237 | ||
239 | /** | 238 | /** |
240 | * usbhid_quirks_exit: release memory associated with dynamic_quirks | 239 | * usbhid_quirks_exit: release memory associated with dynamic_quirks |
241 | * | 240 | * |
242 | * Description: | 241 | * Description: |
243 | * Release all memory associated with dynamic quirks. Called upon | 242 | * Release all memory associated with dynamic quirks. Called upon |
244 | * module unload. | 243 | * module unload. |
245 | * | 244 | * |
246 | * Returns: nothing | 245 | * Returns: nothing |
247 | */ | 246 | */ |
248 | void usbhid_quirks_exit(void) | 247 | void usbhid_quirks_exit(void) |
249 | { | 248 | { |
250 | usbhid_remove_all_dquirks(); | 249 | usbhid_remove_all_dquirks(); |
251 | } | 250 | } |
252 | 251 | ||
253 | /** | 252 | /** |
254 | * usbhid_exists_squirk: return any static quirks for a USB HID device | 253 | * usbhid_exists_squirk: return any static quirks for a USB HID device |
255 | * @idVendor: the 16-bit USB vendor ID, in native byteorder | 254 | * @idVendor: the 16-bit USB vendor ID, in native byteorder |
256 | * @idProduct: the 16-bit USB product ID, in native byteorder | 255 | * @idProduct: the 16-bit USB product ID, in native byteorder |
257 | * | 256 | * |
258 | * Description: | 257 | * Description: |
259 | * Given a USB vendor ID and product ID, return a pointer to | 258 | * Given a USB vendor ID and product ID, return a pointer to |
260 | * the hid_blacklist entry associated with that device. | 259 | * the hid_blacklist entry associated with that device. |
261 | * | 260 | * |
262 | * Returns: pointer if quirk found, or NULL if no quirks found. | 261 | * Returns: pointer if quirk found, or NULL if no quirks found. |
263 | */ | 262 | */ |
264 | static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor, | 263 | static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor, |
265 | const u16 idProduct) | 264 | const u16 idProduct) |
266 | { | 265 | { |
267 | const struct hid_blacklist *bl_entry = NULL; | 266 | const struct hid_blacklist *bl_entry = NULL; |
268 | int n = 0; | 267 | int n = 0; |
269 | 268 | ||
270 | for (; hid_blacklist[n].idVendor; n++) | 269 | for (; hid_blacklist[n].idVendor; n++) |
271 | if (hid_blacklist[n].idVendor == idVendor && | 270 | if (hid_blacklist[n].idVendor == idVendor && |
272 | hid_blacklist[n].idProduct == idProduct) | 271 | hid_blacklist[n].idProduct == idProduct) |
273 | bl_entry = &hid_blacklist[n]; | 272 | bl_entry = &hid_blacklist[n]; |
274 | 273 | ||
275 | if (bl_entry != NULL) | 274 | if (bl_entry != NULL) |
276 | dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", | 275 | dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", |
277 | bl_entry->quirks, bl_entry->idVendor, | 276 | bl_entry->quirks, bl_entry->idVendor, |
278 | bl_entry->idProduct); | 277 | bl_entry->idProduct); |
279 | return bl_entry; | 278 | return bl_entry; |
280 | } | 279 | } |
281 | 280 | ||
282 | /** | 281 | /** |
283 | * usbhid_lookup_quirk: return any quirks associated with a USB HID device | 282 | * usbhid_lookup_quirk: return any quirks associated with a USB HID device |
284 | * @idVendor: the 16-bit USB vendor ID, in native byteorder | 283 | * @idVendor: the 16-bit USB vendor ID, in native byteorder |
285 | * @idProduct: the 16-bit USB product ID, in native byteorder | 284 | * @idProduct: the 16-bit USB product ID, in native byteorder |
286 | * | 285 | * |
287 | * Description: | 286 | * Description: |
288 | * Given a USB vendor ID and product ID, return any quirks associated | 287 | * Given a USB vendor ID and product ID, return any quirks associated |
289 | * with that device. | 288 | * with that device. |
290 | * | 289 | * |
291 | * Returns: a u32 quirks value. | 290 | * Returns: a u32 quirks value. |
292 | */ | 291 | */ |
293 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) | 292 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) |
294 | { | 293 | { |
295 | u32 quirks = 0; | 294 | u32 quirks = 0; |
296 | const struct hid_blacklist *bl_entry = NULL; | 295 | const struct hid_blacklist *bl_entry = NULL; |
297 | 296 | ||
298 | /* NCR devices must not be queried for reports */ | 297 | /* NCR devices must not be queried for reports */ |
299 | if (idVendor == USB_VENDOR_ID_NCR && | 298 | if (idVendor == USB_VENDOR_ID_NCR && |
300 | idProduct >= USB_DEVICE_ID_NCR_FIRST && | 299 | idProduct >= USB_DEVICE_ID_NCR_FIRST && |
301 | idProduct <= USB_DEVICE_ID_NCR_LAST) | 300 | idProduct <= USB_DEVICE_ID_NCR_LAST) |
302 | return HID_QUIRK_NO_INIT_REPORTS; | 301 | return HID_QUIRK_NO_INIT_REPORTS; |
303 | 302 | ||
304 | down_read(&dquirks_rwsem); | 303 | down_read(&dquirks_rwsem); |
305 | bl_entry = usbhid_exists_dquirk(idVendor, idProduct); | 304 | bl_entry = usbhid_exists_dquirk(idVendor, idProduct); |
306 | if (!bl_entry) | 305 | if (!bl_entry) |
307 | bl_entry = usbhid_exists_squirk(idVendor, idProduct); | 306 | bl_entry = usbhid_exists_squirk(idVendor, idProduct); |
308 | if (bl_entry) | 307 | if (bl_entry) |
309 | quirks = bl_entry->quirks; | 308 | quirks = bl_entry->quirks; |
310 | up_read(&dquirks_rwsem); | 309 | up_read(&dquirks_rwsem); |
311 | 310 | ||
312 | return quirks; | 311 | return quirks; |
313 | } | 312 | } |
314 | 313 | ||
315 | EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); | 314 | EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); |
316 | 315 |
include/linux/hid.h
1 | #ifndef __HID_H | 1 | #ifndef __HID_H |
2 | #define __HID_H | 2 | #define __HID_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Copyright (c) 1999 Andreas Gal | 5 | * Copyright (c) 1999 Andreas Gal |
6 | * Copyright (c) 2000-2001 Vojtech Pavlik | 6 | * Copyright (c) 2000-2001 Vojtech Pavlik |
7 | * Copyright (c) 2006-2007 Jiri Kosina | 7 | * Copyright (c) 2006-2007 Jiri Kosina |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * This program is distributed in the hope that it will be useful, | 16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | * | 24 | * |
25 | * Should you need to contact me, the author, you can do so either by | 25 | * Should you need to contact me, the author, you can do so either by |
26 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 26 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
27 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 27 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * USB HID (Human Interface Device) interface class code | 31 | * USB HID (Human Interface Device) interface class code |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #define USB_INTERFACE_CLASS_HID 3 | 34 | #define USB_INTERFACE_CLASS_HID 3 |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * USB HID interface subclass and protocol codes | 37 | * USB HID interface subclass and protocol codes |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #define USB_INTERFACE_SUBCLASS_BOOT 1 | 40 | #define USB_INTERFACE_SUBCLASS_BOOT 1 |
41 | #define USB_INTERFACE_PROTOCOL_KEYBOARD 1 | 41 | #define USB_INTERFACE_PROTOCOL_KEYBOARD 1 |
42 | #define USB_INTERFACE_PROTOCOL_MOUSE 2 | 42 | #define USB_INTERFACE_PROTOCOL_MOUSE 2 |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * HID class requests | 45 | * HID class requests |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #define HID_REQ_GET_REPORT 0x01 | 48 | #define HID_REQ_GET_REPORT 0x01 |
49 | #define HID_REQ_GET_IDLE 0x02 | 49 | #define HID_REQ_GET_IDLE 0x02 |
50 | #define HID_REQ_GET_PROTOCOL 0x03 | 50 | #define HID_REQ_GET_PROTOCOL 0x03 |
51 | #define HID_REQ_SET_REPORT 0x09 | 51 | #define HID_REQ_SET_REPORT 0x09 |
52 | #define HID_REQ_SET_IDLE 0x0A | 52 | #define HID_REQ_SET_IDLE 0x0A |
53 | #define HID_REQ_SET_PROTOCOL 0x0B | 53 | #define HID_REQ_SET_PROTOCOL 0x0B |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * HID class descriptor types | 56 | * HID class descriptor types |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #define HID_DT_HID (USB_TYPE_CLASS | 0x01) | 59 | #define HID_DT_HID (USB_TYPE_CLASS | 0x01) |
60 | #define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) | 60 | #define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) |
61 | #define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) | 61 | #define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) |
62 | 62 | ||
63 | #define HID_MAX_DESCRIPTOR_SIZE 4096 | 63 | #define HID_MAX_DESCRIPTOR_SIZE 4096 |
64 | 64 | ||
65 | #ifdef __KERNEL__ | 65 | #ifdef __KERNEL__ |
66 | 66 | ||
67 | #include <linux/types.h> | 67 | #include <linux/types.h> |
68 | #include <linux/slab.h> | 68 | #include <linux/slab.h> |
69 | #include <linux/list.h> | 69 | #include <linux/list.h> |
70 | #include <linux/mod_devicetable.h> /* hid_device_id */ | 70 | #include <linux/mod_devicetable.h> /* hid_device_id */ |
71 | #include <linux/timer.h> | 71 | #include <linux/timer.h> |
72 | #include <linux/workqueue.h> | 72 | #include <linux/workqueue.h> |
73 | #include <linux/input.h> | 73 | #include <linux/input.h> |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * We parse each description item into this structure. Short items data | 76 | * We parse each description item into this structure. Short items data |
77 | * values are expanded to 32-bit signed int, long items contain a pointer | 77 | * values are expanded to 32-bit signed int, long items contain a pointer |
78 | * into the data area. | 78 | * into the data area. |
79 | */ | 79 | */ |
80 | 80 | ||
81 | struct hid_item { | 81 | struct hid_item { |
82 | unsigned format; | 82 | unsigned format; |
83 | __u8 size; | 83 | __u8 size; |
84 | __u8 type; | 84 | __u8 type; |
85 | __u8 tag; | 85 | __u8 tag; |
86 | union { | 86 | union { |
87 | __u8 u8; | 87 | __u8 u8; |
88 | __s8 s8; | 88 | __s8 s8; |
89 | __u16 u16; | 89 | __u16 u16; |
90 | __s16 s16; | 90 | __s16 s16; |
91 | __u32 u32; | 91 | __u32 u32; |
92 | __s32 s32; | 92 | __s32 s32; |
93 | __u8 *longdata; | 93 | __u8 *longdata; |
94 | } data; | 94 | } data; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * HID report item format | 98 | * HID report item format |
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define HID_ITEM_FORMAT_SHORT 0 | 101 | #define HID_ITEM_FORMAT_SHORT 0 |
102 | #define HID_ITEM_FORMAT_LONG 1 | 102 | #define HID_ITEM_FORMAT_LONG 1 |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Special tag indicating long items | 105 | * Special tag indicating long items |
106 | */ | 106 | */ |
107 | 107 | ||
108 | #define HID_ITEM_TAG_LONG 15 | 108 | #define HID_ITEM_TAG_LONG 15 |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * HID report descriptor item type (prefix bit 2,3) | 111 | * HID report descriptor item type (prefix bit 2,3) |
112 | */ | 112 | */ |
113 | 113 | ||
114 | #define HID_ITEM_TYPE_MAIN 0 | 114 | #define HID_ITEM_TYPE_MAIN 0 |
115 | #define HID_ITEM_TYPE_GLOBAL 1 | 115 | #define HID_ITEM_TYPE_GLOBAL 1 |
116 | #define HID_ITEM_TYPE_LOCAL 2 | 116 | #define HID_ITEM_TYPE_LOCAL 2 |
117 | #define HID_ITEM_TYPE_RESERVED 3 | 117 | #define HID_ITEM_TYPE_RESERVED 3 |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * HID report descriptor main item tags | 120 | * HID report descriptor main item tags |
121 | */ | 121 | */ |
122 | 122 | ||
123 | #define HID_MAIN_ITEM_TAG_INPUT 8 | 123 | #define HID_MAIN_ITEM_TAG_INPUT 8 |
124 | #define HID_MAIN_ITEM_TAG_OUTPUT 9 | 124 | #define HID_MAIN_ITEM_TAG_OUTPUT 9 |
125 | #define HID_MAIN_ITEM_TAG_FEATURE 11 | 125 | #define HID_MAIN_ITEM_TAG_FEATURE 11 |
126 | #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 | 126 | #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 |
127 | #define HID_MAIN_ITEM_TAG_END_COLLECTION 12 | 127 | #define HID_MAIN_ITEM_TAG_END_COLLECTION 12 |
128 | 128 | ||
129 | /* | 129 | /* |
130 | * HID report descriptor main item contents | 130 | * HID report descriptor main item contents |
131 | */ | 131 | */ |
132 | 132 | ||
133 | #define HID_MAIN_ITEM_CONSTANT 0x001 | 133 | #define HID_MAIN_ITEM_CONSTANT 0x001 |
134 | #define HID_MAIN_ITEM_VARIABLE 0x002 | 134 | #define HID_MAIN_ITEM_VARIABLE 0x002 |
135 | #define HID_MAIN_ITEM_RELATIVE 0x004 | 135 | #define HID_MAIN_ITEM_RELATIVE 0x004 |
136 | #define HID_MAIN_ITEM_WRAP 0x008 | 136 | #define HID_MAIN_ITEM_WRAP 0x008 |
137 | #define HID_MAIN_ITEM_NONLINEAR 0x010 | 137 | #define HID_MAIN_ITEM_NONLINEAR 0x010 |
138 | #define HID_MAIN_ITEM_NO_PREFERRED 0x020 | 138 | #define HID_MAIN_ITEM_NO_PREFERRED 0x020 |
139 | #define HID_MAIN_ITEM_NULL_STATE 0x040 | 139 | #define HID_MAIN_ITEM_NULL_STATE 0x040 |
140 | #define HID_MAIN_ITEM_VOLATILE 0x080 | 140 | #define HID_MAIN_ITEM_VOLATILE 0x080 |
141 | #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 | 141 | #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 |
142 | 142 | ||
143 | /* | 143 | /* |
144 | * HID report descriptor collection item types | 144 | * HID report descriptor collection item types |
145 | */ | 145 | */ |
146 | 146 | ||
147 | #define HID_COLLECTION_PHYSICAL 0 | 147 | #define HID_COLLECTION_PHYSICAL 0 |
148 | #define HID_COLLECTION_APPLICATION 1 | 148 | #define HID_COLLECTION_APPLICATION 1 |
149 | #define HID_COLLECTION_LOGICAL 2 | 149 | #define HID_COLLECTION_LOGICAL 2 |
150 | 150 | ||
151 | /* | 151 | /* |
152 | * HID report descriptor global item tags | 152 | * HID report descriptor global item tags |
153 | */ | 153 | */ |
154 | 154 | ||
155 | #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 | 155 | #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 |
156 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 | 156 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 |
157 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 | 157 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 |
158 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 | 158 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 |
159 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 | 159 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 |
160 | #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 | 160 | #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 |
161 | #define HID_GLOBAL_ITEM_TAG_UNIT 6 | 161 | #define HID_GLOBAL_ITEM_TAG_UNIT 6 |
162 | #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 | 162 | #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 |
163 | #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 | 163 | #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 |
164 | #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 | 164 | #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 |
165 | #define HID_GLOBAL_ITEM_TAG_PUSH 10 | 165 | #define HID_GLOBAL_ITEM_TAG_PUSH 10 |
166 | #define HID_GLOBAL_ITEM_TAG_POP 11 | 166 | #define HID_GLOBAL_ITEM_TAG_POP 11 |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * HID report descriptor local item tags | 169 | * HID report descriptor local item tags |
170 | */ | 170 | */ |
171 | 171 | ||
172 | #define HID_LOCAL_ITEM_TAG_USAGE 0 | 172 | #define HID_LOCAL_ITEM_TAG_USAGE 0 |
173 | #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 | 173 | #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 |
174 | #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 | 174 | #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 |
175 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 | 175 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 |
176 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 | 176 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 |
177 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 | 177 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 |
178 | #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 | 178 | #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 |
179 | #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 | 179 | #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 |
180 | #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 | 180 | #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 |
181 | #define HID_LOCAL_ITEM_TAG_DELIMITER 10 | 181 | #define HID_LOCAL_ITEM_TAG_DELIMITER 10 |
182 | 182 | ||
183 | /* | 183 | /* |
184 | * HID usage tables | 184 | * HID usage tables |
185 | */ | 185 | */ |
186 | 186 | ||
187 | #define HID_USAGE_PAGE 0xffff0000 | 187 | #define HID_USAGE_PAGE 0xffff0000 |
188 | 188 | ||
189 | #define HID_UP_UNDEFINED 0x00000000 | 189 | #define HID_UP_UNDEFINED 0x00000000 |
190 | #define HID_UP_GENDESK 0x00010000 | 190 | #define HID_UP_GENDESK 0x00010000 |
191 | #define HID_UP_SIMULATION 0x00020000 | 191 | #define HID_UP_SIMULATION 0x00020000 |
192 | #define HID_UP_KEYBOARD 0x00070000 | 192 | #define HID_UP_KEYBOARD 0x00070000 |
193 | #define HID_UP_LED 0x00080000 | 193 | #define HID_UP_LED 0x00080000 |
194 | #define HID_UP_BUTTON 0x00090000 | 194 | #define HID_UP_BUTTON 0x00090000 |
195 | #define HID_UP_ORDINAL 0x000a0000 | 195 | #define HID_UP_ORDINAL 0x000a0000 |
196 | #define HID_UP_CONSUMER 0x000c0000 | 196 | #define HID_UP_CONSUMER 0x000c0000 |
197 | #define HID_UP_DIGITIZER 0x000d0000 | 197 | #define HID_UP_DIGITIZER 0x000d0000 |
198 | #define HID_UP_PID 0x000f0000 | 198 | #define HID_UP_PID 0x000f0000 |
199 | #define HID_UP_HPVENDOR 0xff7f0000 | 199 | #define HID_UP_HPVENDOR 0xff7f0000 |
200 | #define HID_UP_MSVENDOR 0xff000000 | 200 | #define HID_UP_MSVENDOR 0xff000000 |
201 | #define HID_UP_CUSTOM 0x00ff0000 | 201 | #define HID_UP_CUSTOM 0x00ff0000 |
202 | #define HID_UP_LOGIVENDOR 0xffbc0000 | 202 | #define HID_UP_LOGIVENDOR 0xffbc0000 |
203 | 203 | ||
204 | #define HID_USAGE 0x0000ffff | 204 | #define HID_USAGE 0x0000ffff |
205 | 205 | ||
206 | #define HID_GD_POINTER 0x00010001 | 206 | #define HID_GD_POINTER 0x00010001 |
207 | #define HID_GD_MOUSE 0x00010002 | 207 | #define HID_GD_MOUSE 0x00010002 |
208 | #define HID_GD_JOYSTICK 0x00010004 | 208 | #define HID_GD_JOYSTICK 0x00010004 |
209 | #define HID_GD_GAMEPAD 0x00010005 | 209 | #define HID_GD_GAMEPAD 0x00010005 |
210 | #define HID_GD_KEYBOARD 0x00010006 | 210 | #define HID_GD_KEYBOARD 0x00010006 |
211 | #define HID_GD_KEYPAD 0x00010007 | 211 | #define HID_GD_KEYPAD 0x00010007 |
212 | #define HID_GD_MULTIAXIS 0x00010008 | 212 | #define HID_GD_MULTIAXIS 0x00010008 |
213 | #define HID_GD_X 0x00010030 | 213 | #define HID_GD_X 0x00010030 |
214 | #define HID_GD_Y 0x00010031 | 214 | #define HID_GD_Y 0x00010031 |
215 | #define HID_GD_Z 0x00010032 | 215 | #define HID_GD_Z 0x00010032 |
216 | #define HID_GD_RX 0x00010033 | 216 | #define HID_GD_RX 0x00010033 |
217 | #define HID_GD_RY 0x00010034 | 217 | #define HID_GD_RY 0x00010034 |
218 | #define HID_GD_RZ 0x00010035 | 218 | #define HID_GD_RZ 0x00010035 |
219 | #define HID_GD_SLIDER 0x00010036 | 219 | #define HID_GD_SLIDER 0x00010036 |
220 | #define HID_GD_DIAL 0x00010037 | 220 | #define HID_GD_DIAL 0x00010037 |
221 | #define HID_GD_WHEEL 0x00010038 | 221 | #define HID_GD_WHEEL 0x00010038 |
222 | #define HID_GD_HATSWITCH 0x00010039 | 222 | #define HID_GD_HATSWITCH 0x00010039 |
223 | #define HID_GD_BUFFER 0x0001003a | 223 | #define HID_GD_BUFFER 0x0001003a |
224 | #define HID_GD_BYTECOUNT 0x0001003b | 224 | #define HID_GD_BYTECOUNT 0x0001003b |
225 | #define HID_GD_MOTION 0x0001003c | 225 | #define HID_GD_MOTION 0x0001003c |
226 | #define HID_GD_START 0x0001003d | 226 | #define HID_GD_START 0x0001003d |
227 | #define HID_GD_SELECT 0x0001003e | 227 | #define HID_GD_SELECT 0x0001003e |
228 | #define HID_GD_VX 0x00010040 | 228 | #define HID_GD_VX 0x00010040 |
229 | #define HID_GD_VY 0x00010041 | 229 | #define HID_GD_VY 0x00010041 |
230 | #define HID_GD_VZ 0x00010042 | 230 | #define HID_GD_VZ 0x00010042 |
231 | #define HID_GD_VBRX 0x00010043 | 231 | #define HID_GD_VBRX 0x00010043 |
232 | #define HID_GD_VBRY 0x00010044 | 232 | #define HID_GD_VBRY 0x00010044 |
233 | #define HID_GD_VBRZ 0x00010045 | 233 | #define HID_GD_VBRZ 0x00010045 |
234 | #define HID_GD_VNO 0x00010046 | 234 | #define HID_GD_VNO 0x00010046 |
235 | #define HID_GD_FEATURE 0x00010047 | 235 | #define HID_GD_FEATURE 0x00010047 |
236 | #define HID_GD_UP 0x00010090 | 236 | #define HID_GD_UP 0x00010090 |
237 | #define HID_GD_DOWN 0x00010091 | 237 | #define HID_GD_DOWN 0x00010091 |
238 | #define HID_GD_RIGHT 0x00010092 | 238 | #define HID_GD_RIGHT 0x00010092 |
239 | #define HID_GD_LEFT 0x00010093 | 239 | #define HID_GD_LEFT 0x00010093 |
240 | 240 | ||
241 | #define HID_DG_DIGITIZER 0x000d0001 | 241 | #define HID_DG_DIGITIZER 0x000d0001 |
242 | #define HID_DG_PEN 0x000d0002 | 242 | #define HID_DG_PEN 0x000d0002 |
243 | #define HID_DG_LIGHTPEN 0x000d0003 | 243 | #define HID_DG_LIGHTPEN 0x000d0003 |
244 | #define HID_DG_TOUCHSCREEN 0x000d0004 | 244 | #define HID_DG_TOUCHSCREEN 0x000d0004 |
245 | #define HID_DG_TOUCHPAD 0x000d0005 | 245 | #define HID_DG_TOUCHPAD 0x000d0005 |
246 | #define HID_DG_STYLUS 0x000d0020 | 246 | #define HID_DG_STYLUS 0x000d0020 |
247 | #define HID_DG_PUCK 0x000d0021 | 247 | #define HID_DG_PUCK 0x000d0021 |
248 | #define HID_DG_FINGER 0x000d0022 | 248 | #define HID_DG_FINGER 0x000d0022 |
249 | #define HID_DG_TIPPRESSURE 0x000d0030 | 249 | #define HID_DG_TIPPRESSURE 0x000d0030 |
250 | #define HID_DG_BARRELPRESSURE 0x000d0031 | 250 | #define HID_DG_BARRELPRESSURE 0x000d0031 |
251 | #define HID_DG_INRANGE 0x000d0032 | 251 | #define HID_DG_INRANGE 0x000d0032 |
252 | #define HID_DG_TOUCH 0x000d0033 | 252 | #define HID_DG_TOUCH 0x000d0033 |
253 | #define HID_DG_UNTOUCH 0x000d0034 | 253 | #define HID_DG_UNTOUCH 0x000d0034 |
254 | #define HID_DG_TAP 0x000d0035 | 254 | #define HID_DG_TAP 0x000d0035 |
255 | #define HID_DG_TABLETFUNCTIONKEY 0x000d0039 | 255 | #define HID_DG_TABLETFUNCTIONKEY 0x000d0039 |
256 | #define HID_DG_PROGRAMCHANGEKEY 0x000d003a | 256 | #define HID_DG_PROGRAMCHANGEKEY 0x000d003a |
257 | #define HID_DG_INVERT 0x000d003c | 257 | #define HID_DG_INVERT 0x000d003c |
258 | #define HID_DG_TIPSWITCH 0x000d0042 | 258 | #define HID_DG_TIPSWITCH 0x000d0042 |
259 | #define HID_DG_TIPSWITCH2 0x000d0043 | 259 | #define HID_DG_TIPSWITCH2 0x000d0043 |
260 | #define HID_DG_BARRELSWITCH 0x000d0044 | 260 | #define HID_DG_BARRELSWITCH 0x000d0044 |
261 | #define HID_DG_ERASER 0x000d0045 | 261 | #define HID_DG_ERASER 0x000d0045 |
262 | #define HID_DG_TABLETPICK 0x000d0046 | 262 | #define HID_DG_TABLETPICK 0x000d0046 |
263 | /* | 263 | /* |
264 | * as of May 20, 2009 the usages below are not yet in the official USB spec | 264 | * as of May 20, 2009 the usages below are not yet in the official USB spec |
265 | * but are being pushed by Microsft as described in their paper "Digitizer | 265 | * but are being pushed by Microsft as described in their paper "Digitizer |
266 | * Drivers for Windows Touch and Pen-Based Computers" | 266 | * Drivers for Windows Touch and Pen-Based Computers" |
267 | */ | 267 | */ |
268 | #define HID_DG_CONFIDENCE 0x000d0047 | 268 | #define HID_DG_CONFIDENCE 0x000d0047 |
269 | #define HID_DG_WIDTH 0x000d0048 | 269 | #define HID_DG_WIDTH 0x000d0048 |
270 | #define HID_DG_HEIGHT 0x000d0049 | 270 | #define HID_DG_HEIGHT 0x000d0049 |
271 | #define HID_DG_CONTACTID 0x000d0051 | 271 | #define HID_DG_CONTACTID 0x000d0051 |
272 | #define HID_DG_INPUTMODE 0x000d0052 | 272 | #define HID_DG_INPUTMODE 0x000d0052 |
273 | #define HID_DG_DEVICEINDEX 0x000d0053 | 273 | #define HID_DG_DEVICEINDEX 0x000d0053 |
274 | #define HID_DG_CONTACTCOUNT 0x000d0054 | 274 | #define HID_DG_CONTACTCOUNT 0x000d0054 |
275 | #define HID_DG_CONTACTMAX 0x000d0055 | 275 | #define HID_DG_CONTACTMAX 0x000d0055 |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * HID report types --- Ouch! HID spec says 1 2 3! | 278 | * HID report types --- Ouch! HID spec says 1 2 3! |
279 | */ | 279 | */ |
280 | 280 | ||
281 | #define HID_INPUT_REPORT 0 | 281 | #define HID_INPUT_REPORT 0 |
282 | #define HID_OUTPUT_REPORT 1 | 282 | #define HID_OUTPUT_REPORT 1 |
283 | #define HID_FEATURE_REPORT 2 | 283 | #define HID_FEATURE_REPORT 2 |
284 | 284 | ||
285 | /* | 285 | /* |
286 | * HID connect requests | 286 | * HID connect requests |
287 | */ | 287 | */ |
288 | 288 | ||
289 | #define HID_CONNECT_HIDINPUT 0x01 | 289 | #define HID_CONNECT_HIDINPUT 0x01 |
290 | #define HID_CONNECT_HIDINPUT_FORCE 0x02 | 290 | #define HID_CONNECT_HIDINPUT_FORCE 0x02 |
291 | #define HID_CONNECT_HIDRAW 0x04 | 291 | #define HID_CONNECT_HIDRAW 0x04 |
292 | #define HID_CONNECT_HIDDEV 0x08 | 292 | #define HID_CONNECT_HIDDEV 0x08 |
293 | #define HID_CONNECT_HIDDEV_FORCE 0x10 | 293 | #define HID_CONNECT_HIDDEV_FORCE 0x10 |
294 | #define HID_CONNECT_FF 0x20 | 294 | #define HID_CONNECT_FF 0x20 |
295 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ | 295 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ |
296 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) | 296 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * HID device quirks. | 299 | * HID device quirks. |
300 | */ | 300 | */ |
301 | 301 | ||
302 | /* | 302 | /* |
303 | * Increase this if you need to configure more HID quirks at module load time | 303 | * Increase this if you need to configure more HID quirks at module load time |
304 | */ | 304 | */ |
305 | #define MAX_USBHID_BOOT_QUIRKS 4 | 305 | #define MAX_USBHID_BOOT_QUIRKS 4 |
306 | 306 | ||
307 | #define HID_QUIRK_INVERT 0x00000001 | 307 | #define HID_QUIRK_INVERT 0x00000001 |
308 | #define HID_QUIRK_NOTOUCH 0x00000002 | 308 | #define HID_QUIRK_NOTOUCH 0x00000002 |
309 | #define HID_QUIRK_IGNORE 0x00000004 | 309 | #define HID_QUIRK_IGNORE 0x00000004 |
310 | #define HID_QUIRK_NOGET 0x00000008 | 310 | #define HID_QUIRK_NOGET 0x00000008 |
311 | #define HID_QUIRK_HIDDEV_FORCE 0x00000010 | 311 | #define HID_QUIRK_HIDDEV_FORCE 0x00000010 |
312 | #define HID_QUIRK_BADPAD 0x00000020 | 312 | #define HID_QUIRK_BADPAD 0x00000020 |
313 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 313 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
314 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 314 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
315 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 315 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
316 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 316 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
317 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 | 317 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 |
318 | #define HID_QUIRK_NO_IGNORE 0x40000000 | 318 | #define HID_QUIRK_NO_IGNORE 0x40000000 |
319 | #define HID_QUIRK_NO_INPUT_SYNC 0x80000000 | ||
319 | 320 | ||
320 | /* | 321 | /* |
321 | * This is the global environment of the parser. This information is | 322 | * This is the global environment of the parser. This information is |
322 | * persistent for main-items. The global environment can be saved and | 323 | * persistent for main-items. The global environment can be saved and |
323 | * restored with PUSH/POP statements. | 324 | * restored with PUSH/POP statements. |
324 | */ | 325 | */ |
325 | 326 | ||
326 | struct hid_global { | 327 | struct hid_global { |
327 | unsigned usage_page; | 328 | unsigned usage_page; |
328 | __s32 logical_minimum; | 329 | __s32 logical_minimum; |
329 | __s32 logical_maximum; | 330 | __s32 logical_maximum; |
330 | __s32 physical_minimum; | 331 | __s32 physical_minimum; |
331 | __s32 physical_maximum; | 332 | __s32 physical_maximum; |
332 | __s32 unit_exponent; | 333 | __s32 unit_exponent; |
333 | unsigned unit; | 334 | unsigned unit; |
334 | unsigned report_id; | 335 | unsigned report_id; |
335 | unsigned report_size; | 336 | unsigned report_size; |
336 | unsigned report_count; | 337 | unsigned report_count; |
337 | }; | 338 | }; |
338 | 339 | ||
339 | /* | 340 | /* |
340 | * This is the local environment. It is persistent up the next main-item. | 341 | * This is the local environment. It is persistent up the next main-item. |
341 | */ | 342 | */ |
342 | 343 | ||
343 | #define HID_MAX_USAGES 12288 | 344 | #define HID_MAX_USAGES 12288 |
344 | #define HID_DEFAULT_NUM_COLLECTIONS 16 | 345 | #define HID_DEFAULT_NUM_COLLECTIONS 16 |
345 | 346 | ||
346 | struct hid_local { | 347 | struct hid_local { |
347 | unsigned usage[HID_MAX_USAGES]; /* usage array */ | 348 | unsigned usage[HID_MAX_USAGES]; /* usage array */ |
348 | unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ | 349 | unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ |
349 | unsigned usage_index; | 350 | unsigned usage_index; |
350 | unsigned usage_minimum; | 351 | unsigned usage_minimum; |
351 | unsigned delimiter_depth; | 352 | unsigned delimiter_depth; |
352 | unsigned delimiter_branch; | 353 | unsigned delimiter_branch; |
353 | }; | 354 | }; |
354 | 355 | ||
355 | /* | 356 | /* |
356 | * This is the collection stack. We climb up the stack to determine | 357 | * This is the collection stack. We climb up the stack to determine |
357 | * application and function of each field. | 358 | * application and function of each field. |
358 | */ | 359 | */ |
359 | 360 | ||
360 | struct hid_collection { | 361 | struct hid_collection { |
361 | unsigned type; | 362 | unsigned type; |
362 | unsigned usage; | 363 | unsigned usage; |
363 | unsigned level; | 364 | unsigned level; |
364 | }; | 365 | }; |
365 | 366 | ||
366 | struct hid_usage { | 367 | struct hid_usage { |
367 | unsigned hid; /* hid usage code */ | 368 | unsigned hid; /* hid usage code */ |
368 | unsigned collection_index; /* index into collection array */ | 369 | unsigned collection_index; /* index into collection array */ |
369 | /* hidinput data */ | 370 | /* hidinput data */ |
370 | __u16 code; /* input driver code */ | 371 | __u16 code; /* input driver code */ |
371 | __u8 type; /* input driver type */ | 372 | __u8 type; /* input driver type */ |
372 | __s8 hat_min; /* hat switch fun */ | 373 | __s8 hat_min; /* hat switch fun */ |
373 | __s8 hat_max; /* ditto */ | 374 | __s8 hat_max; /* ditto */ |
374 | __s8 hat_dir; /* ditto */ | 375 | __s8 hat_dir; /* ditto */ |
375 | }; | 376 | }; |
376 | 377 | ||
377 | struct hid_input; | 378 | struct hid_input; |
378 | 379 | ||
379 | struct hid_field { | 380 | struct hid_field { |
380 | unsigned physical; /* physical usage for this field */ | 381 | unsigned physical; /* physical usage for this field */ |
381 | unsigned logical; /* logical usage for this field */ | 382 | unsigned logical; /* logical usage for this field */ |
382 | unsigned application; /* application usage for this field */ | 383 | unsigned application; /* application usage for this field */ |
383 | struct hid_usage *usage; /* usage table for this function */ | 384 | struct hid_usage *usage; /* usage table for this function */ |
384 | unsigned maxusage; /* maximum usage index */ | 385 | unsigned maxusage; /* maximum usage index */ |
385 | unsigned flags; /* main-item flags (i.e. volatile,array,constant) */ | 386 | unsigned flags; /* main-item flags (i.e. volatile,array,constant) */ |
386 | unsigned report_offset; /* bit offset in the report */ | 387 | unsigned report_offset; /* bit offset in the report */ |
387 | unsigned report_size; /* size of this field in the report */ | 388 | unsigned report_size; /* size of this field in the report */ |
388 | unsigned report_count; /* number of this field in the report */ | 389 | unsigned report_count; /* number of this field in the report */ |
389 | unsigned report_type; /* (input,output,feature) */ | 390 | unsigned report_type; /* (input,output,feature) */ |
390 | __s32 *value; /* last known value(s) */ | 391 | __s32 *value; /* last known value(s) */ |
391 | __s32 logical_minimum; | 392 | __s32 logical_minimum; |
392 | __s32 logical_maximum; | 393 | __s32 logical_maximum; |
393 | __s32 physical_minimum; | 394 | __s32 physical_minimum; |
394 | __s32 physical_maximum; | 395 | __s32 physical_maximum; |
395 | __s32 unit_exponent; | 396 | __s32 unit_exponent; |
396 | unsigned unit; | 397 | unsigned unit; |
397 | struct hid_report *report; /* associated report */ | 398 | struct hid_report *report; /* associated report */ |
398 | unsigned index; /* index into report->field[] */ | 399 | unsigned index; /* index into report->field[] */ |
399 | /* hidinput data */ | 400 | /* hidinput data */ |
400 | struct hid_input *hidinput; /* associated input structure */ | 401 | struct hid_input *hidinput; /* associated input structure */ |
401 | __u16 dpad; /* dpad input code */ | 402 | __u16 dpad; /* dpad input code */ |
402 | }; | 403 | }; |
403 | 404 | ||
404 | #define HID_MAX_FIELDS 64 | 405 | #define HID_MAX_FIELDS 64 |
405 | 406 | ||
406 | struct hid_report { | 407 | struct hid_report { |
407 | struct list_head list; | 408 | struct list_head list; |
408 | unsigned id; /* id of this report */ | 409 | unsigned id; /* id of this report */ |
409 | unsigned type; /* report type */ | 410 | unsigned type; /* report type */ |
410 | struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ | 411 | struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ |
411 | unsigned maxfield; /* maximum valid field index */ | 412 | unsigned maxfield; /* maximum valid field index */ |
412 | unsigned size; /* size of the report (bits) */ | 413 | unsigned size; /* size of the report (bits) */ |
413 | struct hid_device *device; /* associated device */ | 414 | struct hid_device *device; /* associated device */ |
414 | }; | 415 | }; |
415 | 416 | ||
416 | struct hid_report_enum { | 417 | struct hid_report_enum { |
417 | unsigned numbered; | 418 | unsigned numbered; |
418 | struct list_head report_list; | 419 | struct list_head report_list; |
419 | struct hid_report *report_id_hash[256]; | 420 | struct hid_report *report_id_hash[256]; |
420 | }; | 421 | }; |
421 | 422 | ||
422 | #define HID_REPORT_TYPES 3 | 423 | #define HID_REPORT_TYPES 3 |
423 | 424 | ||
424 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ | 425 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ |
425 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ | 426 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ |
426 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ | 427 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ |
427 | #define HID_OUTPUT_FIFO_SIZE 64 | 428 | #define HID_OUTPUT_FIFO_SIZE 64 |
428 | 429 | ||
429 | struct hid_control_fifo { | 430 | struct hid_control_fifo { |
430 | unsigned char dir; | 431 | unsigned char dir; |
431 | struct hid_report *report; | 432 | struct hid_report *report; |
432 | char *raw_report; | 433 | char *raw_report; |
433 | }; | 434 | }; |
434 | 435 | ||
435 | struct hid_output_fifo { | 436 | struct hid_output_fifo { |
436 | struct hid_report *report; | 437 | struct hid_report *report; |
437 | char *raw_report; | 438 | char *raw_report; |
438 | }; | 439 | }; |
439 | 440 | ||
440 | #define HID_CLAIMED_INPUT 1 | 441 | #define HID_CLAIMED_INPUT 1 |
441 | #define HID_CLAIMED_HIDDEV 2 | 442 | #define HID_CLAIMED_HIDDEV 2 |
442 | #define HID_CLAIMED_HIDRAW 4 | 443 | #define HID_CLAIMED_HIDRAW 4 |
443 | 444 | ||
444 | #define HID_STAT_ADDED 1 | 445 | #define HID_STAT_ADDED 1 |
445 | #define HID_STAT_PARSED 2 | 446 | #define HID_STAT_PARSED 2 |
446 | 447 | ||
447 | struct hid_input { | 448 | struct hid_input { |
448 | struct list_head list; | 449 | struct list_head list; |
449 | struct hid_report *report; | 450 | struct hid_report *report; |
450 | struct input_dev *input; | 451 | struct input_dev *input; |
451 | }; | 452 | }; |
452 | 453 | ||
453 | enum hid_type { | 454 | enum hid_type { |
454 | HID_TYPE_OTHER = 0, | 455 | HID_TYPE_OTHER = 0, |
455 | HID_TYPE_USBMOUSE | 456 | HID_TYPE_USBMOUSE |
456 | }; | 457 | }; |
457 | 458 | ||
458 | struct hid_driver; | 459 | struct hid_driver; |
459 | struct hid_ll_driver; | 460 | struct hid_ll_driver; |
460 | 461 | ||
461 | struct hid_device { /* device report descriptor */ | 462 | struct hid_device { /* device report descriptor */ |
462 | __u8 *rdesc; | 463 | __u8 *rdesc; |
463 | unsigned rsize; | 464 | unsigned rsize; |
464 | struct hid_collection *collection; /* List of HID collections */ | 465 | struct hid_collection *collection; /* List of HID collections */ |
465 | unsigned collection_size; /* Number of allocated hid_collections */ | 466 | unsigned collection_size; /* Number of allocated hid_collections */ |
466 | unsigned maxcollection; /* Number of parsed collections */ | 467 | unsigned maxcollection; /* Number of parsed collections */ |
467 | unsigned maxapplication; /* Number of applications */ | 468 | unsigned maxapplication; /* Number of applications */ |
468 | __u16 bus; /* BUS ID */ | 469 | __u16 bus; /* BUS ID */ |
469 | __u32 vendor; /* Vendor ID */ | 470 | __u32 vendor; /* Vendor ID */ |
470 | __u32 product; /* Product ID */ | 471 | __u32 product; /* Product ID */ |
471 | __u32 version; /* HID version */ | 472 | __u32 version; /* HID version */ |
472 | enum hid_type type; /* device type (mouse, kbd, ...) */ | 473 | enum hid_type type; /* device type (mouse, kbd, ...) */ |
473 | unsigned country; /* HID country */ | 474 | unsigned country; /* HID country */ |
474 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | 475 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; |
475 | 476 | ||
476 | struct device dev; /* device */ | 477 | struct device dev; /* device */ |
477 | struct hid_driver *driver; | 478 | struct hid_driver *driver; |
478 | struct hid_ll_driver *ll_driver; | 479 | struct hid_ll_driver *ll_driver; |
479 | 480 | ||
480 | unsigned int status; /* see STAT flags above */ | 481 | unsigned int status; /* see STAT flags above */ |
481 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 482 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
482 | unsigned quirks; /* Various quirks the device can pull on us */ | 483 | unsigned quirks; /* Various quirks the device can pull on us */ |
483 | 484 | ||
484 | struct list_head inputs; /* The list of inputs */ | 485 | struct list_head inputs; /* The list of inputs */ |
485 | void *hiddev; /* The hiddev structure */ | 486 | void *hiddev; /* The hiddev structure */ |
486 | void *hidraw; | 487 | void *hidraw; |
487 | int minor; /* Hiddev minor number */ | 488 | int minor; /* Hiddev minor number */ |
488 | 489 | ||
489 | int open; /* is the device open by anyone? */ | 490 | int open; /* is the device open by anyone? */ |
490 | char name[128]; /* Device name */ | 491 | char name[128]; /* Device name */ |
491 | char phys[64]; /* Device physical location */ | 492 | char phys[64]; /* Device physical location */ |
492 | char uniq[64]; /* Device unique identifier (serial #) */ | 493 | char uniq[64]; /* Device unique identifier (serial #) */ |
493 | 494 | ||
494 | void *driver_data; | 495 | void *driver_data; |
495 | 496 | ||
496 | /* temporary hid_ff handling (until moved to the drivers) */ | 497 | /* temporary hid_ff handling (until moved to the drivers) */ |
497 | int (*ff_init)(struct hid_device *); | 498 | int (*ff_init)(struct hid_device *); |
498 | 499 | ||
499 | /* hiddev event handler */ | 500 | /* hiddev event handler */ |
500 | int (*hiddev_connect)(struct hid_device *, unsigned int); | 501 | int (*hiddev_connect)(struct hid_device *, unsigned int); |
501 | void (*hiddev_disconnect)(struct hid_device *); | 502 | void (*hiddev_disconnect)(struct hid_device *); |
502 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, | 503 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, |
503 | struct hid_usage *, __s32); | 504 | struct hid_usage *, __s32); |
504 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); | 505 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); |
505 | 506 | ||
506 | /* handler for raw output data, used by hidraw */ | 507 | /* handler for raw output data, used by hidraw */ |
507 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char); | 508 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char); |
508 | 509 | ||
509 | /* debugging support via debugfs */ | 510 | /* debugging support via debugfs */ |
510 | unsigned short debug; | 511 | unsigned short debug; |
511 | struct dentry *debug_dir; | 512 | struct dentry *debug_dir; |
512 | struct dentry *debug_rdesc; | 513 | struct dentry *debug_rdesc; |
513 | struct dentry *debug_events; | 514 | struct dentry *debug_events; |
514 | struct list_head debug_list; | 515 | struct list_head debug_list; |
515 | wait_queue_head_t debug_wait; | 516 | wait_queue_head_t debug_wait; |
516 | }; | 517 | }; |
517 | 518 | ||
518 | static inline void *hid_get_drvdata(struct hid_device *hdev) | 519 | static inline void *hid_get_drvdata(struct hid_device *hdev) |
519 | { | 520 | { |
520 | return dev_get_drvdata(&hdev->dev); | 521 | return dev_get_drvdata(&hdev->dev); |
521 | } | 522 | } |
522 | 523 | ||
523 | static inline void hid_set_drvdata(struct hid_device *hdev, void *data) | 524 | static inline void hid_set_drvdata(struct hid_device *hdev, void *data) |
524 | { | 525 | { |
525 | dev_set_drvdata(&hdev->dev, data); | 526 | dev_set_drvdata(&hdev->dev, data); |
526 | } | 527 | } |
527 | 528 | ||
528 | #define HID_GLOBAL_STACK_SIZE 4 | 529 | #define HID_GLOBAL_STACK_SIZE 4 |
529 | #define HID_COLLECTION_STACK_SIZE 4 | 530 | #define HID_COLLECTION_STACK_SIZE 4 |
530 | 531 | ||
531 | struct hid_parser { | 532 | struct hid_parser { |
532 | struct hid_global global; | 533 | struct hid_global global; |
533 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; | 534 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; |
534 | unsigned global_stack_ptr; | 535 | unsigned global_stack_ptr; |
535 | struct hid_local local; | 536 | struct hid_local local; |
536 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; | 537 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; |
537 | unsigned collection_stack_ptr; | 538 | unsigned collection_stack_ptr; |
538 | struct hid_device *device; | 539 | struct hid_device *device; |
539 | }; | 540 | }; |
540 | 541 | ||
541 | struct hid_class_descriptor { | 542 | struct hid_class_descriptor { |
542 | __u8 bDescriptorType; | 543 | __u8 bDescriptorType; |
543 | __le16 wDescriptorLength; | 544 | __le16 wDescriptorLength; |
544 | } __attribute__ ((packed)); | 545 | } __attribute__ ((packed)); |
545 | 546 | ||
546 | struct hid_descriptor { | 547 | struct hid_descriptor { |
547 | __u8 bLength; | 548 | __u8 bLength; |
548 | __u8 bDescriptorType; | 549 | __u8 bDescriptorType; |
549 | __le16 bcdHID; | 550 | __le16 bcdHID; |
550 | __u8 bCountryCode; | 551 | __u8 bCountryCode; |
551 | __u8 bNumDescriptors; | 552 | __u8 bNumDescriptors; |
552 | 553 | ||
553 | struct hid_class_descriptor desc[1]; | 554 | struct hid_class_descriptor desc[1]; |
554 | } __attribute__ ((packed)); | 555 | } __attribute__ ((packed)); |
555 | 556 | ||
556 | #define HID_DEVICE(b, ven, prod) \ | 557 | #define HID_DEVICE(b, ven, prod) \ |
557 | .bus = (b), \ | 558 | .bus = (b), \ |
558 | .vendor = (ven), .product = (prod) | 559 | .vendor = (ven), .product = (prod) |
559 | 560 | ||
560 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) | 561 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) |
561 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) | 562 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) |
562 | 563 | ||
563 | #define HID_REPORT_ID(rep) \ | 564 | #define HID_REPORT_ID(rep) \ |
564 | .report_type = (rep) | 565 | .report_type = (rep) |
565 | #define HID_USAGE_ID(uhid, utype, ucode) \ | 566 | #define HID_USAGE_ID(uhid, utype, ucode) \ |
566 | .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) | 567 | .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) |
567 | /* we don't want to catch types and codes equal to 0 */ | 568 | /* we don't want to catch types and codes equal to 0 */ |
568 | #define HID_TERMINATOR (HID_ANY_ID - 1) | 569 | #define HID_TERMINATOR (HID_ANY_ID - 1) |
569 | 570 | ||
570 | struct hid_report_id { | 571 | struct hid_report_id { |
571 | __u32 report_type; | 572 | __u32 report_type; |
572 | }; | 573 | }; |
573 | struct hid_usage_id { | 574 | struct hid_usage_id { |
574 | __u32 usage_hid; | 575 | __u32 usage_hid; |
575 | __u32 usage_type; | 576 | __u32 usage_type; |
576 | __u32 usage_code; | 577 | __u32 usage_code; |
577 | }; | 578 | }; |
578 | 579 | ||
579 | /** | 580 | /** |
580 | * struct hid_driver | 581 | * struct hid_driver |
581 | * @name: driver name (e.g. "Footech_bar-wheel") | 582 | * @name: driver name (e.g. "Footech_bar-wheel") |
582 | * @id_table: which devices is this driver for (must be non-NULL for probe | 583 | * @id_table: which devices is this driver for (must be non-NULL for probe |
583 | * to be called) | 584 | * to be called) |
584 | * @dyn_list: list of dynamically added device ids | 585 | * @dyn_list: list of dynamically added device ids |
585 | * @dyn_lock: lock protecting @dyn_list | 586 | * @dyn_lock: lock protecting @dyn_list |
586 | * @probe: new device inserted | 587 | * @probe: new device inserted |
587 | * @remove: device removed (NULL if not a hot-plug capable driver) | 588 | * @remove: device removed (NULL if not a hot-plug capable driver) |
588 | * @report_table: on which reports to call raw_event (NULL means all) | 589 | * @report_table: on which reports to call raw_event (NULL means all) |
589 | * @raw_event: if report in report_table, this hook is called (NULL means nop) | 590 | * @raw_event: if report in report_table, this hook is called (NULL means nop) |
590 | * @usage_table: on which events to call event (NULL means all) | 591 | * @usage_table: on which events to call event (NULL means all) |
591 | * @event: if usage in usage_table, this hook is called (NULL means nop) | 592 | * @event: if usage in usage_table, this hook is called (NULL means nop) |
592 | * @report_fixup: called before report descriptor parsing (NULL means nop) | 593 | * @report_fixup: called before report descriptor parsing (NULL means nop) |
593 | * @input_mapping: invoked on input registering before mapping an usage | 594 | * @input_mapping: invoked on input registering before mapping an usage |
594 | * @input_mapped: invoked on input registering after mapping an usage | 595 | * @input_mapped: invoked on input registering after mapping an usage |
595 | * @suspend: invoked on suspend (NULL means nop) | 596 | * @suspend: invoked on suspend (NULL means nop) |
596 | * @resume: invoked on resume if device was not reset (NULL means nop) | 597 | * @resume: invoked on resume if device was not reset (NULL means nop) |
597 | * @reset_resume: invoked on resume if device was reset (NULL means nop) | 598 | * @reset_resume: invoked on resume if device was reset (NULL means nop) |
598 | * | 599 | * |
599 | * raw_event and event should return 0 on no action performed, 1 when no | 600 | * raw_event and event should return 0 on no action performed, 1 when no |
600 | * further processing should be done and negative on error | 601 | * further processing should be done and negative on error |
601 | * | 602 | * |
602 | * input_mapping shall return a negative value to completely ignore this usage | 603 | * input_mapping shall return a negative value to completely ignore this usage |
603 | * (e.g. doubled or invalid usage), zero to continue with parsing of this | 604 | * (e.g. doubled or invalid usage), zero to continue with parsing of this |
604 | * usage by generic code (no special handling needed) or positive to skip | 605 | * usage by generic code (no special handling needed) or positive to skip |
605 | * generic parsing (needed special handling which was done in the hook already) | 606 | * generic parsing (needed special handling which was done in the hook already) |
606 | * input_mapped shall return negative to inform the layer that this usage | 607 | * input_mapped shall return negative to inform the layer that this usage |
607 | * should not be considered for further processing or zero to notify that | 608 | * should not be considered for further processing or zero to notify that |
608 | * no processing was performed and should be done in a generic manner | 609 | * no processing was performed and should be done in a generic manner |
609 | * Both these functions may be NULL which means the same behavior as returning | 610 | * Both these functions may be NULL which means the same behavior as returning |
610 | * zero from them. | 611 | * zero from them. |
611 | */ | 612 | */ |
612 | struct hid_driver { | 613 | struct hid_driver { |
613 | char *name; | 614 | char *name; |
614 | const struct hid_device_id *id_table; | 615 | const struct hid_device_id *id_table; |
615 | 616 | ||
616 | struct list_head dyn_list; | 617 | struct list_head dyn_list; |
617 | spinlock_t dyn_lock; | 618 | spinlock_t dyn_lock; |
618 | 619 | ||
619 | int (*probe)(struct hid_device *dev, const struct hid_device_id *id); | 620 | int (*probe)(struct hid_device *dev, const struct hid_device_id *id); |
620 | void (*remove)(struct hid_device *dev); | 621 | void (*remove)(struct hid_device *dev); |
621 | 622 | ||
622 | const struct hid_report_id *report_table; | 623 | const struct hid_report_id *report_table; |
623 | int (*raw_event)(struct hid_device *hdev, struct hid_report *report, | 624 | int (*raw_event)(struct hid_device *hdev, struct hid_report *report, |
624 | u8 *data, int size); | 625 | u8 *data, int size); |
625 | const struct hid_usage_id *usage_table; | 626 | const struct hid_usage_id *usage_table; |
626 | int (*event)(struct hid_device *hdev, struct hid_field *field, | 627 | int (*event)(struct hid_device *hdev, struct hid_field *field, |
627 | struct hid_usage *usage, __s32 value); | 628 | struct hid_usage *usage, __s32 value); |
628 | 629 | ||
629 | void (*report_fixup)(struct hid_device *hdev, __u8 *buf, | 630 | void (*report_fixup)(struct hid_device *hdev, __u8 *buf, |
630 | unsigned int size); | 631 | unsigned int size); |
631 | 632 | ||
632 | int (*input_mapping)(struct hid_device *hdev, | 633 | int (*input_mapping)(struct hid_device *hdev, |
633 | struct hid_input *hidinput, struct hid_field *field, | 634 | struct hid_input *hidinput, struct hid_field *field, |
634 | struct hid_usage *usage, unsigned long **bit, int *max); | 635 | struct hid_usage *usage, unsigned long **bit, int *max); |
635 | int (*input_mapped)(struct hid_device *hdev, | 636 | int (*input_mapped)(struct hid_device *hdev, |
636 | struct hid_input *hidinput, struct hid_field *field, | 637 | struct hid_input *hidinput, struct hid_field *field, |
637 | struct hid_usage *usage, unsigned long **bit, int *max); | 638 | struct hid_usage *usage, unsigned long **bit, int *max); |
638 | #ifdef CONFIG_PM | 639 | #ifdef CONFIG_PM |
639 | int (*suspend)(struct hid_device *hdev, pm_message_t message); | 640 | int (*suspend)(struct hid_device *hdev, pm_message_t message); |
640 | int (*resume)(struct hid_device *hdev); | 641 | int (*resume)(struct hid_device *hdev); |
641 | int (*reset_resume)(struct hid_device *hdev); | 642 | int (*reset_resume)(struct hid_device *hdev); |
642 | #endif | 643 | #endif |
643 | /* private: */ | 644 | /* private: */ |
644 | struct device_driver driver; | 645 | struct device_driver driver; |
645 | }; | 646 | }; |
646 | 647 | ||
647 | /** | 648 | /** |
648 | * hid_ll_driver - low level driver callbacks | 649 | * hid_ll_driver - low level driver callbacks |
649 | * @start: called on probe to start the device | 650 | * @start: called on probe to start the device |
650 | * @stop: called on remove | 651 | * @stop: called on remove |
651 | * @open: called by input layer on open | 652 | * @open: called by input layer on open |
652 | * @close: called by input layer on close | 653 | * @close: called by input layer on close |
653 | * @hidinput_input_event: event input event (e.g. ff or leds) | 654 | * @hidinput_input_event: event input event (e.g. ff or leds) |
654 | * @parse: this method is called only once to parse the device data, | 655 | * @parse: this method is called only once to parse the device data, |
655 | * shouldn't allocate anything to not leak memory | 656 | * shouldn't allocate anything to not leak memory |
656 | */ | 657 | */ |
657 | struct hid_ll_driver { | 658 | struct hid_ll_driver { |
658 | int (*start)(struct hid_device *hdev); | 659 | int (*start)(struct hid_device *hdev); |
659 | void (*stop)(struct hid_device *hdev); | 660 | void (*stop)(struct hid_device *hdev); |
660 | 661 | ||
661 | int (*open)(struct hid_device *hdev); | 662 | int (*open)(struct hid_device *hdev); |
662 | void (*close)(struct hid_device *hdev); | 663 | void (*close)(struct hid_device *hdev); |
663 | 664 | ||
664 | int (*power)(struct hid_device *hdev, int level); | 665 | int (*power)(struct hid_device *hdev, int level); |
665 | 666 | ||
666 | int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, | 667 | int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, |
667 | unsigned int code, int value); | 668 | unsigned int code, int value); |
668 | 669 | ||
669 | int (*parse)(struct hid_device *hdev); | 670 | int (*parse)(struct hid_device *hdev); |
670 | }; | 671 | }; |
671 | 672 | ||
672 | #define PM_HINT_FULLON 1<<5 | 673 | #define PM_HINT_FULLON 1<<5 |
673 | #define PM_HINT_NORMAL 1<<1 | 674 | #define PM_HINT_NORMAL 1<<1 |
674 | 675 | ||
675 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ | 676 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ |
676 | /* We ignore a few input applications that are not widely used */ | 677 | /* We ignore a few input applications that are not widely used */ |
677 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || ((a >= 0x000d0002) && (a <= 0x000d0006))) | 678 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || ((a >= 0x000d0002) && (a <= 0x000d0006))) |
678 | 679 | ||
679 | /* HID core API */ | 680 | /* HID core API */ |
680 | 681 | ||
681 | extern int hid_debug; | 682 | extern int hid_debug; |
682 | 683 | ||
683 | extern int hid_add_device(struct hid_device *); | 684 | extern int hid_add_device(struct hid_device *); |
684 | extern void hid_destroy_device(struct hid_device *); | 685 | extern void hid_destroy_device(struct hid_device *); |
685 | 686 | ||
686 | extern int __must_check __hid_register_driver(struct hid_driver *, | 687 | extern int __must_check __hid_register_driver(struct hid_driver *, |
687 | struct module *, const char *mod_name); | 688 | struct module *, const char *mod_name); |
688 | static inline int __must_check hid_register_driver(struct hid_driver *driver) | 689 | static inline int __must_check hid_register_driver(struct hid_driver *driver) |
689 | { | 690 | { |
690 | return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); | 691 | return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); |
691 | } | 692 | } |
692 | extern void hid_unregister_driver(struct hid_driver *); | 693 | extern void hid_unregister_driver(struct hid_driver *); |
693 | 694 | ||
694 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 695 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
695 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | 696 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); |
696 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); | 697 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); |
697 | extern void hidinput_disconnect(struct hid_device *); | 698 | extern void hidinput_disconnect(struct hid_device *); |
698 | 699 | ||
699 | int hid_set_field(struct hid_field *, unsigned, __s32); | 700 | int hid_set_field(struct hid_field *, unsigned, __s32); |
700 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); | 701 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); |
701 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); | 702 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
702 | void hid_output_report(struct hid_report *report, __u8 *data); | 703 | void hid_output_report(struct hid_report *report, __u8 *data); |
703 | struct hid_device *hid_allocate_device(void); | 704 | struct hid_device *hid_allocate_device(void); |
704 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); | 705 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); |
705 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | 706 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
706 | int hid_check_keys_pressed(struct hid_device *hid); | 707 | int hid_check_keys_pressed(struct hid_device *hid); |
707 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | 708 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); |
708 | void hid_disconnect(struct hid_device *hid); | 709 | void hid_disconnect(struct hid_device *hid); |
709 | 710 | ||
710 | /** | 711 | /** |
711 | * hid_map_usage - map usage input bits | 712 | * hid_map_usage - map usage input bits |
712 | * | 713 | * |
713 | * @hidinput: hidinput which we are interested in | 714 | * @hidinput: hidinput which we are interested in |
714 | * @usage: usage to fill in | 715 | * @usage: usage to fill in |
715 | * @bit: pointer to input->{}bit (out parameter) | 716 | * @bit: pointer to input->{}bit (out parameter) |
716 | * @max: maximal valid usage->code to consider later (out parameter) | 717 | * @max: maximal valid usage->code to consider later (out parameter) |
717 | * @type: input event type (EV_KEY, EV_REL, ...) | 718 | * @type: input event type (EV_KEY, EV_REL, ...) |
718 | * @c: code which corresponds to this usage and type | 719 | * @c: code which corresponds to this usage and type |
719 | */ | 720 | */ |
720 | static inline void hid_map_usage(struct hid_input *hidinput, | 721 | static inline void hid_map_usage(struct hid_input *hidinput, |
721 | struct hid_usage *usage, unsigned long **bit, int *max, | 722 | struct hid_usage *usage, unsigned long **bit, int *max, |
722 | __u8 type, __u16 c) | 723 | __u8 type, __u16 c) |
723 | { | 724 | { |
724 | struct input_dev *input = hidinput->input; | 725 | struct input_dev *input = hidinput->input; |
725 | 726 | ||
726 | usage->type = type; | 727 | usage->type = type; |
727 | usage->code = c; | 728 | usage->code = c; |
728 | 729 | ||
729 | switch (type) { | 730 | switch (type) { |
730 | case EV_ABS: | 731 | case EV_ABS: |
731 | *bit = input->absbit; | 732 | *bit = input->absbit; |
732 | *max = ABS_MAX; | 733 | *max = ABS_MAX; |
733 | break; | 734 | break; |
734 | case EV_REL: | 735 | case EV_REL: |
735 | *bit = input->relbit; | 736 | *bit = input->relbit; |
736 | *max = REL_MAX; | 737 | *max = REL_MAX; |
737 | break; | 738 | break; |
738 | case EV_KEY: | 739 | case EV_KEY: |
739 | *bit = input->keybit; | 740 | *bit = input->keybit; |
740 | *max = KEY_MAX; | 741 | *max = KEY_MAX; |
741 | break; | 742 | break; |
742 | case EV_LED: | 743 | case EV_LED: |
743 | *bit = input->ledbit; | 744 | *bit = input->ledbit; |
744 | *max = LED_MAX; | 745 | *max = LED_MAX; |
745 | break; | 746 | break; |
746 | } | 747 | } |
747 | } | 748 | } |
748 | 749 | ||
749 | /** | 750 | /** |
750 | * hid_map_usage_clear - map usage input bits and clear the input bit | 751 | * hid_map_usage_clear - map usage input bits and clear the input bit |
751 | * | 752 | * |
752 | * The same as hid_map_usage, except the @c bit is also cleared in supported | 753 | * The same as hid_map_usage, except the @c bit is also cleared in supported |
753 | * bits (@bit). | 754 | * bits (@bit). |
754 | */ | 755 | */ |
755 | static inline void hid_map_usage_clear(struct hid_input *hidinput, | 756 | static inline void hid_map_usage_clear(struct hid_input *hidinput, |
756 | struct hid_usage *usage, unsigned long **bit, int *max, | 757 | struct hid_usage *usage, unsigned long **bit, int *max, |
757 | __u8 type, __u16 c) | 758 | __u8 type, __u16 c) |
758 | { | 759 | { |
759 | hid_map_usage(hidinput, usage, bit, max, type, c); | 760 | hid_map_usage(hidinput, usage, bit, max, type, c); |
760 | clear_bit(c, *bit); | 761 | clear_bit(c, *bit); |
761 | } | 762 | } |
762 | 763 | ||
763 | /** | 764 | /** |
764 | * hid_parse - parse HW reports | 765 | * hid_parse - parse HW reports |
765 | * | 766 | * |
766 | * @hdev: hid device | 767 | * @hdev: hid device |
767 | * | 768 | * |
768 | * Call this from probe after you set up the device (if needed). Your | 769 | * Call this from probe after you set up the device (if needed). Your |
769 | * report_fixup will be called (if non-NULL) after reading raw report from | 770 | * report_fixup will be called (if non-NULL) after reading raw report from |
770 | * device before passing it to hid layer for real parsing. | 771 | * device before passing it to hid layer for real parsing. |
771 | */ | 772 | */ |
772 | static inline int __must_check hid_parse(struct hid_device *hdev) | 773 | static inline int __must_check hid_parse(struct hid_device *hdev) |
773 | { | 774 | { |
774 | int ret; | 775 | int ret; |
775 | 776 | ||
776 | if (hdev->status & HID_STAT_PARSED) | 777 | if (hdev->status & HID_STAT_PARSED) |
777 | return 0; | 778 | return 0; |
778 | 779 | ||
779 | ret = hdev->ll_driver->parse(hdev); | 780 | ret = hdev->ll_driver->parse(hdev); |
780 | if (!ret) | 781 | if (!ret) |
781 | hdev->status |= HID_STAT_PARSED; | 782 | hdev->status |= HID_STAT_PARSED; |
782 | 783 | ||
783 | return ret; | 784 | return ret; |
784 | } | 785 | } |
785 | 786 | ||
786 | /** | 787 | /** |
787 | * hid_hw_start - start underlaying HW | 788 | * hid_hw_start - start underlaying HW |
788 | * | 789 | * |
789 | * @hdev: hid device | 790 | * @hdev: hid device |
790 | * @connect_mask: which outputs to connect, see HID_CONNECT_* | 791 | * @connect_mask: which outputs to connect, see HID_CONNECT_* |
791 | * | 792 | * |
792 | * Call this in probe function *after* hid_parse. This will setup HW buffers | 793 | * Call this in probe function *after* hid_parse. This will setup HW buffers |
793 | * and start the device (if not deffered to device open). hid_hw_stop must be | 794 | * and start the device (if not deffered to device open). hid_hw_stop must be |
794 | * called if this was successfull. | 795 | * called if this was successfull. |
795 | */ | 796 | */ |
796 | static inline int __must_check hid_hw_start(struct hid_device *hdev, | 797 | static inline int __must_check hid_hw_start(struct hid_device *hdev, |
797 | unsigned int connect_mask) | 798 | unsigned int connect_mask) |
798 | { | 799 | { |
799 | int ret = hdev->ll_driver->start(hdev); | 800 | int ret = hdev->ll_driver->start(hdev); |
800 | if (ret || !connect_mask) | 801 | if (ret || !connect_mask) |
801 | return ret; | 802 | return ret; |
802 | ret = hid_connect(hdev, connect_mask); | 803 | ret = hid_connect(hdev, connect_mask); |
803 | if (ret) | 804 | if (ret) |
804 | hdev->ll_driver->stop(hdev); | 805 | hdev->ll_driver->stop(hdev); |
805 | return ret; | 806 | return ret; |
806 | } | 807 | } |
807 | 808 | ||
808 | /** | 809 | /** |
809 | * hid_hw_stop - stop underlaying HW | 810 | * hid_hw_stop - stop underlaying HW |
810 | * | 811 | * |
811 | * @hdev: hid device | 812 | * @hdev: hid device |
812 | * | 813 | * |
813 | * This is usually called from remove function or from probe when something | 814 | * This is usually called from remove function or from probe when something |
814 | * failed and hid_hw_start was called already. | 815 | * failed and hid_hw_start was called already. |
815 | */ | 816 | */ |
816 | static inline void hid_hw_stop(struct hid_device *hdev) | 817 | static inline void hid_hw_stop(struct hid_device *hdev) |
817 | { | 818 | { |
818 | hid_disconnect(hdev); | 819 | hid_disconnect(hdev); |
819 | hdev->ll_driver->stop(hdev); | 820 | hdev->ll_driver->stop(hdev); |
820 | } | 821 | } |
821 | 822 | ||
822 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 823 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
823 | int interrupt); | 824 | int interrupt); |
824 | 825 | ||
825 | extern int hid_generic_init(void); | 826 | extern int hid_generic_init(void); |
826 | extern void hid_generic_exit(void); | 827 | extern void hid_generic_exit(void); |
827 | 828 | ||
828 | /* HID quirks API */ | 829 | /* HID quirks API */ |
829 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); | 830 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); |
830 | int usbhid_quirks_init(char **quirks_param); | 831 | int usbhid_quirks_init(char **quirks_param); |
831 | void usbhid_quirks_exit(void); | 832 | void usbhid_quirks_exit(void); |
832 | void usbhid_set_leds(struct hid_device *hid); | 833 | void usbhid_set_leds(struct hid_device *hid); |
833 | 834 | ||
834 | #ifdef CONFIG_HID_PID | 835 | #ifdef CONFIG_HID_PID |
835 | int hid_pidff_init(struct hid_device *hid); | 836 | int hid_pidff_init(struct hid_device *hid); |
836 | #else | 837 | #else |
837 | #define hid_pidff_init NULL | 838 | #define hid_pidff_init NULL |
838 | #endif | 839 | #endif |
839 | 840 | ||
840 | #define dbg_hid(format, arg...) if (hid_debug) \ | 841 | #define dbg_hid(format, arg...) if (hid_debug) \ |
841 | printk(KERN_DEBUG "%s: " format ,\ | 842 | printk(KERN_DEBUG "%s: " format ,\ |
842 | __FILE__ , ## arg) | 843 | __FILE__ , ## arg) |
843 | #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ | 844 | #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ |
844 | __FILE__ , ## arg) | 845 | __FILE__ , ## arg) |
845 | #endif /* HID_FF */ | 846 | #endif /* HID_FF */ |
846 | 847 | ||
847 | #endif | 848 | #endif |
848 | 849 | ||
849 | 850 |