Commit afa5eb7c68689ced4284f01c96feed44a2d0a127
Committed by
Jiri Kosina
1 parent
b2ddd54e19
Exists in
master
and in
39 other branches
HID: remove compat stuff
This removal was scheduled and there is no problem with later distros to adapt for the new bus, thanks to aliases. module-init-tools map files are deprecated nowadays, so that the patch which introduced hid ones into the m-i-t won't be accepted and hence there is no reason for leaving compat stuff in. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Showing 30 changed files with 0 additions and 195 deletions Inline Diff
- Documentation/feature-removal-schedule.txt
- drivers/hid/Kconfig
- drivers/hid/Makefile
- drivers/hid/hid-a4tech.c
- drivers/hid/hid-apple.c
- drivers/hid/hid-belkin.c
- drivers/hid/hid-cherry.c
- drivers/hid/hid-chicony.c
- drivers/hid/hid-core.c
- drivers/hid/hid-cypress.c
- drivers/hid/hid-drff.c
- drivers/hid/hid-dummy.c
- drivers/hid/hid-ezkey.c
- drivers/hid/hid-gaff.c
- drivers/hid/hid-gyration.c
- drivers/hid/hid-kensington.c
- drivers/hid/hid-kye.c
- drivers/hid/hid-lg.c
- drivers/hid/hid-microsoft.c
- drivers/hid/hid-monterey.c
- drivers/hid/hid-ntrig.c
- drivers/hid/hid-petalynx.c
- drivers/hid/hid-pl.c
- drivers/hid/hid-samsung.c
- drivers/hid/hid-sony.c
- drivers/hid/hid-sunplus.c
- drivers/hid/hid-tmff.c
- drivers/hid/hid-topseed.c
- drivers/hid/hid-zpff.c
- include/linux/hid.h
Documentation/feature-removal-schedule.txt
1 | The following is a list of files and features that are going to be | 1 | The following is a list of files and features that are going to be |
2 | removed in the kernel source tree. Every entry should contain what | 2 | removed in the kernel source tree. Every entry should contain what |
3 | exactly is going away, why it is happening, and who is going to be doing | 3 | exactly is going away, why it is happening, and who is going to be doing |
4 | the work. When the feature is removed from the kernel, it should also | 4 | the work. When the feature is removed from the kernel, it should also |
5 | be removed from this file. | 5 | be removed from this file. |
6 | 6 | ||
7 | --------------------------- | 7 | --------------------------- |
8 | 8 | ||
9 | What: The ieee80211_regdom module parameter | 9 | What: The ieee80211_regdom module parameter |
10 | When: March 2010 / desktop catchup | 10 | When: March 2010 / desktop catchup |
11 | 11 | ||
12 | Why: This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code, | 12 | Why: This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code, |
13 | and currently serves as an option for users to define an | 13 | and currently serves as an option for users to define an |
14 | ISO / IEC 3166 alpha2 code for the country they are currently | 14 | ISO / IEC 3166 alpha2 code for the country they are currently |
15 | present in. Although there are userspace API replacements for this | 15 | present in. Although there are userspace API replacements for this |
16 | through nl80211 distributions haven't yet caught up with implementing | 16 | through nl80211 distributions haven't yet caught up with implementing |
17 | decent alternatives through standard GUIs. Although available as an | 17 | decent alternatives through standard GUIs. Although available as an |
18 | option through iw or wpa_supplicant its just a matter of time before | 18 | option through iw or wpa_supplicant its just a matter of time before |
19 | distributions pick up good GUI options for this. The ideal solution | 19 | distributions pick up good GUI options for this. The ideal solution |
20 | would actually consist of intelligent designs which would do this for | 20 | would actually consist of intelligent designs which would do this for |
21 | the user automatically even when travelling through different countries. | 21 | the user automatically even when travelling through different countries. |
22 | Until then we leave this module parameter as a compromise. | 22 | Until then we leave this module parameter as a compromise. |
23 | 23 | ||
24 | When userspace improves with reasonable widely-available alternatives for | 24 | When userspace improves with reasonable widely-available alternatives for |
25 | this we will no longer need this module parameter. This entry hopes that | 25 | this we will no longer need this module parameter. This entry hopes that |
26 | by the super-futuristically looking date of "March 2010" we will have | 26 | by the super-futuristically looking date of "March 2010" we will have |
27 | such replacements widely available. | 27 | such replacements widely available. |
28 | 28 | ||
29 | Who: Luis R. Rodriguez <lrodriguez@atheros.com> | 29 | Who: Luis R. Rodriguez <lrodriguez@atheros.com> |
30 | 30 | ||
31 | --------------------------- | 31 | --------------------------- |
32 | 32 | ||
33 | What: CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information | 33 | What: CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information |
34 | When: March 2010 / desktop catchup | 34 | When: March 2010 / desktop catchup |
35 | 35 | ||
36 | Why: The old regulatory infrastructure has been replaced with a new one | 36 | Why: The old regulatory infrastructure has been replaced with a new one |
37 | which does not require statically defined regulatory domains. We do | 37 | which does not require statically defined regulatory domains. We do |
38 | not want to keep static regulatory domains in the kernel due to the | 38 | not want to keep static regulatory domains in the kernel due to the |
39 | the dynamic nature of regulatory law and localization. We kept around | 39 | the dynamic nature of regulatory law and localization. We kept around |
40 | the old static definitions for the regulatory domains of: | 40 | the old static definitions for the regulatory domains of: |
41 | 41 | ||
42 | * US | 42 | * US |
43 | * JP | 43 | * JP |
44 | * EU | 44 | * EU |
45 | 45 | ||
46 | and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was | 46 | and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was |
47 | set. We will remove this option once the standard Linux desktop catches | 47 | set. We will remove this option once the standard Linux desktop catches |
48 | up with the new userspace APIs we have implemented. | 48 | up with the new userspace APIs we have implemented. |
49 | 49 | ||
50 | Who: Luis R. Rodriguez <lrodriguez@atheros.com> | 50 | Who: Luis R. Rodriguez <lrodriguez@atheros.com> |
51 | 51 | ||
52 | --------------------------- | 52 | --------------------------- |
53 | 53 | ||
54 | What: dev->power.power_state | 54 | What: dev->power.power_state |
55 | When: July 2007 | 55 | When: July 2007 |
56 | Why: Broken design for runtime control over driver power states, confusing | 56 | Why: Broken design for runtime control over driver power states, confusing |
57 | driver-internal runtime power management with: mechanisms to support | 57 | driver-internal runtime power management with: mechanisms to support |
58 | system-wide sleep state transitions; event codes that distinguish | 58 | system-wide sleep state transitions; event codes that distinguish |
59 | different phases of swsusp "sleep" transitions; and userspace policy | 59 | different phases of swsusp "sleep" transitions; and userspace policy |
60 | inputs. This framework was never widely used, and most attempts to | 60 | inputs. This framework was never widely used, and most attempts to |
61 | use it were broken. Drivers should instead be exposing domain-specific | 61 | use it were broken. Drivers should instead be exposing domain-specific |
62 | interfaces either to kernel or to userspace. | 62 | interfaces either to kernel or to userspace. |
63 | Who: Pavel Machek <pavel@suse.cz> | 63 | Who: Pavel Machek <pavel@suse.cz> |
64 | 64 | ||
65 | --------------------------- | 65 | --------------------------- |
66 | 66 | ||
67 | What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. | 67 | What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. |
68 | When: December 2008 | 68 | When: December 2008 |
69 | Files: include/linux/video_decoder.h include/linux/videodev.h | 69 | Files: include/linux/video_decoder.h include/linux/videodev.h |
70 | Check: include/linux/video_decoder.h include/linux/videodev.h | 70 | Check: include/linux/video_decoder.h include/linux/videodev.h |
71 | Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6 | 71 | Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6 |
72 | series. The old API have lots of drawbacks and don't provide enough | 72 | series. The old API have lots of drawbacks and don't provide enough |
73 | means to work with all video and audio standards. The newer API is | 73 | means to work with all video and audio standards. The newer API is |
74 | already available on the main drivers and should be used instead. | 74 | already available on the main drivers and should be used instead. |
75 | Newer drivers should use v4l_compat_translate_ioctl function to handle | 75 | Newer drivers should use v4l_compat_translate_ioctl function to handle |
76 | old calls, replacing to newer ones. | 76 | old calls, replacing to newer ones. |
77 | Decoder iocts are using internally to allow video drivers to | 77 | Decoder iocts are using internally to allow video drivers to |
78 | communicate with video decoders. This should also be improved to allow | 78 | communicate with video decoders. This should also be improved to allow |
79 | V4L2 calls being translated into compatible internal ioctls. | 79 | V4L2 calls being translated into compatible internal ioctls. |
80 | Compatibility ioctls will be provided, for a while, via | 80 | Compatibility ioctls will be provided, for a while, via |
81 | v4l1-compat module. | 81 | v4l1-compat module. |
82 | Who: Mauro Carvalho Chehab <mchehab@infradead.org> | 82 | Who: Mauro Carvalho Chehab <mchehab@infradead.org> |
83 | 83 | ||
84 | --------------------------- | 84 | --------------------------- |
85 | 85 | ||
86 | What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) | 86 | What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) |
87 | When: November 2005 | 87 | When: November 2005 |
88 | Files: drivers/pcmcia/: pcmcia_ioctl.c | 88 | Files: drivers/pcmcia/: pcmcia_ioctl.c |
89 | Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a | 89 | Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a |
90 | normal hotpluggable bus, and with it using the default kernel | 90 | normal hotpluggable bus, and with it using the default kernel |
91 | infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA | 91 | infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA |
92 | control ioctl needed by cardmgr and cardctl from pcmcia-cs is | 92 | control ioctl needed by cardmgr and cardctl from pcmcia-cs is |
93 | unnecessary, and makes further cleanups and integration of the | 93 | unnecessary, and makes further cleanups and integration of the |
94 | PCMCIA subsystem into the Linux kernel device driver model more | 94 | PCMCIA subsystem into the Linux kernel device driver model more |
95 | difficult. The features provided by cardmgr and cardctl are either | 95 | difficult. The features provided by cardmgr and cardctl are either |
96 | handled by the kernel itself now or are available in the new | 96 | handled by the kernel itself now or are available in the new |
97 | pcmciautils package available at | 97 | pcmciautils package available at |
98 | http://kernel.org/pub/linux/utils/kernel/pcmcia/ | 98 | http://kernel.org/pub/linux/utils/kernel/pcmcia/ |
99 | Who: Dominik Brodowski <linux@brodo.de> | 99 | Who: Dominik Brodowski <linux@brodo.de> |
100 | 100 | ||
101 | --------------------------- | 101 | --------------------------- |
102 | 102 | ||
103 | What: sys_sysctl | 103 | What: sys_sysctl |
104 | When: September 2010 | 104 | When: September 2010 |
105 | Option: CONFIG_SYSCTL_SYSCALL | 105 | Option: CONFIG_SYSCTL_SYSCALL |
106 | Why: The same information is available in a more convenient from | 106 | Why: The same information is available in a more convenient from |
107 | /proc/sys, and none of the sysctl variables appear to be | 107 | /proc/sys, and none of the sysctl variables appear to be |
108 | important performance wise. | 108 | important performance wise. |
109 | 109 | ||
110 | Binary sysctls are a long standing source of subtle kernel | 110 | Binary sysctls are a long standing source of subtle kernel |
111 | bugs and security issues. | 111 | bugs and security issues. |
112 | 112 | ||
113 | When I looked several months ago all I could find after | 113 | When I looked several months ago all I could find after |
114 | searching several distributions were 5 user space programs and | 114 | searching several distributions were 5 user space programs and |
115 | glibc (which falls back to /proc/sys) using this syscall. | 115 | glibc (which falls back to /proc/sys) using this syscall. |
116 | 116 | ||
117 | The man page for sysctl(2) documents it as unusable for user | 117 | The man page for sysctl(2) documents it as unusable for user |
118 | space programs. | 118 | space programs. |
119 | 119 | ||
120 | sysctl(2) is not generally ABI compatible to a 32bit user | 120 | sysctl(2) is not generally ABI compatible to a 32bit user |
121 | space application on a 64bit and a 32bit kernel. | 121 | space application on a 64bit and a 32bit kernel. |
122 | 122 | ||
123 | For the last several months the policy has been no new binary | 123 | For the last several months the policy has been no new binary |
124 | sysctls and no one has put forward an argument to use them. | 124 | sysctls and no one has put forward an argument to use them. |
125 | 125 | ||
126 | Binary sysctls issues seem to keep happening appearing so | 126 | Binary sysctls issues seem to keep happening appearing so |
127 | properly deprecating them (with a warning to user space) and a | 127 | properly deprecating them (with a warning to user space) and a |
128 | 2 year grace warning period will mean eventually we can kill | 128 | 2 year grace warning period will mean eventually we can kill |
129 | them and end the pain. | 129 | them and end the pain. |
130 | 130 | ||
131 | In the mean time individual binary sysctls can be dealt with | 131 | In the mean time individual binary sysctls can be dealt with |
132 | in a piecewise fashion. | 132 | in a piecewise fashion. |
133 | 133 | ||
134 | Who: Eric Biederman <ebiederm@xmission.com> | 134 | Who: Eric Biederman <ebiederm@xmission.com> |
135 | 135 | ||
136 | --------------------------- | 136 | --------------------------- |
137 | 137 | ||
138 | What: remove EXPORT_SYMBOL(kernel_thread) | 138 | What: remove EXPORT_SYMBOL(kernel_thread) |
139 | When: August 2006 | 139 | When: August 2006 |
140 | Files: arch/*/kernel/*_ksyms.c | 140 | Files: arch/*/kernel/*_ksyms.c |
141 | Check: kernel_thread | 141 | Check: kernel_thread |
142 | Why: kernel_thread is a low-level implementation detail. Drivers should | 142 | Why: kernel_thread is a low-level implementation detail. Drivers should |
143 | use the <linux/kthread.h> API instead which shields them from | 143 | use the <linux/kthread.h> API instead which shields them from |
144 | implementation details and provides a higherlevel interface that | 144 | implementation details and provides a higherlevel interface that |
145 | prevents bugs and code duplication | 145 | prevents bugs and code duplication |
146 | Who: Christoph Hellwig <hch@lst.de> | 146 | Who: Christoph Hellwig <hch@lst.de> |
147 | 147 | ||
148 | --------------------------- | 148 | --------------------------- |
149 | 149 | ||
150 | What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports | 150 | What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports |
151 | (temporary transition config option provided until then) | 151 | (temporary transition config option provided until then) |
152 | The transition config option will also be removed at the same time. | 152 | The transition config option will also be removed at the same time. |
153 | When: before 2.6.19 | 153 | When: before 2.6.19 |
154 | Why: Unused symbols are both increasing the size of the kernel binary | 154 | Why: Unused symbols are both increasing the size of the kernel binary |
155 | and are often a sign of "wrong API" | 155 | and are often a sign of "wrong API" |
156 | Who: Arjan van de Ven <arjan@linux.intel.com> | 156 | Who: Arjan van de Ven <arjan@linux.intel.com> |
157 | 157 | ||
158 | --------------------------- | 158 | --------------------------- |
159 | 159 | ||
160 | What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment | 160 | What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment |
161 | When: October 2008 | 161 | When: October 2008 |
162 | Why: The stacking of class devices makes these values misleading and | 162 | Why: The stacking of class devices makes these values misleading and |
163 | inconsistent. | 163 | inconsistent. |
164 | Class devices should not carry any of these properties, and bus | 164 | Class devices should not carry any of these properties, and bus |
165 | devices have SUBSYTEM and DRIVER as a replacement. | 165 | devices have SUBSYTEM and DRIVER as a replacement. |
166 | Who: Kay Sievers <kay.sievers@suse.de> | 166 | Who: Kay Sievers <kay.sievers@suse.de> |
167 | 167 | ||
168 | --------------------------- | 168 | --------------------------- |
169 | 169 | ||
170 | What: ACPI procfs interface | 170 | What: ACPI procfs interface |
171 | When: July 2008 | 171 | When: July 2008 |
172 | Why: ACPI sysfs conversion should be finished by January 2008. | 172 | Why: ACPI sysfs conversion should be finished by January 2008. |
173 | ACPI procfs interface will be removed in July 2008 so that | 173 | ACPI procfs interface will be removed in July 2008 so that |
174 | there is enough time for the user space to catch up. | 174 | there is enough time for the user space to catch up. |
175 | Who: Zhang Rui <rui.zhang@intel.com> | 175 | Who: Zhang Rui <rui.zhang@intel.com> |
176 | 176 | ||
177 | --------------------------- | 177 | --------------------------- |
178 | 178 | ||
179 | What: /proc/acpi/button | 179 | What: /proc/acpi/button |
180 | When: August 2007 | 180 | When: August 2007 |
181 | Why: /proc/acpi/button has been replaced by events to the input layer | 181 | Why: /proc/acpi/button has been replaced by events to the input layer |
182 | since 2.6.20. | 182 | since 2.6.20. |
183 | Who: Len Brown <len.brown@intel.com> | 183 | Who: Len Brown <len.brown@intel.com> |
184 | 184 | ||
185 | --------------------------- | 185 | --------------------------- |
186 | 186 | ||
187 | What: /proc/acpi/event | 187 | What: /proc/acpi/event |
188 | When: February 2008 | 188 | When: February 2008 |
189 | Why: /proc/acpi/event has been replaced by events via the input layer | 189 | Why: /proc/acpi/event has been replaced by events via the input layer |
190 | and netlink since 2.6.23. | 190 | and netlink since 2.6.23. |
191 | Who: Len Brown <len.brown@intel.com> | 191 | Who: Len Brown <len.brown@intel.com> |
192 | 192 | ||
193 | --------------------------- | 193 | --------------------------- |
194 | 194 | ||
195 | What: libata spindown skipping and warning | 195 | What: libata spindown skipping and warning |
196 | When: Dec 2008 | 196 | When: Dec 2008 |
197 | Why: Some halt(8) implementations synchronize caches for and spin | 197 | Why: Some halt(8) implementations synchronize caches for and spin |
198 | down libata disks because libata didn't use to spin down disk on | 198 | down libata disks because libata didn't use to spin down disk on |
199 | system halt (only synchronized caches). | 199 | system halt (only synchronized caches). |
200 | Spin down on system halt is now implemented. sysfs node | 200 | Spin down on system halt is now implemented. sysfs node |
201 | /sys/class/scsi_disk/h:c:i:l/manage_start_stop is present if | 201 | /sys/class/scsi_disk/h:c:i:l/manage_start_stop is present if |
202 | spin down support is available. | 202 | spin down support is available. |
203 | Because issuing spin down command to an already spun down disk | 203 | Because issuing spin down command to an already spun down disk |
204 | makes some disks spin up just to spin down again, libata tracks | 204 | makes some disks spin up just to spin down again, libata tracks |
205 | device spindown status to skip the extra spindown command and | 205 | device spindown status to skip the extra spindown command and |
206 | warn about it. | 206 | warn about it. |
207 | This is to give userspace tools the time to get updated and will | 207 | This is to give userspace tools the time to get updated and will |
208 | be removed after userspace is reasonably updated. | 208 | be removed after userspace is reasonably updated. |
209 | Who: Tejun Heo <htejun@gmail.com> | 209 | Who: Tejun Heo <htejun@gmail.com> |
210 | 210 | ||
211 | --------------------------- | 211 | --------------------------- |
212 | 212 | ||
213 | What: i386/x86_64 bzImage symlinks | 213 | What: i386/x86_64 bzImage symlinks |
214 | When: April 2010 | 214 | When: April 2010 |
215 | 215 | ||
216 | Why: The i386/x86_64 merge provides a symlink to the old bzImage | 216 | Why: The i386/x86_64 merge provides a symlink to the old bzImage |
217 | location so not yet updated user space tools, e.g. package | 217 | location so not yet updated user space tools, e.g. package |
218 | scripts, do not break. | 218 | scripts, do not break. |
219 | Who: Thomas Gleixner <tglx@linutronix.de> | 219 | Who: Thomas Gleixner <tglx@linutronix.de> |
220 | 220 | ||
221 | --------------------------- | 221 | --------------------------- |
222 | 222 | ||
223 | What (Why): | 223 | What (Why): |
224 | - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files | 224 | - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files |
225 | (superseded by xt_TOS/xt_tos target & match) | 225 | (superseded by xt_TOS/xt_tos target & match) |
226 | 226 | ||
227 | - "forwarding" header files like ipt_mac.h in | 227 | - "forwarding" header files like ipt_mac.h in |
228 | include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/ | 228 | include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/ |
229 | 229 | ||
230 | - xt_CONNMARK match revision 0 | 230 | - xt_CONNMARK match revision 0 |
231 | (superseded by xt_CONNMARK match revision 1) | 231 | (superseded by xt_CONNMARK match revision 1) |
232 | 232 | ||
233 | - xt_MARK target revisions 0 and 1 | 233 | - xt_MARK target revisions 0 and 1 |
234 | (superseded by xt_MARK match revision 2) | 234 | (superseded by xt_MARK match revision 2) |
235 | 235 | ||
236 | - xt_connmark match revision 0 | 236 | - xt_connmark match revision 0 |
237 | (superseded by xt_connmark match revision 1) | 237 | (superseded by xt_connmark match revision 1) |
238 | 238 | ||
239 | - xt_conntrack match revision 0 | 239 | - xt_conntrack match revision 0 |
240 | (superseded by xt_conntrack match revision 1) | 240 | (superseded by xt_conntrack match revision 1) |
241 | 241 | ||
242 | - xt_iprange match revision 0, | 242 | - xt_iprange match revision 0, |
243 | include/linux/netfilter_ipv4/ipt_iprange.h | 243 | include/linux/netfilter_ipv4/ipt_iprange.h |
244 | (superseded by xt_iprange match revision 1) | 244 | (superseded by xt_iprange match revision 1) |
245 | 245 | ||
246 | - xt_mark match revision 0 | 246 | - xt_mark match revision 0 |
247 | (superseded by xt_mark match revision 1) | 247 | (superseded by xt_mark match revision 1) |
248 | 248 | ||
249 | - xt_recent: the old ipt_recent proc dir | 249 | - xt_recent: the old ipt_recent proc dir |
250 | (superseded by /proc/net/xt_recent) | 250 | (superseded by /proc/net/xt_recent) |
251 | 251 | ||
252 | When: January 2009 or Linux 2.7.0, whichever comes first | 252 | When: January 2009 or Linux 2.7.0, whichever comes first |
253 | Why: Superseded by newer revisions or modules | 253 | Why: Superseded by newer revisions or modules |
254 | Who: Jan Engelhardt <jengelh@computergmbh.de> | 254 | Who: Jan Engelhardt <jengelh@computergmbh.de> |
255 | 255 | ||
256 | --------------------------- | 256 | --------------------------- |
257 | 257 | ||
258 | What: b43 support for firmware revision < 410 | 258 | What: b43 support for firmware revision < 410 |
259 | When: The schedule was July 2008, but it was decided that we are going to keep the | 259 | When: The schedule was July 2008, but it was decided that we are going to keep the |
260 | code as long as there are no major maintanance headaches. | 260 | code as long as there are no major maintanance headaches. |
261 | So it _could_ be removed _any_ time now, if it conflicts with something new. | 261 | So it _could_ be removed _any_ time now, if it conflicts with something new. |
262 | Why: The support code for the old firmware hurts code readability/maintainability | 262 | Why: The support code for the old firmware hurts code readability/maintainability |
263 | and slightly hurts runtime performance. Bugfixes for the old firmware | 263 | and slightly hurts runtime performance. Bugfixes for the old firmware |
264 | are not provided by Broadcom anymore. | 264 | are not provided by Broadcom anymore. |
265 | Who: Michael Buesch <mb@bu3sch.de> | 265 | Who: Michael Buesch <mb@bu3sch.de> |
266 | 266 | ||
267 | --------------------------- | 267 | --------------------------- |
268 | 268 | ||
269 | What: usedac i386 kernel parameter | 269 | What: usedac i386 kernel parameter |
270 | When: 2.6.27 | 270 | When: 2.6.27 |
271 | Why: replaced by allowdac and no dac combination | 271 | Why: replaced by allowdac and no dac combination |
272 | Who: Glauber Costa <gcosta@redhat.com> | 272 | Who: Glauber Costa <gcosta@redhat.com> |
273 | 273 | ||
274 | --------------------------- | 274 | --------------------------- |
275 | 275 | ||
276 | What: remove HID compat support | ||
277 | When: 2.6.29 | ||
278 | Why: needed only as a temporary solution until distros fix themselves up | ||
279 | Who: Jiri Slaby <jirislaby@gmail.com> | ||
280 | |||
281 | --------------------------- | ||
282 | |||
283 | What: print_fn_descriptor_symbol() | 276 | What: print_fn_descriptor_symbol() |
284 | When: October 2009 | 277 | When: October 2009 |
285 | Why: The %pF vsprintf format provides the same functionality in a | 278 | Why: The %pF vsprintf format provides the same functionality in a |
286 | simpler way. print_fn_descriptor_symbol() is deprecated but | 279 | simpler way. print_fn_descriptor_symbol() is deprecated but |
287 | still present to give out-of-tree modules time to change. | 280 | still present to give out-of-tree modules time to change. |
288 | Who: Bjorn Helgaas <bjorn.helgaas@hp.com> | 281 | Who: Bjorn Helgaas <bjorn.helgaas@hp.com> |
289 | 282 | ||
290 | --------------------------- | 283 | --------------------------- |
291 | 284 | ||
292 | What: /sys/o2cb symlink | 285 | What: /sys/o2cb symlink |
293 | When: January 2010 | 286 | When: January 2010 |
294 | Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb | 287 | Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb |
295 | exists as a symlink for backwards compatibility for old versions of | 288 | exists as a symlink for backwards compatibility for old versions of |
296 | ocfs2-tools. 2 years should be sufficient time to phase in new versions | 289 | ocfs2-tools. 2 years should be sufficient time to phase in new versions |
297 | which know to look in /sys/fs/o2cb. | 290 | which know to look in /sys/fs/o2cb. |
298 | Who: ocfs2-devel@oss.oracle.com | 291 | Who: ocfs2-devel@oss.oracle.com |
299 | 292 | ||
300 | --------------------------- | 293 | --------------------------- |
301 | 294 | ||
302 | What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD, | 295 | What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD, |
303 | SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD | 296 | SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD |
304 | When: June 2009 | 297 | When: June 2009 |
305 | Why: A newer version of the options have been introduced in 2005 that | 298 | Why: A newer version of the options have been introduced in 2005 that |
306 | removes the limitions of the old API. The sctp library has been | 299 | removes the limitions of the old API. The sctp library has been |
307 | converted to use these new options at the same time. Any user | 300 | converted to use these new options at the same time. Any user |
308 | space app that directly uses the old options should convert to using | 301 | space app that directly uses the old options should convert to using |
309 | the new options. | 302 | the new options. |
310 | Who: Vlad Yasevich <vladislav.yasevich@hp.com> | 303 | Who: Vlad Yasevich <vladislav.yasevich@hp.com> |
311 | 304 | ||
312 | --------------------------- | 305 | --------------------------- |
313 | 306 | ||
314 | What: CONFIG_THERMAL_HWMON | 307 | What: CONFIG_THERMAL_HWMON |
315 | When: January 2009 | 308 | When: January 2009 |
316 | Why: This option was introduced just to allow older lm-sensors userspace | 309 | Why: This option was introduced just to allow older lm-sensors userspace |
317 | to keep working over the upgrade to 2.6.26. At the scheduled time of | 310 | to keep working over the upgrade to 2.6.26. At the scheduled time of |
318 | removal fixed lm-sensors (2.x or 3.x) should be readily available. | 311 | removal fixed lm-sensors (2.x or 3.x) should be readily available. |
319 | Who: Rene Herman <rene.herman@gmail.com> | 312 | Who: Rene Herman <rene.herman@gmail.com> |
320 | 313 | ||
321 | --------------------------- | 314 | --------------------------- |
322 | 315 | ||
323 | What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS | 316 | What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS |
324 | (in net/core/net-sysfs.c) | 317 | (in net/core/net-sysfs.c) |
325 | When: After the only user (hal) has seen a release with the patches | 318 | When: After the only user (hal) has seen a release with the patches |
326 | for enough time, probably some time in 2010. | 319 | for enough time, probably some time in 2010. |
327 | Why: Over 1K .text/.data size reduction, data is available in other | 320 | Why: Over 1K .text/.data size reduction, data is available in other |
328 | ways (ioctls) | 321 | ways (ioctls) |
329 | Who: Johannes Berg <johannes@sipsolutions.net> | 322 | Who: Johannes Berg <johannes@sipsolutions.net> |
330 | 323 | ||
331 | --------------------------- | 324 | --------------------------- |
332 | 325 | ||
333 | What: CONFIG_NF_CT_ACCT | 326 | What: CONFIG_NF_CT_ACCT |
334 | When: 2.6.29 | 327 | When: 2.6.29 |
335 | Why: Accounting can now be enabled/disabled without kernel recompilation. | 328 | Why: Accounting can now be enabled/disabled without kernel recompilation. |
336 | Currently used only to set a default value for a feature that is also | 329 | Currently used only to set a default value for a feature that is also |
337 | controlled by a kernel/module/sysfs/sysctl parameter. | 330 | controlled by a kernel/module/sysfs/sysctl parameter. |
338 | Who: Krzysztof Piotr Oledzki <ole@ans.pl> | 331 | Who: Krzysztof Piotr Oledzki <ole@ans.pl> |
339 | 332 | ||
340 | --------------------------- | 333 | --------------------------- |
341 | 334 | ||
342 | What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() | 335 | What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() |
343 | When: 2.6.30 | 336 | When: 2.6.30 |
344 | Check: i2c_attach_client i2c_detach_client | 337 | Check: i2c_attach_client i2c_detach_client |
345 | Why: Deprecated by the new (standard) device driver binding model. Use | 338 | Why: Deprecated by the new (standard) device driver binding model. Use |
346 | i2c_driver->probe() and ->remove() instead. | 339 | i2c_driver->probe() and ->remove() instead. |
347 | Who: Jean Delvare <khali@linux-fr.org> | 340 | Who: Jean Delvare <khali@linux-fr.org> |
348 | 341 | ||
349 | --------------------------- | 342 | --------------------------- |
350 | 343 | ||
351 | What: fscher and fscpos drivers | 344 | What: fscher and fscpos drivers |
352 | When: June 2009 | 345 | When: June 2009 |
353 | Why: Deprecated by the new fschmd driver. | 346 | Why: Deprecated by the new fschmd driver. |
354 | Who: Hans de Goede <hdegoede@redhat.com> | 347 | Who: Hans de Goede <hdegoede@redhat.com> |
355 | Jean Delvare <khali@linux-fr.org> | 348 | Jean Delvare <khali@linux-fr.org> |
356 | 349 | ||
357 | --------------------------- | 350 | --------------------------- |
358 | 351 | ||
359 | What: sysfs ui for changing p4-clockmod parameters | 352 | What: sysfs ui for changing p4-clockmod parameters |
360 | When: September 2009 | 353 | When: September 2009 |
361 | Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and | 354 | Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and |
362 | e088e4c9cdb618675874becb91b2fd581ee707e6. | 355 | e088e4c9cdb618675874becb91b2fd581ee707e6. |
363 | Removal is subject to fixing any remaining bugs in ACPI which may | 356 | Removal is subject to fixing any remaining bugs in ACPI which may |
364 | cause the thermal throttling not to happen at the right time. | 357 | cause the thermal throttling not to happen at the right time. |
365 | Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com> | 358 | Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com> |
366 | 359 | ||
367 | ----------------------------- | 360 | ----------------------------- |
368 | 361 | ||
369 | What: __do_IRQ all in one fits nothing interrupt handler | 362 | What: __do_IRQ all in one fits nothing interrupt handler |
370 | When: 2.6.32 | 363 | When: 2.6.32 |
371 | Why: __do_IRQ was kept for easy migration to the type flow handlers. | 364 | Why: __do_IRQ was kept for easy migration to the type flow handlers. |
372 | More than two years of migration time is enough. | 365 | More than two years of migration time is enough. |
373 | Who: Thomas Gleixner <tglx@linutronix.de> | 366 | Who: Thomas Gleixner <tglx@linutronix.de> |
374 | 367 | ||
375 | ----------------------------- | 368 | ----------------------------- |
376 | 369 | ||
377 | What: obsolete generic irq defines and typedefs | 370 | What: obsolete generic irq defines and typedefs |
378 | When: 2.6.30 | 371 | When: 2.6.30 |
379 | Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) | 372 | Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) |
380 | have been kept around for migration reasons. After more than two years | 373 | have been kept around for migration reasons. After more than two years |
381 | it's time to remove them finally | 374 | it's time to remove them finally |
382 | Who: Thomas Gleixner <tglx@linutronix.de> | 375 | Who: Thomas Gleixner <tglx@linutronix.de> |
383 | 376 |
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 HID_DEBUG | 34 | config HID_DEBUG |
35 | bool "HID debugging support" | 35 | bool "HID debugging support" |
36 | default y | 36 | default y |
37 | depends on HID | 37 | depends on HID |
38 | ---help--- | 38 | ---help--- |
39 | This option lets the HID layer output diagnostics about its internal | 39 | This option lets the HID layer output diagnostics about its internal |
40 | state, resolve HID usages, dump HID fields, etc. Individual HID drivers | 40 | state, resolve HID usages, dump HID fields, etc. Individual HID drivers |
41 | use this debugging facility to output information about individual HID | 41 | use this debugging facility to output information about individual HID |
42 | devices, etc. | 42 | devices, etc. |
43 | 43 | ||
44 | This feature is useful for those who are either debugging the HID parser | 44 | This feature is useful for those who are either debugging the HID parser |
45 | or any HID hardware device. | 45 | or any HID hardware device. |
46 | 46 | ||
47 | If unsure, say Y. | 47 | If unsure, say Y. |
48 | 48 | ||
49 | config HIDRAW | 49 | config HIDRAW |
50 | bool "/dev/hidraw raw HID device support" | 50 | bool "/dev/hidraw raw HID device support" |
51 | depends on HID | 51 | depends on HID |
52 | ---help--- | 52 | ---help--- |
53 | Say Y here if you want to support HID devices (from the USB | 53 | Say Y here if you want to support HID devices (from the USB |
54 | specification standpoint) that aren't strictly user interface | 54 | specification standpoint) that aren't strictly user interface |
55 | devices, like monitor controls and Uninterruptable Power Supplies. | 55 | devices, like monitor controls and Uninterruptable Power Supplies. |
56 | 56 | ||
57 | This module supports these devices separately using a separate | 57 | This module supports these devices separately using a separate |
58 | event interface on /dev/hidraw. | 58 | event interface on /dev/hidraw. |
59 | 59 | ||
60 | There is also a /dev/hiddev configuration option in the USB HID | 60 | There is also a /dev/hiddev configuration option in the USB HID |
61 | configuration menu. In comparison to hiddev, this device does not process | 61 | configuration menu. In comparison to hiddev, this device does not process |
62 | the hid events at all (no parsing, no lookups). This lets applications | 62 | the hid events at all (no parsing, no lookups). This lets applications |
63 | to work on raw hid events when they want to, and avoid using transport-specific | 63 | to work on raw hid events when they want to, and avoid using transport-specific |
64 | userspace libhid/libusb libraries. | 64 | userspace libhid/libusb libraries. |
65 | 65 | ||
66 | If unsure, say Y. | 66 | If unsure, say Y. |
67 | 67 | ||
68 | source "drivers/hid/usbhid/Kconfig" | 68 | source "drivers/hid/usbhid/Kconfig" |
69 | 69 | ||
70 | menu "Special HID drivers" | 70 | menu "Special HID drivers" |
71 | depends on HID | 71 | depends on HID |
72 | 72 | ||
73 | config HID_COMPAT | ||
74 | bool "Load all HID drivers on hid core load" | ||
75 | default y | ||
76 | ---help--- | ||
77 | Compatible option for older userspace. If you have system without udev | ||
78 | support of module loading through aliases and also old | ||
79 | module-init-tools which can't handle hid bus, choose Y here. Otherwise | ||
80 | say N. If you say N and your userspace is old enough, the only | ||
81 | functionality you lose is modules autoloading. | ||
82 | |||
83 | If unsure, say Y. | ||
84 | |||
85 | config HID_A4TECH | 73 | config HID_A4TECH |
86 | tristate "A4 tech" if EMBEDDED | 74 | tristate "A4 tech" if EMBEDDED |
87 | depends on USB_HID | 75 | depends on USB_HID |
88 | default !EMBEDDED | 76 | default !EMBEDDED |
89 | ---help--- | 77 | ---help--- |
90 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | 78 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. |
91 | 79 | ||
92 | config HID_APPLE | 80 | config HID_APPLE |
93 | tristate "Apple" if EMBEDDED | 81 | tristate "Apple" if EMBEDDED |
94 | depends on (USB_HID || BT_HIDP) | 82 | depends on (USB_HID || BT_HIDP) |
95 | default !EMBEDDED | 83 | default !EMBEDDED |
96 | ---help--- | 84 | ---help--- |
97 | Support for some Apple devices which less or more break | 85 | Support for some Apple devices which less or more break |
98 | HID specification. | 86 | HID specification. |
99 | 87 | ||
100 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, | 88 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, |
101 | MacBooks, MacBook Pros and Apple Aluminum. | 89 | MacBooks, MacBook Pros and Apple Aluminum. |
102 | 90 | ||
103 | config HID_BELKIN | 91 | config HID_BELKIN |
104 | tristate "Belkin" if EMBEDDED | 92 | tristate "Belkin" if EMBEDDED |
105 | depends on USB_HID | 93 | depends on USB_HID |
106 | default !EMBEDDED | 94 | default !EMBEDDED |
107 | ---help--- | 95 | ---help--- |
108 | Support for Belkin Flip KVM and Wireless keyboard. | 96 | Support for Belkin Flip KVM and Wireless keyboard. |
109 | 97 | ||
110 | config HID_CHERRY | 98 | config HID_CHERRY |
111 | tristate "Cherry" if EMBEDDED | 99 | tristate "Cherry" if EMBEDDED |
112 | depends on USB_HID | 100 | depends on USB_HID |
113 | default !EMBEDDED | 101 | default !EMBEDDED |
114 | ---help--- | 102 | ---help--- |
115 | Support for Cherry Cymotion keyboard. | 103 | Support for Cherry Cymotion keyboard. |
116 | 104 | ||
117 | config HID_CHICONY | 105 | config HID_CHICONY |
118 | tristate "Chicony" if EMBEDDED | 106 | tristate "Chicony" if EMBEDDED |
119 | depends on USB_HID | 107 | depends on USB_HID |
120 | default !EMBEDDED | 108 | default !EMBEDDED |
121 | ---help--- | 109 | ---help--- |
122 | Support for Chicony Tactical pad. | 110 | Support for Chicony Tactical pad. |
123 | 111 | ||
124 | config HID_CYPRESS | 112 | config HID_CYPRESS |
125 | tristate "Cypress" if EMBEDDED | 113 | tristate "Cypress" if EMBEDDED |
126 | depends on USB_HID | 114 | depends on USB_HID |
127 | default !EMBEDDED | 115 | default !EMBEDDED |
128 | ---help--- | 116 | ---help--- |
129 | Support for cypress mouse and barcode readers. | 117 | Support for cypress mouse and barcode readers. |
130 | 118 | ||
131 | config DRAGONRISE_FF | 119 | config DRAGONRISE_FF |
132 | tristate "DragonRise Inc. force feedback support" | 120 | tristate "DragonRise Inc. force feedback support" |
133 | depends on USB_HID | 121 | depends on USB_HID |
134 | select INPUT_FF_MEMLESS | 122 | select INPUT_FF_MEMLESS |
135 | ---help--- | 123 | ---help--- |
136 | Say Y here if you want to enable force feedback support for DragonRise Inc. | 124 | Say Y here if you want to enable force feedback support for DragonRise Inc. |
137 | game controllers. | 125 | game controllers. |
138 | 126 | ||
139 | config HID_EZKEY | 127 | config HID_EZKEY |
140 | tristate "Ezkey" if EMBEDDED | 128 | tristate "Ezkey" if EMBEDDED |
141 | depends on USB_HID | 129 | depends on USB_HID |
142 | default !EMBEDDED | 130 | default !EMBEDDED |
143 | ---help--- | 131 | ---help--- |
144 | Support for Ezkey BTC 8193 keyboard. | 132 | Support for Ezkey BTC 8193 keyboard. |
145 | 133 | ||
146 | config HID_KYE | 134 | config HID_KYE |
147 | tristate "Kye" if EMBEDDED | 135 | tristate "Kye" if EMBEDDED |
148 | depends on USB_HID | 136 | depends on USB_HID |
149 | default !EMBEDDED | 137 | default !EMBEDDED |
150 | ---help--- | 138 | ---help--- |
151 | Support for Kye/Genius Ergo Mouse. | 139 | Support for Kye/Genius Ergo Mouse. |
152 | 140 | ||
153 | config HID_GYRATION | 141 | config HID_GYRATION |
154 | tristate "Gyration" if EMBEDDED | 142 | tristate "Gyration" if EMBEDDED |
155 | depends on USB_HID | 143 | depends on USB_HID |
156 | default !EMBEDDED | 144 | default !EMBEDDED |
157 | ---help--- | 145 | ---help--- |
158 | Support for Gyration remote control. | 146 | Support for Gyration remote control. |
159 | 147 | ||
160 | config HID_KENSINGTON | 148 | config HID_KENSINGTON |
161 | tristate "Kensington" if EMBEDDED | 149 | tristate "Kensington" if EMBEDDED |
162 | depends on USB_HID | 150 | depends on USB_HID |
163 | default !EMBEDDED | 151 | default !EMBEDDED |
164 | ---help--- | 152 | ---help--- |
165 | Support for Kensington Slimblade Trackball. | 153 | Support for Kensington Slimblade Trackball. |
166 | 154 | ||
167 | config HID_LOGITECH | 155 | config HID_LOGITECH |
168 | tristate "Logitech" if EMBEDDED | 156 | tristate "Logitech" if EMBEDDED |
169 | depends on USB_HID | 157 | depends on USB_HID |
170 | default !EMBEDDED | 158 | default !EMBEDDED |
171 | ---help--- | 159 | ---help--- |
172 | Support for Logitech devices that are not fully compliant with HID standard. | 160 | Support for Logitech devices that are not fully compliant with HID standard. |
173 | 161 | ||
174 | config LOGITECH_FF | 162 | config LOGITECH_FF |
175 | bool "Logitech force feedback" | 163 | bool "Logitech force feedback" |
176 | depends on HID_LOGITECH | 164 | depends on HID_LOGITECH |
177 | select INPUT_FF_MEMLESS | 165 | select INPUT_FF_MEMLESS |
178 | help | 166 | help |
179 | Say Y here if you have one of these devices: | 167 | Say Y here if you have one of these devices: |
180 | - Logitech WingMan Cordless RumblePad | 168 | - Logitech WingMan Cordless RumblePad |
181 | - Logitech WingMan Cordless RumblePad 2 | 169 | - Logitech WingMan Cordless RumblePad 2 |
182 | - Logitech WingMan Force 3D | 170 | - Logitech WingMan Force 3D |
183 | - Logitech Formula Force EX | 171 | - Logitech Formula Force EX |
184 | - Logitech MOMO Force wheel | 172 | - Logitech MOMO Force wheel |
185 | 173 | ||
186 | and if you want to enable force feedback for them. | 174 | and if you want to enable force feedback for them. |
187 | Note: if you say N here, this device will still be supported, but without | 175 | Note: if you say N here, this device will still be supported, but without |
188 | force feedback. | 176 | force feedback. |
189 | 177 | ||
190 | config LOGIRUMBLEPAD2_FF | 178 | config LOGIRUMBLEPAD2_FF |
191 | bool "Logitech Rumblepad 2 force feedback" | 179 | bool "Logitech Rumblepad 2 force feedback" |
192 | depends on HID_LOGITECH | 180 | depends on HID_LOGITECH |
193 | select INPUT_FF_MEMLESS | 181 | select INPUT_FF_MEMLESS |
194 | help | 182 | help |
195 | Say Y here if you want to enable force feedback support for Logitech | 183 | Say Y here if you want to enable force feedback support for Logitech |
196 | Rumblepad 2 devices. | 184 | Rumblepad 2 devices. |
197 | 185 | ||
198 | config HID_MICROSOFT | 186 | config HID_MICROSOFT |
199 | tristate "Microsoft" if EMBEDDED | 187 | tristate "Microsoft" if EMBEDDED |
200 | depends on USB_HID | 188 | depends on USB_HID |
201 | default !EMBEDDED | 189 | default !EMBEDDED |
202 | ---help--- | 190 | ---help--- |
203 | Support for Microsoft devices that are not fully compliant with HID standard. | 191 | Support for Microsoft devices that are not fully compliant with HID standard. |
204 | 192 | ||
205 | config HID_MONTEREY | 193 | config HID_MONTEREY |
206 | tristate "Monterey" if EMBEDDED | 194 | tristate "Monterey" if EMBEDDED |
207 | depends on USB_HID | 195 | depends on USB_HID |
208 | default !EMBEDDED | 196 | default !EMBEDDED |
209 | ---help--- | 197 | ---help--- |
210 | Support for Monterey Genius KB29E. | 198 | Support for Monterey Genius KB29E. |
211 | 199 | ||
212 | config HID_NTRIG | 200 | config HID_NTRIG |
213 | tristate "NTrig" if EMBEDDED | 201 | tristate "NTrig" if EMBEDDED |
214 | depends on USB_HID | 202 | depends on USB_HID |
215 | default !EMBEDDED | 203 | default !EMBEDDED |
216 | ---help--- | 204 | ---help--- |
217 | Support for N-Trig touch screen. | 205 | Support for N-Trig touch screen. |
218 | 206 | ||
219 | config HID_PANTHERLORD | 207 | config HID_PANTHERLORD |
220 | tristate "Pantherlord devices support" if EMBEDDED | 208 | tristate "Pantherlord devices support" if EMBEDDED |
221 | depends on USB_HID | 209 | depends on USB_HID |
222 | default !EMBEDDED | 210 | default !EMBEDDED |
223 | ---help--- | 211 | ---help--- |
224 | Support for PantherLord/GreenAsia based device support. | 212 | Support for PantherLord/GreenAsia based device support. |
225 | 213 | ||
226 | config PANTHERLORD_FF | 214 | config PANTHERLORD_FF |
227 | bool "Pantherlord force feedback support" | 215 | bool "Pantherlord force feedback support" |
228 | depends on HID_PANTHERLORD | 216 | depends on HID_PANTHERLORD |
229 | select INPUT_FF_MEMLESS | 217 | select INPUT_FF_MEMLESS |
230 | help | 218 | help |
231 | Say Y here if you have a PantherLord/GreenAsia based game controller | 219 | Say Y here if you have a PantherLord/GreenAsia based game controller |
232 | or adapter and want to enable force feedback support for it. | 220 | or adapter and want to enable force feedback support for it. |
233 | 221 | ||
234 | config HID_PETALYNX | 222 | config HID_PETALYNX |
235 | tristate "Petalynx" if EMBEDDED | 223 | tristate "Petalynx" if EMBEDDED |
236 | depends on USB_HID | 224 | depends on USB_HID |
237 | default !EMBEDDED | 225 | default !EMBEDDED |
238 | ---help--- | 226 | ---help--- |
239 | Support for Petalynx Maxter remote control. | 227 | Support for Petalynx Maxter remote control. |
240 | 228 | ||
241 | config HID_SAMSUNG | 229 | config HID_SAMSUNG |
242 | tristate "Samsung" if EMBEDDED | 230 | tristate "Samsung" if EMBEDDED |
243 | depends on USB_HID | 231 | depends on USB_HID |
244 | default !EMBEDDED | 232 | default !EMBEDDED |
245 | ---help--- | 233 | ---help--- |
246 | Support for Samsung InfraRed remote control. | 234 | Support for Samsung InfraRed remote control. |
247 | 235 | ||
248 | config HID_SONY | 236 | config HID_SONY |
249 | tristate "Sony" if EMBEDDED | 237 | tristate "Sony" if EMBEDDED |
250 | depends on USB_HID | 238 | depends on USB_HID |
251 | default !EMBEDDED | 239 | default !EMBEDDED |
252 | ---help--- | 240 | ---help--- |
253 | Support for Sony PS3 controller. | 241 | Support for Sony PS3 controller. |
254 | 242 | ||
255 | config HID_SUNPLUS | 243 | config HID_SUNPLUS |
256 | tristate "Sunplus" if EMBEDDED | 244 | tristate "Sunplus" if EMBEDDED |
257 | depends on USB_HID | 245 | depends on USB_HID |
258 | default !EMBEDDED | 246 | default !EMBEDDED |
259 | ---help--- | 247 | ---help--- |
260 | Support for Sunplus wireless desktop. | 248 | Support for Sunplus wireless desktop. |
261 | 249 | ||
262 | config GREENASIA_FF | 250 | config GREENASIA_FF |
263 | tristate "GreenAsia (Product ID 0x12) force feedback support" | 251 | tristate "GreenAsia (Product ID 0x12) force feedback support" |
264 | depends on USB_HID | 252 | depends on USB_HID |
265 | select INPUT_FF_MEMLESS | 253 | select INPUT_FF_MEMLESS |
266 | ---help--- | 254 | ---help--- |
267 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller | 255 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller |
268 | (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter | 256 | (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter |
269 | and want to enable force feedback support for it. | 257 | and want to enable force feedback support for it. |
270 | 258 | ||
271 | config HID_TOPSEED | 259 | config HID_TOPSEED |
272 | tristate "TopSeed Cyberlink remote control support" if EMBEDDED | 260 | tristate "TopSeed Cyberlink remote control support" if EMBEDDED |
273 | depends on USB_HID | 261 | depends on USB_HID |
274 | default !EMBEDDED | 262 | default !EMBEDDED |
275 | ---help--- | 263 | ---help--- |
276 | Say Y if you have a TopSeed Cyberlink remote control. | 264 | Say Y if you have a TopSeed Cyberlink remote control. |
277 | 265 | ||
278 | config THRUSTMASTER_FF | 266 | config THRUSTMASTER_FF |
279 | tristate "ThrustMaster devices support" | 267 | tristate "ThrustMaster devices support" |
280 | depends on USB_HID | 268 | depends on USB_HID |
281 | select INPUT_FF_MEMLESS | 269 | select INPUT_FF_MEMLESS |
282 | help | 270 | help |
283 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or | 271 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or |
284 | a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel. | 272 | a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel. |
285 | 273 | ||
286 | config ZEROPLUS_FF | 274 | config ZEROPLUS_FF |
287 | tristate "Zeroplus based game controller support" | 275 | tristate "Zeroplus based game controller support" |
288 | depends on USB_HID | 276 | depends on USB_HID |
289 | select INPUT_FF_MEMLESS | 277 | select INPUT_FF_MEMLESS |
290 | help | 278 | help |
291 | Say Y here if you have a Zeroplus based game controller. | 279 | Say Y here if you have a Zeroplus based game controller. |
292 | 280 | ||
293 | endmenu | 281 | endmenu |
294 | 282 | ||
295 | endif # HID_SUPPORT | 283 | endif # HID_SUPPORT |
296 | 284 |
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 | obj-$(CONFIG_HID) += hid.o | 6 | obj-$(CONFIG_HID) += hid.o |
7 | 7 | ||
8 | hid-$(CONFIG_HID_DEBUG) += hid-debug.o | 8 | hid-$(CONFIG_HID_DEBUG) += hid-debug.o |
9 | hid-$(CONFIG_HIDRAW) += hidraw.o | 9 | hid-$(CONFIG_HIDRAW) += hidraw.o |
10 | 10 | ||
11 | ifdef CONFIG_HID_COMPAT | ||
12 | obj-m += hid-dummy.o | ||
13 | endif | ||
14 | |||
15 | hid-logitech-objs := hid-lg.o | 11 | hid-logitech-objs := hid-lg.o |
16 | ifdef CONFIG_LOGITECH_FF | 12 | ifdef CONFIG_LOGITECH_FF |
17 | hid-logitech-objs += hid-lgff.o | 13 | hid-logitech-objs += hid-lgff.o |
18 | endif | 14 | endif |
19 | ifdef CONFIG_LOGIRUMBLEPAD2_FF | 15 | ifdef CONFIG_LOGIRUMBLEPAD2_FF |
20 | hid-logitech-objs += hid-lg2ff.o | 16 | hid-logitech-objs += hid-lg2ff.o |
21 | endif | 17 | endif |
22 | 18 | ||
23 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 19 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
24 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 20 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
25 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 21 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
26 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 22 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
27 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 23 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
28 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 24 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
29 | obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o | 25 | obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o |
30 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 26 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
31 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 27 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
32 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 28 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
33 | obj-$(CONFIG_HID_KYE) += hid-kye.o | 29 | obj-$(CONFIG_HID_KYE) += hid-kye.o |
34 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | 30 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o |
35 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 31 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
36 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 32 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
37 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 33 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
38 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o | 34 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o |
39 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 35 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
40 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 36 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
41 | obj-$(CONFIG_HID_SONY) += hid-sony.o | 37 | obj-$(CONFIG_HID_SONY) += hid-sony.o |
42 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 38 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
43 | obj-$(CONFIG_GREENASIA_FF) += hid-gaff.o | 39 | obj-$(CONFIG_GREENASIA_FF) += hid-gaff.o |
44 | obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o | 40 | obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o |
45 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o | 41 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o |
46 | obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o | 42 | obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o |
47 | 43 | ||
48 | obj-$(CONFIG_USB_HID) += usbhid/ | 44 | obj-$(CONFIG_USB_HID) += usbhid/ |
49 | obj-$(CONFIG_USB_MOUSE) += usbhid/ | 45 | obj-$(CONFIG_USB_MOUSE) += usbhid/ |
50 | obj-$(CONFIG_USB_KBD) += usbhid/ | 46 | obj-$(CONFIG_USB_KBD) += usbhid/ |
51 | 47 | ||
52 | 48 |
drivers/hid/hid-a4tech.c
1 | /* | 1 | /* |
2 | * HID driver for some a4tech "special" devices | 2 | * HID driver for some a4tech "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define A4_2WHEEL_MOUSE_HACK_7 0x01 | 26 | #define A4_2WHEEL_MOUSE_HACK_7 0x01 |
27 | #define A4_2WHEEL_MOUSE_HACK_B8 0x02 | 27 | #define A4_2WHEEL_MOUSE_HACK_B8 0x02 |
28 | 28 | ||
29 | struct a4tech_sc { | 29 | struct a4tech_sc { |
30 | unsigned long quirks; | 30 | unsigned long quirks; |
31 | unsigned int hw_wheel; | 31 | unsigned int hw_wheel; |
32 | __s32 delayed_value; | 32 | __s32 delayed_value; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 35 | static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
36 | struct hid_field *field, struct hid_usage *usage, | 36 | struct hid_field *field, struct hid_usage *usage, |
37 | unsigned long **bit, int *max) | 37 | unsigned long **bit, int *max) |
38 | { | 38 | { |
39 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | 39 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); |
40 | 40 | ||
41 | if (usage->type == EV_REL && usage->code == REL_WHEEL) | 41 | if (usage->type == EV_REL && usage->code == REL_WHEEL) |
42 | set_bit(REL_HWHEEL, *bit); | 42 | set_bit(REL_HWHEEL, *bit); |
43 | 43 | ||
44 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) | 44 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) |
45 | return -1; | 45 | return -1; |
46 | 46 | ||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int a4_event(struct hid_device *hdev, struct hid_field *field, | 50 | static int a4_event(struct hid_device *hdev, struct hid_field *field, |
51 | struct hid_usage *usage, __s32 value) | 51 | struct hid_usage *usage, __s32 value) |
52 | { | 52 | { |
53 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | 53 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); |
54 | struct input_dev *input; | 54 | struct input_dev *input; |
55 | 55 | ||
56 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | 56 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
57 | !usage->type) | 57 | !usage->type) |
58 | return 0; | 58 | return 0; |
59 | 59 | ||
60 | input = field->hidinput->input; | 60 | input = field->hidinput->input; |
61 | 61 | ||
62 | if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { | 62 | if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { |
63 | if (usage->type == EV_REL && usage->code == REL_WHEEL) { | 63 | if (usage->type == EV_REL && usage->code == REL_WHEEL) { |
64 | a4->delayed_value = value; | 64 | a4->delayed_value = value; |
65 | return 1; | 65 | return 1; |
66 | } | 66 | } |
67 | 67 | ||
68 | if (usage->hid == 0x000100b8) { | 68 | if (usage->hid == 0x000100b8) { |
69 | input_event(input, EV_REL, value ? REL_HWHEEL : | 69 | input_event(input, EV_REL, value ? REL_HWHEEL : |
70 | REL_WHEEL, a4->delayed_value); | 70 | REL_WHEEL, a4->delayed_value); |
71 | return 1; | 71 | return 1; |
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { | 75 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { |
76 | a4->hw_wheel = !!value; | 76 | a4->hw_wheel = !!value; |
77 | return 1; | 77 | return 1; |
78 | } | 78 | } |
79 | 79 | ||
80 | if (usage->code == REL_WHEEL && a4->hw_wheel) { | 80 | if (usage->code == REL_WHEEL && a4->hw_wheel) { |
81 | input_event(input, usage->type, REL_HWHEEL, value); | 81 | input_event(input, usage->type, REL_HWHEEL, value); |
82 | return 1; | 82 | return 1; |
83 | } | 83 | } |
84 | 84 | ||
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) | 88 | static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) |
89 | { | 89 | { |
90 | struct a4tech_sc *a4; | 90 | struct a4tech_sc *a4; |
91 | int ret; | 91 | int ret; |
92 | 92 | ||
93 | a4 = kzalloc(sizeof(*a4), GFP_KERNEL); | 93 | a4 = kzalloc(sizeof(*a4), GFP_KERNEL); |
94 | if (a4 == NULL) { | 94 | if (a4 == NULL) { |
95 | dev_err(&hdev->dev, "can't alloc device descriptor\n"); | 95 | dev_err(&hdev->dev, "can't alloc device descriptor\n"); |
96 | ret = -ENOMEM; | 96 | ret = -ENOMEM; |
97 | goto err_free; | 97 | goto err_free; |
98 | } | 98 | } |
99 | 99 | ||
100 | a4->quirks = id->driver_data; | 100 | a4->quirks = id->driver_data; |
101 | 101 | ||
102 | hid_set_drvdata(hdev, a4); | 102 | hid_set_drvdata(hdev, a4); |
103 | 103 | ||
104 | ret = hid_parse(hdev); | 104 | ret = hid_parse(hdev); |
105 | if (ret) { | 105 | if (ret) { |
106 | dev_err(&hdev->dev, "parse failed\n"); | 106 | dev_err(&hdev->dev, "parse failed\n"); |
107 | goto err_free; | 107 | goto err_free; |
108 | } | 108 | } |
109 | 109 | ||
110 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 110 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
111 | if (ret) { | 111 | if (ret) { |
112 | dev_err(&hdev->dev, "hw start failed\n"); | 112 | dev_err(&hdev->dev, "hw start failed\n"); |
113 | goto err_free; | 113 | goto err_free; |
114 | } | 114 | } |
115 | 115 | ||
116 | return 0; | 116 | return 0; |
117 | err_free: | 117 | err_free: |
118 | kfree(a4); | 118 | kfree(a4); |
119 | return ret; | 119 | return ret; |
120 | } | 120 | } |
121 | 121 | ||
122 | static void a4_remove(struct hid_device *hdev) | 122 | static void a4_remove(struct hid_device *hdev) |
123 | { | 123 | { |
124 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | 124 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); |
125 | 125 | ||
126 | hid_hw_stop(hdev); | 126 | hid_hw_stop(hdev); |
127 | kfree(a4); | 127 | kfree(a4); |
128 | } | 128 | } |
129 | 129 | ||
130 | static const struct hid_device_id a4_devices[] = { | 130 | static const struct hid_device_id a4_devices[] = { |
131 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), | 131 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), |
132 | .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, | 132 | .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, |
133 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), | 133 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), |
134 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, | 134 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, |
135 | { } | 135 | { } |
136 | }; | 136 | }; |
137 | MODULE_DEVICE_TABLE(hid, a4_devices); | 137 | MODULE_DEVICE_TABLE(hid, a4_devices); |
138 | 138 | ||
139 | static struct hid_driver a4_driver = { | 139 | static struct hid_driver a4_driver = { |
140 | .name = "a4tech", | 140 | .name = "a4tech", |
141 | .id_table = a4_devices, | 141 | .id_table = a4_devices, |
142 | .input_mapped = a4_input_mapped, | 142 | .input_mapped = a4_input_mapped, |
143 | .event = a4_event, | 143 | .event = a4_event, |
144 | .probe = a4_probe, | 144 | .probe = a4_probe, |
145 | .remove = a4_remove, | 145 | .remove = a4_remove, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static int a4_init(void) | 148 | static int a4_init(void) |
149 | { | 149 | { |
150 | return hid_register_driver(&a4_driver); | 150 | return hid_register_driver(&a4_driver); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void a4_exit(void) | 153 | static void a4_exit(void) |
154 | { | 154 | { |
155 | hid_unregister_driver(&a4_driver); | 155 | hid_unregister_driver(&a4_driver); |
156 | } | 156 | } |
157 | 157 | ||
158 | module_init(a4_init); | 158 | module_init(a4_init); |
159 | module_exit(a4_exit); | 159 | module_exit(a4_exit); |
160 | MODULE_LICENSE("GPL"); | 160 | MODULE_LICENSE("GPL"); |
161 | |||
162 | HID_COMPAT_LOAD_DRIVER(a4tech); | ||
163 | 161 |
drivers/hid/hid-apple.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 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> | 9 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define APPLE_RDESC_JIS 0x0001 | 26 | #define APPLE_RDESC_JIS 0x0001 |
27 | #define APPLE_IGNORE_MOUSE 0x0002 | 27 | #define APPLE_IGNORE_MOUSE 0x0002 |
28 | #define APPLE_HAS_FN 0x0004 | 28 | #define APPLE_HAS_FN 0x0004 |
29 | #define APPLE_HIDDEV 0x0008 | 29 | #define APPLE_HIDDEV 0x0008 |
30 | #define APPLE_ISO_KEYBOARD 0x0010 | 30 | #define APPLE_ISO_KEYBOARD 0x0010 |
31 | #define APPLE_MIGHTYMOUSE 0x0020 | 31 | #define APPLE_MIGHTYMOUSE 0x0020 |
32 | #define APPLE_INVERT_HWHEEL 0x0040 | 32 | #define APPLE_INVERT_HWHEEL 0x0040 |
33 | #define APPLE_IGNORE_HIDINPUT 0x0080 | 33 | #define APPLE_IGNORE_HIDINPUT 0x0080 |
34 | #define APPLE_NUMLOCK_EMULATION 0x0100 | 34 | #define APPLE_NUMLOCK_EMULATION 0x0100 |
35 | 35 | ||
36 | #define APPLE_FLAG_FKEY 0x01 | 36 | #define APPLE_FLAG_FKEY 0x01 |
37 | 37 | ||
38 | static unsigned int fnmode = 1; | 38 | static unsigned int fnmode = 1; |
39 | module_param(fnmode, uint, 0644); | 39 | module_param(fnmode, uint, 0644); |
40 | MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " | 40 | MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " |
41 | "[1] = fkeyslast, 2 = fkeysfirst)"); | 41 | "[1] = fkeyslast, 2 = fkeysfirst)"); |
42 | 42 | ||
43 | struct apple_sc { | 43 | struct apple_sc { |
44 | unsigned long quirks; | 44 | unsigned long quirks; |
45 | unsigned int fn_on; | 45 | unsigned int fn_on; |
46 | DECLARE_BITMAP(pressed_fn, KEY_CNT); | 46 | DECLARE_BITMAP(pressed_fn, KEY_CNT); |
47 | DECLARE_BITMAP(pressed_numlock, KEY_CNT); | 47 | DECLARE_BITMAP(pressed_numlock, KEY_CNT); |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct apple_key_translation { | 50 | struct apple_key_translation { |
51 | u16 from; | 51 | u16 from; |
52 | u16 to; | 52 | u16 to; |
53 | u8 flags; | 53 | u8 flags; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static const struct apple_key_translation apple_fn_keys[] = { | 56 | static const struct apple_key_translation apple_fn_keys[] = { |
57 | { KEY_BACKSPACE, KEY_DELETE }, | 57 | { KEY_BACKSPACE, KEY_DELETE }, |
58 | { KEY_ENTER, KEY_INSERT }, | 58 | { KEY_ENTER, KEY_INSERT }, |
59 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | 59 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
60 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | 60 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
61 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, | 61 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
62 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, | 62 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
63 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, | 63 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
64 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, | 64 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
65 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, | 65 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
66 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | 66 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
67 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, | 67 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
68 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, | 68 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, |
69 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | 69 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
70 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | 70 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
71 | { KEY_UP, KEY_PAGEUP }, | 71 | { KEY_UP, KEY_PAGEUP }, |
72 | { KEY_DOWN, KEY_PAGEDOWN }, | 72 | { KEY_DOWN, KEY_PAGEDOWN }, |
73 | { KEY_LEFT, KEY_HOME }, | 73 | { KEY_LEFT, KEY_HOME }, |
74 | { KEY_RIGHT, KEY_END }, | 74 | { KEY_RIGHT, KEY_END }, |
75 | { } | 75 | { } |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static const struct apple_key_translation powerbook_fn_keys[] = { | 78 | static const struct apple_key_translation powerbook_fn_keys[] = { |
79 | { KEY_BACKSPACE, KEY_DELETE }, | 79 | { KEY_BACKSPACE, KEY_DELETE }, |
80 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | 80 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
81 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | 81 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
82 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, | 82 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, |
83 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | 83 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
84 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | 84 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
85 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, | 85 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
86 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, | 86 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, |
87 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, | 87 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, |
88 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, | 88 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
89 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, | 89 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
90 | { KEY_UP, KEY_PAGEUP }, | 90 | { KEY_UP, KEY_PAGEUP }, |
91 | { KEY_DOWN, KEY_PAGEDOWN }, | 91 | { KEY_DOWN, KEY_PAGEDOWN }, |
92 | { KEY_LEFT, KEY_HOME }, | 92 | { KEY_LEFT, KEY_HOME }, |
93 | { KEY_RIGHT, KEY_END }, | 93 | { KEY_RIGHT, KEY_END }, |
94 | { } | 94 | { } |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static const struct apple_key_translation powerbook_numlock_keys[] = { | 97 | static const struct apple_key_translation powerbook_numlock_keys[] = { |
98 | { KEY_J, KEY_KP1 }, | 98 | { KEY_J, KEY_KP1 }, |
99 | { KEY_K, KEY_KP2 }, | 99 | { KEY_K, KEY_KP2 }, |
100 | { KEY_L, KEY_KP3 }, | 100 | { KEY_L, KEY_KP3 }, |
101 | { KEY_U, KEY_KP4 }, | 101 | { KEY_U, KEY_KP4 }, |
102 | { KEY_I, KEY_KP5 }, | 102 | { KEY_I, KEY_KP5 }, |
103 | { KEY_O, KEY_KP6 }, | 103 | { KEY_O, KEY_KP6 }, |
104 | { KEY_7, KEY_KP7 }, | 104 | { KEY_7, KEY_KP7 }, |
105 | { KEY_8, KEY_KP8 }, | 105 | { KEY_8, KEY_KP8 }, |
106 | { KEY_9, KEY_KP9 }, | 106 | { KEY_9, KEY_KP9 }, |
107 | { KEY_M, KEY_KP0 }, | 107 | { KEY_M, KEY_KP0 }, |
108 | { KEY_DOT, KEY_KPDOT }, | 108 | { KEY_DOT, KEY_KPDOT }, |
109 | { KEY_SLASH, KEY_KPPLUS }, | 109 | { KEY_SLASH, KEY_KPPLUS }, |
110 | { KEY_SEMICOLON, KEY_KPMINUS }, | 110 | { KEY_SEMICOLON, KEY_KPMINUS }, |
111 | { KEY_P, KEY_KPASTERISK }, | 111 | { KEY_P, KEY_KPASTERISK }, |
112 | { KEY_MINUS, KEY_KPEQUAL }, | 112 | { KEY_MINUS, KEY_KPEQUAL }, |
113 | { KEY_0, KEY_KPSLASH }, | 113 | { KEY_0, KEY_KPSLASH }, |
114 | { KEY_F6, KEY_NUMLOCK }, | 114 | { KEY_F6, KEY_NUMLOCK }, |
115 | { KEY_KPENTER, KEY_KPENTER }, | 115 | { KEY_KPENTER, KEY_KPENTER }, |
116 | { KEY_BACKSPACE, KEY_BACKSPACE }, | 116 | { KEY_BACKSPACE, KEY_BACKSPACE }, |
117 | { } | 117 | { } |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static const struct apple_key_translation apple_iso_keyboard[] = { | 120 | static const struct apple_key_translation apple_iso_keyboard[] = { |
121 | { KEY_GRAVE, KEY_102ND }, | 121 | { KEY_GRAVE, KEY_102ND }, |
122 | { KEY_102ND, KEY_GRAVE }, | 122 | { KEY_102ND, KEY_GRAVE }, |
123 | { } | 123 | { } |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static const struct apple_key_translation *apple_find_translation( | 126 | static const struct apple_key_translation *apple_find_translation( |
127 | const struct apple_key_translation *table, u16 from) | 127 | const struct apple_key_translation *table, u16 from) |
128 | { | 128 | { |
129 | const struct apple_key_translation *trans; | 129 | const struct apple_key_translation *trans; |
130 | 130 | ||
131 | /* Look for the translation */ | 131 | /* Look for the translation */ |
132 | for (trans = table; trans->from; trans++) | 132 | for (trans = table; trans->from; trans++) |
133 | if (trans->from == from) | 133 | if (trans->from == from) |
134 | return trans; | 134 | return trans; |
135 | 135 | ||
136 | return NULL; | 136 | return NULL; |
137 | } | 137 | } |
138 | 138 | ||
139 | static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | 139 | static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
140 | struct hid_usage *usage, __s32 value) | 140 | struct hid_usage *usage, __s32 value) |
141 | { | 141 | { |
142 | struct apple_sc *asc = hid_get_drvdata(hid); | 142 | struct apple_sc *asc = hid_get_drvdata(hid); |
143 | const struct apple_key_translation *trans; | 143 | const struct apple_key_translation *trans; |
144 | 144 | ||
145 | if (usage->code == KEY_FN) { | 145 | if (usage->code == KEY_FN) { |
146 | asc->fn_on = !!value; | 146 | asc->fn_on = !!value; |
147 | input_event(input, usage->type, usage->code, value); | 147 | input_event(input, usage->type, usage->code, value); |
148 | return 1; | 148 | return 1; |
149 | } | 149 | } |
150 | 150 | ||
151 | if (fnmode) { | 151 | if (fnmode) { |
152 | int do_translate; | 152 | int do_translate; |
153 | 153 | ||
154 | trans = apple_find_translation((hid->product < 0x220 || | 154 | trans = apple_find_translation((hid->product < 0x220 || |
155 | hid->product >= 0x300) ? | 155 | hid->product >= 0x300) ? |
156 | powerbook_fn_keys : apple_fn_keys, | 156 | powerbook_fn_keys : apple_fn_keys, |
157 | usage->code); | 157 | usage->code); |
158 | if (trans) { | 158 | if (trans) { |
159 | if (test_bit(usage->code, asc->pressed_fn)) | 159 | if (test_bit(usage->code, asc->pressed_fn)) |
160 | do_translate = 1; | 160 | do_translate = 1; |
161 | else if (trans->flags & APPLE_FLAG_FKEY) | 161 | else if (trans->flags & APPLE_FLAG_FKEY) |
162 | do_translate = (fnmode == 2 && asc->fn_on) || | 162 | do_translate = (fnmode == 2 && asc->fn_on) || |
163 | (fnmode == 1 && !asc->fn_on); | 163 | (fnmode == 1 && !asc->fn_on); |
164 | else | 164 | else |
165 | do_translate = asc->fn_on; | 165 | do_translate = asc->fn_on; |
166 | 166 | ||
167 | if (do_translate) { | 167 | if (do_translate) { |
168 | if (value) | 168 | if (value) |
169 | set_bit(usage->code, asc->pressed_fn); | 169 | set_bit(usage->code, asc->pressed_fn); |
170 | else | 170 | else |
171 | clear_bit(usage->code, asc->pressed_fn); | 171 | clear_bit(usage->code, asc->pressed_fn); |
172 | 172 | ||
173 | input_event(input, usage->type, trans->to, | 173 | input_event(input, usage->type, trans->to, |
174 | value); | 174 | value); |
175 | 175 | ||
176 | return 1; | 176 | return 1; |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | if (asc->quirks & APPLE_NUMLOCK_EMULATION && | 180 | if (asc->quirks & APPLE_NUMLOCK_EMULATION && |
181 | (test_bit(usage->code, asc->pressed_numlock) || | 181 | (test_bit(usage->code, asc->pressed_numlock) || |
182 | test_bit(LED_NUML, input->led))) { | 182 | test_bit(LED_NUML, input->led))) { |
183 | trans = apple_find_translation(powerbook_numlock_keys, | 183 | trans = apple_find_translation(powerbook_numlock_keys, |
184 | usage->code); | 184 | usage->code); |
185 | 185 | ||
186 | if (trans) { | 186 | if (trans) { |
187 | if (value) | 187 | if (value) |
188 | set_bit(usage->code, | 188 | set_bit(usage->code, |
189 | asc->pressed_numlock); | 189 | asc->pressed_numlock); |
190 | else | 190 | else |
191 | clear_bit(usage->code, | 191 | clear_bit(usage->code, |
192 | asc->pressed_numlock); | 192 | asc->pressed_numlock); |
193 | 193 | ||
194 | input_event(input, usage->type, trans->to, | 194 | input_event(input, usage->type, trans->to, |
195 | value); | 195 | value); |
196 | } | 196 | } |
197 | 197 | ||
198 | return 1; | 198 | return 1; |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | if (asc->quirks & APPLE_ISO_KEYBOARD) { | 202 | if (asc->quirks & APPLE_ISO_KEYBOARD) { |
203 | trans = apple_find_translation(apple_iso_keyboard, usage->code); | 203 | trans = apple_find_translation(apple_iso_keyboard, usage->code); |
204 | if (trans) { | 204 | if (trans) { |
205 | input_event(input, usage->type, trans->to, value); | 205 | input_event(input, usage->type, trans->to, value); |
206 | return 1; | 206 | return 1; |
207 | } | 207 | } |
208 | } | 208 | } |
209 | 209 | ||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | static int apple_event(struct hid_device *hdev, struct hid_field *field, | 213 | static int apple_event(struct hid_device *hdev, struct hid_field *field, |
214 | struct hid_usage *usage, __s32 value) | 214 | struct hid_usage *usage, __s32 value) |
215 | { | 215 | { |
216 | struct apple_sc *asc = hid_get_drvdata(hdev); | 216 | struct apple_sc *asc = hid_get_drvdata(hdev); |
217 | 217 | ||
218 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | 218 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
219 | !usage->type) | 219 | !usage->type) |
220 | return 0; | 220 | return 0; |
221 | 221 | ||
222 | if ((asc->quirks & APPLE_INVERT_HWHEEL) && | 222 | if ((asc->quirks & APPLE_INVERT_HWHEEL) && |
223 | usage->code == REL_HWHEEL) { | 223 | usage->code == REL_HWHEEL) { |
224 | input_event(field->hidinput->input, usage->type, usage->code, | 224 | input_event(field->hidinput->input, usage->type, usage->code, |
225 | -value); | 225 | -value); |
226 | return 1; | 226 | return 1; |
227 | } | 227 | } |
228 | 228 | ||
229 | if ((asc->quirks & APPLE_HAS_FN) && | 229 | if ((asc->quirks & APPLE_HAS_FN) && |
230 | hidinput_apple_event(hdev, field->hidinput->input, | 230 | hidinput_apple_event(hdev, field->hidinput->input, |
231 | usage, value)) | 231 | usage, value)) |
232 | return 1; | 232 | return 1; |
233 | 233 | ||
234 | 234 | ||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* | 238 | /* |
239 | * MacBook JIS keyboard has wrong logical maximum | 239 | * MacBook JIS keyboard has wrong logical maximum |
240 | */ | 240 | */ |
241 | static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 241 | static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
242 | unsigned int rsize) | 242 | unsigned int rsize) |
243 | { | 243 | { |
244 | struct apple_sc *asc = hid_get_drvdata(hdev); | 244 | struct apple_sc *asc = hid_get_drvdata(hdev); |
245 | 245 | ||
246 | if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 && | 246 | if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 && |
247 | rdesc[53] == 0x65 && rdesc[59] == 0x65) { | 247 | rdesc[53] == 0x65 && rdesc[59] == 0x65) { |
248 | dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " | 248 | dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " |
249 | "descriptor\n"); | 249 | "descriptor\n"); |
250 | rdesc[53] = rdesc[59] = 0xe7; | 250 | rdesc[53] = rdesc[59] = 0xe7; |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | static void apple_setup_input(struct input_dev *input) | 254 | static void apple_setup_input(struct input_dev *input) |
255 | { | 255 | { |
256 | const struct apple_key_translation *trans; | 256 | const struct apple_key_translation *trans; |
257 | 257 | ||
258 | set_bit(KEY_NUMLOCK, input->keybit); | 258 | set_bit(KEY_NUMLOCK, input->keybit); |
259 | 259 | ||
260 | /* Enable all needed keys */ | 260 | /* Enable all needed keys */ |
261 | for (trans = apple_fn_keys; trans->from; trans++) | 261 | for (trans = apple_fn_keys; trans->from; trans++) |
262 | set_bit(trans->to, input->keybit); | 262 | set_bit(trans->to, input->keybit); |
263 | 263 | ||
264 | for (trans = powerbook_fn_keys; trans->from; trans++) | 264 | for (trans = powerbook_fn_keys; trans->from; trans++) |
265 | set_bit(trans->to, input->keybit); | 265 | set_bit(trans->to, input->keybit); |
266 | 266 | ||
267 | for (trans = powerbook_numlock_keys; trans->from; trans++) | 267 | for (trans = powerbook_numlock_keys; trans->from; trans++) |
268 | set_bit(trans->to, input->keybit); | 268 | set_bit(trans->to, input->keybit); |
269 | 269 | ||
270 | for (trans = apple_iso_keyboard; trans->from; trans++) | 270 | for (trans = apple_iso_keyboard; trans->from; trans++) |
271 | set_bit(trans->to, input->keybit); | 271 | set_bit(trans->to, input->keybit); |
272 | } | 272 | } |
273 | 273 | ||
274 | static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 274 | static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
275 | struct hid_field *field, struct hid_usage *usage, | 275 | struct hid_field *field, struct hid_usage *usage, |
276 | unsigned long **bit, int *max) | 276 | unsigned long **bit, int *max) |
277 | { | 277 | { |
278 | if (usage->hid == (HID_UP_CUSTOM | 0x0003)) { | 278 | if (usage->hid == (HID_UP_CUSTOM | 0x0003)) { |
279 | /* The fn key on Apple USB keyboards */ | 279 | /* The fn key on Apple USB keyboards */ |
280 | set_bit(EV_REP, hi->input->evbit); | 280 | set_bit(EV_REP, hi->input->evbit); |
281 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); | 281 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); |
282 | apple_setup_input(hi->input); | 282 | apple_setup_input(hi->input); |
283 | return 1; | 283 | return 1; |
284 | } | 284 | } |
285 | 285 | ||
286 | /* we want the hid layer to go through standard path (set and ignore) */ | 286 | /* we want the hid layer to go through standard path (set and ignore) */ |
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 290 | static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
291 | struct hid_field *field, struct hid_usage *usage, | 291 | struct hid_field *field, struct hid_usage *usage, |
292 | unsigned long **bit, int *max) | 292 | unsigned long **bit, int *max) |
293 | { | 293 | { |
294 | struct apple_sc *asc = hid_get_drvdata(hdev); | 294 | struct apple_sc *asc = hid_get_drvdata(hdev); |
295 | 295 | ||
296 | if (asc->quirks & APPLE_MIGHTYMOUSE) { | 296 | if (asc->quirks & APPLE_MIGHTYMOUSE) { |
297 | if (usage->hid == HID_GD_Z) | 297 | if (usage->hid == HID_GD_Z) |
298 | hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); | 298 | hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); |
299 | else if (usage->code == BTN_1) | 299 | else if (usage->code == BTN_1) |
300 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2); | 300 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2); |
301 | else if (usage->code == BTN_2) | 301 | else if (usage->code == BTN_2) |
302 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1); | 302 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1); |
303 | } | 303 | } |
304 | 304 | ||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | static int apple_probe(struct hid_device *hdev, | 308 | static int apple_probe(struct hid_device *hdev, |
309 | const struct hid_device_id *id) | 309 | const struct hid_device_id *id) |
310 | { | 310 | { |
311 | unsigned long quirks = id->driver_data; | 311 | unsigned long quirks = id->driver_data; |
312 | struct apple_sc *asc; | 312 | struct apple_sc *asc; |
313 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 313 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
314 | int ret; | 314 | int ret; |
315 | 315 | ||
316 | asc = kzalloc(sizeof(*asc), GFP_KERNEL); | 316 | asc = kzalloc(sizeof(*asc), GFP_KERNEL); |
317 | if (asc == NULL) { | 317 | if (asc == NULL) { |
318 | dev_err(&hdev->dev, "can't alloc apple descriptor\n"); | 318 | dev_err(&hdev->dev, "can't alloc apple descriptor\n"); |
319 | return -ENOMEM; | 319 | return -ENOMEM; |
320 | } | 320 | } |
321 | 321 | ||
322 | asc->quirks = quirks; | 322 | asc->quirks = quirks; |
323 | 323 | ||
324 | hid_set_drvdata(hdev, asc); | 324 | hid_set_drvdata(hdev, asc); |
325 | 325 | ||
326 | ret = hid_parse(hdev); | 326 | ret = hid_parse(hdev); |
327 | if (ret) { | 327 | if (ret) { |
328 | dev_err(&hdev->dev, "parse failed\n"); | 328 | dev_err(&hdev->dev, "parse failed\n"); |
329 | goto err_free; | 329 | goto err_free; |
330 | } | 330 | } |
331 | 331 | ||
332 | if (quirks & APPLE_HIDDEV) | 332 | if (quirks & APPLE_HIDDEV) |
333 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | 333 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; |
334 | if (quirks & APPLE_IGNORE_HIDINPUT) | 334 | if (quirks & APPLE_IGNORE_HIDINPUT) |
335 | connect_mask &= ~HID_CONNECT_HIDINPUT; | 335 | connect_mask &= ~HID_CONNECT_HIDINPUT; |
336 | 336 | ||
337 | ret = hid_hw_start(hdev, connect_mask); | 337 | ret = hid_hw_start(hdev, connect_mask); |
338 | if (ret) { | 338 | if (ret) { |
339 | dev_err(&hdev->dev, "hw start failed\n"); | 339 | dev_err(&hdev->dev, "hw start failed\n"); |
340 | goto err_free; | 340 | goto err_free; |
341 | } | 341 | } |
342 | 342 | ||
343 | return 0; | 343 | return 0; |
344 | err_free: | 344 | err_free: |
345 | kfree(asc); | 345 | kfree(asc); |
346 | return ret; | 346 | return ret; |
347 | } | 347 | } |
348 | 348 | ||
349 | static void apple_remove(struct hid_device *hdev) | 349 | static void apple_remove(struct hid_device *hdev) |
350 | { | 350 | { |
351 | hid_hw_stop(hdev); | 351 | hid_hw_stop(hdev); |
352 | kfree(hid_get_drvdata(hdev)); | 352 | kfree(hid_get_drvdata(hdev)); |
353 | } | 353 | } |
354 | 354 | ||
355 | static const struct hid_device_id apple_devices[] = { | 355 | static const struct hid_device_id apple_devices[] = { |
356 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), | 356 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), |
357 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, | 357 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, |
358 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), | 358 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), |
359 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, | 359 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, |
360 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), | 360 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), |
361 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, | 361 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, |
362 | 362 | ||
363 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI), | 363 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI), |
364 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 364 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
365 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO), | 365 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO), |
366 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 366 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
367 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI), | 367 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI), |
368 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 368 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
369 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO), | 369 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO), |
370 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 370 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
371 | APPLE_ISO_KEYBOARD }, | 371 | APPLE_ISO_KEYBOARD }, |
372 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS), | 372 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS), |
373 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 373 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
374 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI), | 374 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI), |
375 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 375 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
376 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO), | 376 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO), |
377 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 377 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
378 | APPLE_ISO_KEYBOARD }, | 378 | APPLE_ISO_KEYBOARD }, |
379 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS), | 379 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS), |
380 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 380 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
381 | APPLE_RDESC_JIS }, | 381 | APPLE_RDESC_JIS }, |
382 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI), | 382 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI), |
383 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 383 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
384 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO), | 384 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO), |
385 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 385 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
386 | APPLE_ISO_KEYBOARD }, | 386 | APPLE_ISO_KEYBOARD }, |
387 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS), | 387 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS), |
388 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 388 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
389 | APPLE_RDESC_JIS }, | 389 | APPLE_RDESC_JIS }, |
390 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI), | 390 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI), |
391 | .driver_data = APPLE_HAS_FN }, | 391 | .driver_data = APPLE_HAS_FN }, |
392 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO), | 392 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO), |
393 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 393 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
394 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS), | 394 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS), |
395 | .driver_data = APPLE_HAS_FN }, | 395 | .driver_data = APPLE_HAS_FN }, |
396 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI), | 396 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI), |
397 | .driver_data = APPLE_HAS_FN }, | 397 | .driver_data = APPLE_HAS_FN }, |
398 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO), | 398 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO), |
399 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 399 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
400 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS), | 400 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS), |
401 | .driver_data = APPLE_HAS_FN }, | 401 | .driver_data = APPLE_HAS_FN }, |
402 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), | 402 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), |
403 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 403 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
404 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), | 404 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), |
405 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 405 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
406 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), | 406 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), |
407 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 407 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
408 | APPLE_RDESC_JIS }, | 408 | APPLE_RDESC_JIS }, |
409 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), | 409 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
410 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 410 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
411 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), | 411 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), |
412 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 412 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
413 | APPLE_ISO_KEYBOARD }, | 413 | APPLE_ISO_KEYBOARD }, |
414 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 414 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
415 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 415 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
416 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 416 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
417 | .driver_data = APPLE_HAS_FN }, | 417 | .driver_data = APPLE_HAS_FN }, |
418 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO), | 418 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO), |
419 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 419 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
420 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS), | 420 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS), |
421 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 421 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
422 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), | 422 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), |
423 | .driver_data = APPLE_HAS_FN }, | 423 | .driver_data = APPLE_HAS_FN }, |
424 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), | 424 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), |
425 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 425 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
426 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | 426 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
427 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 427 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
428 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | 428 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), |
429 | .driver_data = APPLE_HAS_FN }, | 429 | .driver_data = APPLE_HAS_FN }, |
430 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | 430 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), |
431 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 431 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
432 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | 432 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), |
433 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 433 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
434 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), | 434 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), |
435 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 435 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
436 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), | 436 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), |
437 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 437 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
438 | 438 | ||
439 | /* Apple wireless Mighty Mouse */ | 439 | /* Apple wireless Mighty Mouse */ |
440 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c), | 440 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c), |
441 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, | 441 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, |
442 | 442 | ||
443 | { } | 443 | { } |
444 | }; | 444 | }; |
445 | MODULE_DEVICE_TABLE(hid, apple_devices); | 445 | MODULE_DEVICE_TABLE(hid, apple_devices); |
446 | 446 | ||
447 | static struct hid_driver apple_driver = { | 447 | static struct hid_driver apple_driver = { |
448 | .name = "apple", | 448 | .name = "apple", |
449 | .id_table = apple_devices, | 449 | .id_table = apple_devices, |
450 | .report_fixup = apple_report_fixup, | 450 | .report_fixup = apple_report_fixup, |
451 | .probe = apple_probe, | 451 | .probe = apple_probe, |
452 | .remove = apple_remove, | 452 | .remove = apple_remove, |
453 | .event = apple_event, | 453 | .event = apple_event, |
454 | .input_mapping = apple_input_mapping, | 454 | .input_mapping = apple_input_mapping, |
455 | .input_mapped = apple_input_mapped, | 455 | .input_mapped = apple_input_mapped, |
456 | }; | 456 | }; |
457 | 457 | ||
458 | static int apple_init(void) | 458 | static int apple_init(void) |
459 | { | 459 | { |
460 | int ret; | 460 | int ret; |
461 | 461 | ||
462 | ret = hid_register_driver(&apple_driver); | 462 | ret = hid_register_driver(&apple_driver); |
463 | if (ret) | 463 | if (ret) |
464 | printk(KERN_ERR "can't register apple driver\n"); | 464 | printk(KERN_ERR "can't register apple driver\n"); |
465 | 465 | ||
466 | return ret; | 466 | return ret; |
467 | } | 467 | } |
468 | 468 | ||
469 | static void apple_exit(void) | 469 | static void apple_exit(void) |
470 | { | 470 | { |
471 | hid_unregister_driver(&apple_driver); | 471 | hid_unregister_driver(&apple_driver); |
472 | } | 472 | } |
473 | 473 | ||
474 | module_init(apple_init); | 474 | module_init(apple_init); |
475 | module_exit(apple_exit); | 475 | module_exit(apple_exit); |
476 | MODULE_LICENSE("GPL"); | 476 | MODULE_LICENSE("GPL"); |
477 | |||
478 | HID_COMPAT_LOAD_DRIVER(apple); | ||
479 | 477 |
drivers/hid/hid-belkin.c
1 | /* | 1 | /* |
2 | * HID driver for some belkin "special" devices | 2 | * HID driver for some belkin "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | #define BELKIN_HIDDEV 0x01 | 25 | #define BELKIN_HIDDEV 0x01 |
26 | #define BELKIN_WKBD 0x02 | 26 | #define BELKIN_WKBD 0x02 |
27 | 27 | ||
28 | #define belkin_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 28 | #define belkin_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
29 | EV_KEY, (c)) | 29 | EV_KEY, (c)) |
30 | static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 30 | static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
31 | struct hid_field *field, struct hid_usage *usage, | 31 | struct hid_field *field, struct hid_usage *usage, |
32 | unsigned long **bit, int *max) | 32 | unsigned long **bit, int *max) |
33 | { | 33 | { |
34 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 34 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
35 | 35 | ||
36 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER || | 36 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER || |
37 | !(quirks & BELKIN_WKBD)) | 37 | !(quirks & BELKIN_WKBD)) |
38 | return 0; | 38 | return 0; |
39 | 39 | ||
40 | switch (usage->hid & HID_USAGE) { | 40 | switch (usage->hid & HID_USAGE) { |
41 | case 0x03a: belkin_map_key_clear(KEY_SOUND); break; | 41 | case 0x03a: belkin_map_key_clear(KEY_SOUND); break; |
42 | case 0x03b: belkin_map_key_clear(KEY_CAMERA); break; | 42 | case 0x03b: belkin_map_key_clear(KEY_CAMERA); break; |
43 | case 0x03c: belkin_map_key_clear(KEY_DOCUMENTS); break; | 43 | case 0x03c: belkin_map_key_clear(KEY_DOCUMENTS); break; |
44 | default: | 44 | default: |
45 | return 0; | 45 | return 0; |
46 | } | 46 | } |
47 | return 1; | 47 | return 1; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) | 50 | static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) |
51 | { | 51 | { |
52 | unsigned long quirks = id->driver_data; | 52 | unsigned long quirks = id->driver_data; |
53 | int ret; | 53 | int ret; |
54 | 54 | ||
55 | hid_set_drvdata(hdev, (void *)quirks); | 55 | hid_set_drvdata(hdev, (void *)quirks); |
56 | 56 | ||
57 | ret = hid_parse(hdev); | 57 | ret = hid_parse(hdev); |
58 | if (ret) { | 58 | if (ret) { |
59 | dev_err(&hdev->dev, "parse failed\n"); | 59 | dev_err(&hdev->dev, "parse failed\n"); |
60 | goto err_free; | 60 | goto err_free; |
61 | } | 61 | } |
62 | 62 | ||
63 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | | 63 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | |
64 | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); | 64 | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); |
65 | if (ret) { | 65 | if (ret) { |
66 | dev_err(&hdev->dev, "hw start failed\n"); | 66 | dev_err(&hdev->dev, "hw start failed\n"); |
67 | goto err_free; | 67 | goto err_free; |
68 | } | 68 | } |
69 | 69 | ||
70 | return 0; | 70 | return 0; |
71 | err_free: | 71 | err_free: |
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
74 | 74 | ||
75 | static const struct hid_device_id belkin_devices[] = { | 75 | static const struct hid_device_id belkin_devices[] = { |
76 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM), | 76 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM), |
77 | .driver_data = BELKIN_HIDDEV }, | 77 | .driver_data = BELKIN_HIDDEV }, |
78 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD), | 78 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD), |
79 | .driver_data = BELKIN_WKBD }, | 79 | .driver_data = BELKIN_WKBD }, |
80 | { } | 80 | { } |
81 | }; | 81 | }; |
82 | MODULE_DEVICE_TABLE(hid, belkin_devices); | 82 | MODULE_DEVICE_TABLE(hid, belkin_devices); |
83 | 83 | ||
84 | static struct hid_driver belkin_driver = { | 84 | static struct hid_driver belkin_driver = { |
85 | .name = "belkin", | 85 | .name = "belkin", |
86 | .id_table = belkin_devices, | 86 | .id_table = belkin_devices, |
87 | .input_mapping = belkin_input_mapping, | 87 | .input_mapping = belkin_input_mapping, |
88 | .probe = belkin_probe, | 88 | .probe = belkin_probe, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int belkin_init(void) | 91 | static int belkin_init(void) |
92 | { | 92 | { |
93 | return hid_register_driver(&belkin_driver); | 93 | return hid_register_driver(&belkin_driver); |
94 | } | 94 | } |
95 | 95 | ||
96 | static void belkin_exit(void) | 96 | static void belkin_exit(void) |
97 | { | 97 | { |
98 | hid_unregister_driver(&belkin_driver); | 98 | hid_unregister_driver(&belkin_driver); |
99 | } | 99 | } |
100 | 100 | ||
101 | module_init(belkin_init); | 101 | module_init(belkin_init); |
102 | module_exit(belkin_exit); | 102 | module_exit(belkin_exit); |
103 | MODULE_LICENSE("GPL"); | 103 | MODULE_LICENSE("GPL"); |
104 | |||
105 | HID_COMPAT_LOAD_DRIVER(belkin); | ||
106 | 104 |
drivers/hid/hid-cherry.c
1 | /* | 1 | /* |
2 | * HID driver for some cherry "special" devices | 2 | * HID driver for some cherry "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Cherry Cymotion keyboard have an invalid HID report descriptor, | 26 | * Cherry Cymotion keyboard have an invalid HID report descriptor, |
27 | * that needs fixing before we can parse it. | 27 | * that needs fixing before we can parse it. |
28 | */ | 28 | */ |
29 | static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 29 | static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
30 | unsigned int rsize) | 30 | unsigned int rsize) |
31 | { | 31 | { |
32 | if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | 32 | if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { |
33 | dev_info(&hdev->dev, "fixing up Cherry Cymotion report " | 33 | dev_info(&hdev->dev, "fixing up Cherry Cymotion report " |
34 | "descriptor\n"); | 34 | "descriptor\n"); |
35 | rdesc[11] = rdesc[16] = 0xff; | 35 | rdesc[11] = rdesc[16] = 0xff; |
36 | rdesc[12] = rdesc[17] = 0x03; | 36 | rdesc[12] = rdesc[17] = 0x03; |
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 40 | #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
41 | EV_KEY, (c)) | 41 | EV_KEY, (c)) |
42 | static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 42 | static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
43 | struct hid_field *field, struct hid_usage *usage, | 43 | struct hid_field *field, struct hid_usage *usage, |
44 | unsigned long **bit, int *max) | 44 | unsigned long **bit, int *max) |
45 | { | 45 | { |
46 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 46 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
47 | return 0; | 47 | return 0; |
48 | 48 | ||
49 | switch (usage->hid & HID_USAGE) { | 49 | switch (usage->hid & HID_USAGE) { |
50 | case 0x301: ch_map_key_clear(KEY_PROG1); break; | 50 | case 0x301: ch_map_key_clear(KEY_PROG1); break; |
51 | case 0x302: ch_map_key_clear(KEY_PROG2); break; | 51 | case 0x302: ch_map_key_clear(KEY_PROG2); break; |
52 | case 0x303: ch_map_key_clear(KEY_PROG3); break; | 52 | case 0x303: ch_map_key_clear(KEY_PROG3); break; |
53 | default: | 53 | default: |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | return 1; | 57 | return 1; |
58 | } | 58 | } |
59 | 59 | ||
60 | static const struct hid_device_id ch_devices[] = { | 60 | static const struct hid_device_id ch_devices[] = { |
61 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 61 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
62 | { } | 62 | { } |
63 | }; | 63 | }; |
64 | MODULE_DEVICE_TABLE(hid, ch_devices); | 64 | MODULE_DEVICE_TABLE(hid, ch_devices); |
65 | 65 | ||
66 | static struct hid_driver ch_driver = { | 66 | static struct hid_driver ch_driver = { |
67 | .name = "cherry", | 67 | .name = "cherry", |
68 | .id_table = ch_devices, | 68 | .id_table = ch_devices, |
69 | .report_fixup = ch_report_fixup, | 69 | .report_fixup = ch_report_fixup, |
70 | .input_mapping = ch_input_mapping, | 70 | .input_mapping = ch_input_mapping, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static int ch_init(void) | 73 | static int ch_init(void) |
74 | { | 74 | { |
75 | return hid_register_driver(&ch_driver); | 75 | return hid_register_driver(&ch_driver); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void ch_exit(void) | 78 | static void ch_exit(void) |
79 | { | 79 | { |
80 | hid_unregister_driver(&ch_driver); | 80 | hid_unregister_driver(&ch_driver); |
81 | } | 81 | } |
82 | 82 | ||
83 | module_init(ch_init); | 83 | module_init(ch_init); |
84 | module_exit(ch_exit); | 84 | module_exit(ch_exit); |
85 | MODULE_LICENSE("GPL"); | 85 | MODULE_LICENSE("GPL"); |
86 | |||
87 | HID_COMPAT_LOAD_DRIVER(cherry); | ||
88 | 86 |
drivers/hid/hid-chicony.c
1 | /* | 1 | /* |
2 | * HID driver for some chicony "special" devices | 2 | * HID driver for some chicony "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 26 | #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
27 | EV_KEY, (c)) | 27 | EV_KEY, (c)) |
28 | static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 28 | static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
29 | struct hid_field *field, struct hid_usage *usage, | 29 | struct hid_field *field, struct hid_usage *usage, |
30 | unsigned long **bit, int *max) | 30 | unsigned long **bit, int *max) |
31 | { | 31 | { |
32 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | 32 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) |
33 | return 0; | 33 | return 0; |
34 | 34 | ||
35 | set_bit(EV_REP, hi->input->evbit); | 35 | set_bit(EV_REP, hi->input->evbit); |
36 | switch (usage->hid & HID_USAGE) { | 36 | switch (usage->hid & HID_USAGE) { |
37 | case 0xff01: ch_map_key_clear(BTN_1); break; | 37 | case 0xff01: ch_map_key_clear(BTN_1); break; |
38 | case 0xff02: ch_map_key_clear(BTN_2); break; | 38 | case 0xff02: ch_map_key_clear(BTN_2); break; |
39 | case 0xff03: ch_map_key_clear(BTN_3); break; | 39 | case 0xff03: ch_map_key_clear(BTN_3); break; |
40 | case 0xff04: ch_map_key_clear(BTN_4); break; | 40 | case 0xff04: ch_map_key_clear(BTN_4); break; |
41 | case 0xff05: ch_map_key_clear(BTN_5); break; | 41 | case 0xff05: ch_map_key_clear(BTN_5); break; |
42 | case 0xff06: ch_map_key_clear(BTN_6); break; | 42 | case 0xff06: ch_map_key_clear(BTN_6); break; |
43 | case 0xff07: ch_map_key_clear(BTN_7); break; | 43 | case 0xff07: ch_map_key_clear(BTN_7); break; |
44 | case 0xff08: ch_map_key_clear(BTN_8); break; | 44 | case 0xff08: ch_map_key_clear(BTN_8); break; |
45 | case 0xff09: ch_map_key_clear(BTN_9); break; | 45 | case 0xff09: ch_map_key_clear(BTN_9); break; |
46 | case 0xff0a: ch_map_key_clear(BTN_A); break; | 46 | case 0xff0a: ch_map_key_clear(BTN_A); break; |
47 | case 0xff0b: ch_map_key_clear(BTN_B); break; | 47 | case 0xff0b: ch_map_key_clear(BTN_B); break; |
48 | default: | 48 | default: |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | return 1; | 51 | return 1; |
52 | } | 52 | } |
53 | 53 | ||
54 | static const struct hid_device_id ch_devices[] = { | 54 | static const struct hid_device_id ch_devices[] = { |
55 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 55 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
56 | { } | 56 | { } |
57 | }; | 57 | }; |
58 | MODULE_DEVICE_TABLE(hid, ch_devices); | 58 | MODULE_DEVICE_TABLE(hid, ch_devices); |
59 | 59 | ||
60 | static struct hid_driver ch_driver = { | 60 | static struct hid_driver ch_driver = { |
61 | .name = "chicony", | 61 | .name = "chicony", |
62 | .id_table = ch_devices, | 62 | .id_table = ch_devices, |
63 | .input_mapping = ch_input_mapping, | 63 | .input_mapping = ch_input_mapping, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static int ch_init(void) | 66 | static int ch_init(void) |
67 | { | 67 | { |
68 | return hid_register_driver(&ch_driver); | 68 | return hid_register_driver(&ch_driver); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void ch_exit(void) | 71 | static void ch_exit(void) |
72 | { | 72 | { |
73 | hid_unregister_driver(&ch_driver); | 73 | hid_unregister_driver(&ch_driver); |
74 | } | 74 | } |
75 | 75 | ||
76 | module_init(ch_init); | 76 | module_init(ch_init); |
77 | module_exit(ch_exit); | 77 | module_exit(ch_exit); |
78 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
79 | |||
80 | HID_COMPAT_LOAD_DRIVER(chicony); | ||
81 | 79 |
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-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 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_VERSION "v2.6" | 42 | #define DRIVER_VERSION "v2.6" |
43 | #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina" | 43 | #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina" |
44 | #define DRIVER_DESC "HID core driver" | 44 | #define DRIVER_DESC "HID core driver" |
45 | #define DRIVER_LICENSE "GPL" | 45 | #define DRIVER_LICENSE "GPL" |
46 | 46 | ||
47 | #ifdef CONFIG_HID_DEBUG | 47 | #ifdef CONFIG_HID_DEBUG |
48 | int hid_debug = 0; | 48 | int hid_debug = 0; |
49 | module_param_named(debug, hid_debug, int, 0600); | 49 | module_param_named(debug, hid_debug, int, 0600); |
50 | MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)"); | 50 | MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)"); |
51 | EXPORT_SYMBOL_GPL(hid_debug); | 51 | EXPORT_SYMBOL_GPL(hid_debug); |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Register a new report for a device. | 55 | * Register a new report for a device. |
56 | */ | 56 | */ |
57 | 57 | ||
58 | static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) | 58 | static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) |
59 | { | 59 | { |
60 | struct hid_report_enum *report_enum = device->report_enum + type; | 60 | struct hid_report_enum *report_enum = device->report_enum + type; |
61 | struct hid_report *report; | 61 | struct hid_report *report; |
62 | 62 | ||
63 | if (report_enum->report_id_hash[id]) | 63 | if (report_enum->report_id_hash[id]) |
64 | return report_enum->report_id_hash[id]; | 64 | return report_enum->report_id_hash[id]; |
65 | 65 | ||
66 | if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) | 66 | if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) |
67 | return NULL; | 67 | return NULL; |
68 | 68 | ||
69 | if (id != 0) | 69 | if (id != 0) |
70 | report_enum->numbered = 1; | 70 | report_enum->numbered = 1; |
71 | 71 | ||
72 | report->id = id; | 72 | report->id = id; |
73 | report->type = type; | 73 | report->type = type; |
74 | report->size = 0; | 74 | report->size = 0; |
75 | report->device = device; | 75 | report->device = device; |
76 | report_enum->report_id_hash[id] = report; | 76 | report_enum->report_id_hash[id] = report; |
77 | 77 | ||
78 | list_add_tail(&report->list, &report_enum->report_list); | 78 | list_add_tail(&report->list, &report_enum->report_list); |
79 | 79 | ||
80 | return report; | 80 | return report; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Register a new field for this report. | 84 | * Register a new field for this report. |
85 | */ | 85 | */ |
86 | 86 | ||
87 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) | 87 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) |
88 | { | 88 | { |
89 | struct hid_field *field; | 89 | struct hid_field *field; |
90 | 90 | ||
91 | if (report->maxfield == HID_MAX_FIELDS) { | 91 | if (report->maxfield == HID_MAX_FIELDS) { |
92 | dbg_hid("too many fields in report\n"); | 92 | dbg_hid("too many fields in report\n"); |
93 | return NULL; | 93 | return NULL; |
94 | } | 94 | } |
95 | 95 | ||
96 | if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) | 96 | if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) |
97 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; | 97 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; |
98 | 98 | ||
99 | field->index = report->maxfield++; | 99 | field->index = report->maxfield++; |
100 | report->field[field->index] = field; | 100 | report->field[field->index] = field; |
101 | field->usage = (struct hid_usage *)(field + 1); | 101 | field->usage = (struct hid_usage *)(field + 1); |
102 | field->value = (s32 *)(field->usage + usages); | 102 | field->value = (s32 *)(field->usage + usages); |
103 | field->report = report; | 103 | field->report = report; |
104 | 104 | ||
105 | return field; | 105 | return field; |
106 | } | 106 | } |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * Open a collection. The type/usage is pushed on the stack. | 109 | * Open a collection. The type/usage is pushed on the stack. |
110 | */ | 110 | */ |
111 | 111 | ||
112 | static int open_collection(struct hid_parser *parser, unsigned type) | 112 | static int open_collection(struct hid_parser *parser, unsigned type) |
113 | { | 113 | { |
114 | struct hid_collection *collection; | 114 | struct hid_collection *collection; |
115 | unsigned usage; | 115 | unsigned usage; |
116 | 116 | ||
117 | usage = parser->local.usage[0]; | 117 | usage = parser->local.usage[0]; |
118 | 118 | ||
119 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { | 119 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { |
120 | dbg_hid("collection stack overflow\n"); | 120 | dbg_hid("collection stack overflow\n"); |
121 | return -1; | 121 | return -1; |
122 | } | 122 | } |
123 | 123 | ||
124 | if (parser->device->maxcollection == parser->device->collection_size) { | 124 | if (parser->device->maxcollection == parser->device->collection_size) { |
125 | collection = kmalloc(sizeof(struct hid_collection) * | 125 | collection = kmalloc(sizeof(struct hid_collection) * |
126 | parser->device->collection_size * 2, GFP_KERNEL); | 126 | parser->device->collection_size * 2, GFP_KERNEL); |
127 | if (collection == NULL) { | 127 | if (collection == NULL) { |
128 | dbg_hid("failed to reallocate collection array\n"); | 128 | dbg_hid("failed to reallocate collection array\n"); |
129 | return -1; | 129 | return -1; |
130 | } | 130 | } |
131 | memcpy(collection, parser->device->collection, | 131 | memcpy(collection, parser->device->collection, |
132 | sizeof(struct hid_collection) * | 132 | sizeof(struct hid_collection) * |
133 | parser->device->collection_size); | 133 | parser->device->collection_size); |
134 | memset(collection + parser->device->collection_size, 0, | 134 | memset(collection + parser->device->collection_size, 0, |
135 | sizeof(struct hid_collection) * | 135 | sizeof(struct hid_collection) * |
136 | parser->device->collection_size); | 136 | parser->device->collection_size); |
137 | kfree(parser->device->collection); | 137 | kfree(parser->device->collection); |
138 | parser->device->collection = collection; | 138 | parser->device->collection = collection; |
139 | parser->device->collection_size *= 2; | 139 | parser->device->collection_size *= 2; |
140 | } | 140 | } |
141 | 141 | ||
142 | parser->collection_stack[parser->collection_stack_ptr++] = | 142 | parser->collection_stack[parser->collection_stack_ptr++] = |
143 | parser->device->maxcollection; | 143 | parser->device->maxcollection; |
144 | 144 | ||
145 | collection = parser->device->collection + | 145 | collection = parser->device->collection + |
146 | parser->device->maxcollection++; | 146 | parser->device->maxcollection++; |
147 | collection->type = type; | 147 | collection->type = type; |
148 | collection->usage = usage; | 148 | collection->usage = usage; |
149 | collection->level = parser->collection_stack_ptr - 1; | 149 | collection->level = parser->collection_stack_ptr - 1; |
150 | 150 | ||
151 | if (type == HID_COLLECTION_APPLICATION) | 151 | if (type == HID_COLLECTION_APPLICATION) |
152 | parser->device->maxapplication++; | 152 | parser->device->maxapplication++; |
153 | 153 | ||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | /* | 157 | /* |
158 | * Close a collection. | 158 | * Close a collection. |
159 | */ | 159 | */ |
160 | 160 | ||
161 | static int close_collection(struct hid_parser *parser) | 161 | static int close_collection(struct hid_parser *parser) |
162 | { | 162 | { |
163 | if (!parser->collection_stack_ptr) { | 163 | if (!parser->collection_stack_ptr) { |
164 | dbg_hid("collection stack underflow\n"); | 164 | dbg_hid("collection stack underflow\n"); |
165 | return -1; | 165 | return -1; |
166 | } | 166 | } |
167 | parser->collection_stack_ptr--; | 167 | parser->collection_stack_ptr--; |
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * Climb up the stack, search for the specified collection type | 172 | * Climb up the stack, search for the specified collection type |
173 | * and return the usage. | 173 | * and return the usage. |
174 | */ | 174 | */ |
175 | 175 | ||
176 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) | 176 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) |
177 | { | 177 | { |
178 | int n; | 178 | int n; |
179 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) | 179 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) |
180 | if (parser->device->collection[parser->collection_stack[n]].type == type) | 180 | if (parser->device->collection[parser->collection_stack[n]].type == type) |
181 | return parser->device->collection[parser->collection_stack[n]].usage; | 181 | return parser->device->collection[parser->collection_stack[n]].usage; |
182 | return 0; /* we know nothing about this usage type */ | 182 | return 0; /* we know nothing about this usage type */ |
183 | } | 183 | } |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * Add a usage to the temporary parser table. | 186 | * Add a usage to the temporary parser table. |
187 | */ | 187 | */ |
188 | 188 | ||
189 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) | 189 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) |
190 | { | 190 | { |
191 | if (parser->local.usage_index >= HID_MAX_USAGES) { | 191 | if (parser->local.usage_index >= HID_MAX_USAGES) { |
192 | dbg_hid("usage index exceeded\n"); | 192 | dbg_hid("usage index exceeded\n"); |
193 | return -1; | 193 | return -1; |
194 | } | 194 | } |
195 | parser->local.usage[parser->local.usage_index] = usage; | 195 | parser->local.usage[parser->local.usage_index] = usage; |
196 | parser->local.collection_index[parser->local.usage_index] = | 196 | parser->local.collection_index[parser->local.usage_index] = |
197 | parser->collection_stack_ptr ? | 197 | parser->collection_stack_ptr ? |
198 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; | 198 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; |
199 | parser->local.usage_index++; | 199 | parser->local.usage_index++; |
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * Register a new field for this report. | 204 | * Register a new field for this report. |
205 | */ | 205 | */ |
206 | 206 | ||
207 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) | 207 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) |
208 | { | 208 | { |
209 | struct hid_report *report; | 209 | struct hid_report *report; |
210 | struct hid_field *field; | 210 | struct hid_field *field; |
211 | int usages; | 211 | int usages; |
212 | unsigned offset; | 212 | unsigned offset; |
213 | int i; | 213 | int i; |
214 | 214 | ||
215 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { | 215 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { |
216 | dbg_hid("hid_register_report failed\n"); | 216 | dbg_hid("hid_register_report failed\n"); |
217 | return -1; | 217 | return -1; |
218 | } | 218 | } |
219 | 219 | ||
220 | if (parser->global.logical_maximum < parser->global.logical_minimum) { | 220 | if (parser->global.logical_maximum < parser->global.logical_minimum) { |
221 | dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum); | 221 | dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum); |
222 | return -1; | 222 | return -1; |
223 | } | 223 | } |
224 | 224 | ||
225 | offset = report->size; | 225 | offset = report->size; |
226 | report->size += parser->global.report_size * parser->global.report_count; | 226 | report->size += parser->global.report_size * parser->global.report_count; |
227 | 227 | ||
228 | if (!parser->local.usage_index) /* Ignore padding fields */ | 228 | if (!parser->local.usage_index) /* Ignore padding fields */ |
229 | return 0; | 229 | return 0; |
230 | 230 | ||
231 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); | 231 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); |
232 | 232 | ||
233 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) | 233 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) |
234 | return 0; | 234 | return 0; |
235 | 235 | ||
236 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); | 236 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); |
237 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); | 237 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); |
238 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); | 238 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); |
239 | 239 | ||
240 | for (i = 0; i < usages; i++) { | 240 | for (i = 0; i < usages; i++) { |
241 | int j = i; | 241 | int j = i; |
242 | /* Duplicate the last usage we parsed if we have excess values */ | 242 | /* Duplicate the last usage we parsed if we have excess values */ |
243 | if (i >= parser->local.usage_index) | 243 | if (i >= parser->local.usage_index) |
244 | j = parser->local.usage_index - 1; | 244 | j = parser->local.usage_index - 1; |
245 | field->usage[i].hid = parser->local.usage[j]; | 245 | field->usage[i].hid = parser->local.usage[j]; |
246 | field->usage[i].collection_index = | 246 | field->usage[i].collection_index = |
247 | parser->local.collection_index[j]; | 247 | parser->local.collection_index[j]; |
248 | } | 248 | } |
249 | 249 | ||
250 | field->maxusage = usages; | 250 | field->maxusage = usages; |
251 | field->flags = flags; | 251 | field->flags = flags; |
252 | field->report_offset = offset; | 252 | field->report_offset = offset; |
253 | field->report_type = report_type; | 253 | field->report_type = report_type; |
254 | field->report_size = parser->global.report_size; | 254 | field->report_size = parser->global.report_size; |
255 | field->report_count = parser->global.report_count; | 255 | field->report_count = parser->global.report_count; |
256 | field->logical_minimum = parser->global.logical_minimum; | 256 | field->logical_minimum = parser->global.logical_minimum; |
257 | field->logical_maximum = parser->global.logical_maximum; | 257 | field->logical_maximum = parser->global.logical_maximum; |
258 | field->physical_minimum = parser->global.physical_minimum; | 258 | field->physical_minimum = parser->global.physical_minimum; |
259 | field->physical_maximum = parser->global.physical_maximum; | 259 | field->physical_maximum = parser->global.physical_maximum; |
260 | field->unit_exponent = parser->global.unit_exponent; | 260 | field->unit_exponent = parser->global.unit_exponent; |
261 | field->unit = parser->global.unit; | 261 | field->unit = parser->global.unit; |
262 | 262 | ||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | /* | 266 | /* |
267 | * Read data value from item. | 267 | * Read data value from item. |
268 | */ | 268 | */ |
269 | 269 | ||
270 | static u32 item_udata(struct hid_item *item) | 270 | static u32 item_udata(struct hid_item *item) |
271 | { | 271 | { |
272 | switch (item->size) { | 272 | switch (item->size) { |
273 | case 1: return item->data.u8; | 273 | case 1: return item->data.u8; |
274 | case 2: return item->data.u16; | 274 | case 2: return item->data.u16; |
275 | case 4: return item->data.u32; | 275 | case 4: return item->data.u32; |
276 | } | 276 | } |
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | static s32 item_sdata(struct hid_item *item) | 280 | static s32 item_sdata(struct hid_item *item) |
281 | { | 281 | { |
282 | switch (item->size) { | 282 | switch (item->size) { |
283 | case 1: return item->data.s8; | 283 | case 1: return item->data.s8; |
284 | case 2: return item->data.s16; | 284 | case 2: return item->data.s16; |
285 | case 4: return item->data.s32; | 285 | case 4: return item->data.s32; |
286 | } | 286 | } |
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | /* | 290 | /* |
291 | * Process a global item. | 291 | * Process a global item. |
292 | */ | 292 | */ |
293 | 293 | ||
294 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) | 294 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) |
295 | { | 295 | { |
296 | switch (item->tag) { | 296 | switch (item->tag) { |
297 | case HID_GLOBAL_ITEM_TAG_PUSH: | 297 | case HID_GLOBAL_ITEM_TAG_PUSH: |
298 | 298 | ||
299 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { | 299 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { |
300 | dbg_hid("global enviroment stack overflow\n"); | 300 | dbg_hid("global enviroment stack overflow\n"); |
301 | return -1; | 301 | return -1; |
302 | } | 302 | } |
303 | 303 | ||
304 | memcpy(parser->global_stack + parser->global_stack_ptr++, | 304 | memcpy(parser->global_stack + parser->global_stack_ptr++, |
305 | &parser->global, sizeof(struct hid_global)); | 305 | &parser->global, sizeof(struct hid_global)); |
306 | return 0; | 306 | return 0; |
307 | 307 | ||
308 | case HID_GLOBAL_ITEM_TAG_POP: | 308 | case HID_GLOBAL_ITEM_TAG_POP: |
309 | 309 | ||
310 | if (!parser->global_stack_ptr) { | 310 | if (!parser->global_stack_ptr) { |
311 | dbg_hid("global enviroment stack underflow\n"); | 311 | dbg_hid("global enviroment stack underflow\n"); |
312 | return -1; | 312 | return -1; |
313 | } | 313 | } |
314 | 314 | ||
315 | memcpy(&parser->global, parser->global_stack + | 315 | memcpy(&parser->global, parser->global_stack + |
316 | --parser->global_stack_ptr, sizeof(struct hid_global)); | 316 | --parser->global_stack_ptr, sizeof(struct hid_global)); |
317 | return 0; | 317 | return 0; |
318 | 318 | ||
319 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: | 319 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: |
320 | parser->global.usage_page = item_udata(item); | 320 | parser->global.usage_page = item_udata(item); |
321 | return 0; | 321 | return 0; |
322 | 322 | ||
323 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: | 323 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: |
324 | parser->global.logical_minimum = item_sdata(item); | 324 | parser->global.logical_minimum = item_sdata(item); |
325 | return 0; | 325 | return 0; |
326 | 326 | ||
327 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: | 327 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: |
328 | if (parser->global.logical_minimum < 0) | 328 | if (parser->global.logical_minimum < 0) |
329 | parser->global.logical_maximum = item_sdata(item); | 329 | parser->global.logical_maximum = item_sdata(item); |
330 | else | 330 | else |
331 | parser->global.logical_maximum = item_udata(item); | 331 | parser->global.logical_maximum = item_udata(item); |
332 | return 0; | 332 | return 0; |
333 | 333 | ||
334 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: | 334 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: |
335 | parser->global.physical_minimum = item_sdata(item); | 335 | parser->global.physical_minimum = item_sdata(item); |
336 | return 0; | 336 | return 0; |
337 | 337 | ||
338 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: | 338 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: |
339 | if (parser->global.physical_minimum < 0) | 339 | if (parser->global.physical_minimum < 0) |
340 | parser->global.physical_maximum = item_sdata(item); | 340 | parser->global.physical_maximum = item_sdata(item); |
341 | else | 341 | else |
342 | parser->global.physical_maximum = item_udata(item); | 342 | parser->global.physical_maximum = item_udata(item); |
343 | return 0; | 343 | return 0; |
344 | 344 | ||
345 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: | 345 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: |
346 | parser->global.unit_exponent = item_sdata(item); | 346 | parser->global.unit_exponent = item_sdata(item); |
347 | return 0; | 347 | return 0; |
348 | 348 | ||
349 | case HID_GLOBAL_ITEM_TAG_UNIT: | 349 | case HID_GLOBAL_ITEM_TAG_UNIT: |
350 | parser->global.unit = item_udata(item); | 350 | parser->global.unit = item_udata(item); |
351 | return 0; | 351 | return 0; |
352 | 352 | ||
353 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: | 353 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: |
354 | parser->global.report_size = item_udata(item); | 354 | parser->global.report_size = item_udata(item); |
355 | if (parser->global.report_size > 32) { | 355 | if (parser->global.report_size > 32) { |
356 | dbg_hid("invalid report_size %d\n", | 356 | dbg_hid("invalid report_size %d\n", |
357 | parser->global.report_size); | 357 | parser->global.report_size); |
358 | return -1; | 358 | return -1; |
359 | } | 359 | } |
360 | return 0; | 360 | return 0; |
361 | 361 | ||
362 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: | 362 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: |
363 | parser->global.report_count = item_udata(item); | 363 | parser->global.report_count = item_udata(item); |
364 | if (parser->global.report_count > HID_MAX_USAGES) { | 364 | if (parser->global.report_count > HID_MAX_USAGES) { |
365 | dbg_hid("invalid report_count %d\n", | 365 | dbg_hid("invalid report_count %d\n", |
366 | parser->global.report_count); | 366 | parser->global.report_count); |
367 | return -1; | 367 | return -1; |
368 | } | 368 | } |
369 | return 0; | 369 | return 0; |
370 | 370 | ||
371 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: | 371 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: |
372 | parser->global.report_id = item_udata(item); | 372 | parser->global.report_id = item_udata(item); |
373 | if (parser->global.report_id == 0) { | 373 | if (parser->global.report_id == 0) { |
374 | dbg_hid("report_id 0 is invalid\n"); | 374 | dbg_hid("report_id 0 is invalid\n"); |
375 | return -1; | 375 | return -1; |
376 | } | 376 | } |
377 | return 0; | 377 | return 0; |
378 | 378 | ||
379 | default: | 379 | default: |
380 | dbg_hid("unknown global tag 0x%x\n", item->tag); | 380 | dbg_hid("unknown global tag 0x%x\n", item->tag); |
381 | return -1; | 381 | return -1; |
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | /* | 385 | /* |
386 | * Process a local item. | 386 | * Process a local item. |
387 | */ | 387 | */ |
388 | 388 | ||
389 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) | 389 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) |
390 | { | 390 | { |
391 | __u32 data; | 391 | __u32 data; |
392 | unsigned n; | 392 | unsigned n; |
393 | 393 | ||
394 | if (item->size == 0) { | 394 | if (item->size == 0) { |
395 | dbg_hid("item data expected for local item\n"); | 395 | dbg_hid("item data expected for local item\n"); |
396 | return -1; | 396 | return -1; |
397 | } | 397 | } |
398 | 398 | ||
399 | data = item_udata(item); | 399 | data = item_udata(item); |
400 | 400 | ||
401 | switch (item->tag) { | 401 | switch (item->tag) { |
402 | case HID_LOCAL_ITEM_TAG_DELIMITER: | 402 | case HID_LOCAL_ITEM_TAG_DELIMITER: |
403 | 403 | ||
404 | if (data) { | 404 | if (data) { |
405 | /* | 405 | /* |
406 | * We treat items before the first delimiter | 406 | * We treat items before the first delimiter |
407 | * as global to all usage sets (branch 0). | 407 | * as global to all usage sets (branch 0). |
408 | * In the moment we process only these global | 408 | * In the moment we process only these global |
409 | * items and the first delimiter set. | 409 | * items and the first delimiter set. |
410 | */ | 410 | */ |
411 | if (parser->local.delimiter_depth != 0) { | 411 | if (parser->local.delimiter_depth != 0) { |
412 | dbg_hid("nested delimiters\n"); | 412 | dbg_hid("nested delimiters\n"); |
413 | return -1; | 413 | return -1; |
414 | } | 414 | } |
415 | parser->local.delimiter_depth++; | 415 | parser->local.delimiter_depth++; |
416 | parser->local.delimiter_branch++; | 416 | parser->local.delimiter_branch++; |
417 | } else { | 417 | } else { |
418 | if (parser->local.delimiter_depth < 1) { | 418 | if (parser->local.delimiter_depth < 1) { |
419 | dbg_hid("bogus close delimiter\n"); | 419 | dbg_hid("bogus close delimiter\n"); |
420 | return -1; | 420 | return -1; |
421 | } | 421 | } |
422 | parser->local.delimiter_depth--; | 422 | parser->local.delimiter_depth--; |
423 | } | 423 | } |
424 | return 1; | 424 | return 1; |
425 | 425 | ||
426 | case HID_LOCAL_ITEM_TAG_USAGE: | 426 | case HID_LOCAL_ITEM_TAG_USAGE: |
427 | 427 | ||
428 | if (parser->local.delimiter_branch > 1) { | 428 | if (parser->local.delimiter_branch > 1) { |
429 | dbg_hid("alternative usage ignored\n"); | 429 | dbg_hid("alternative usage ignored\n"); |
430 | return 0; | 430 | return 0; |
431 | } | 431 | } |
432 | 432 | ||
433 | if (item->size <= 2) | 433 | if (item->size <= 2) |
434 | data = (parser->global.usage_page << 16) + data; | 434 | data = (parser->global.usage_page << 16) + data; |
435 | 435 | ||
436 | return hid_add_usage(parser, data); | 436 | return hid_add_usage(parser, data); |
437 | 437 | ||
438 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: | 438 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: |
439 | 439 | ||
440 | if (parser->local.delimiter_branch > 1) { | 440 | if (parser->local.delimiter_branch > 1) { |
441 | dbg_hid("alternative usage ignored\n"); | 441 | dbg_hid("alternative usage ignored\n"); |
442 | return 0; | 442 | return 0; |
443 | } | 443 | } |
444 | 444 | ||
445 | if (item->size <= 2) | 445 | if (item->size <= 2) |
446 | data = (parser->global.usage_page << 16) + data; | 446 | data = (parser->global.usage_page << 16) + data; |
447 | 447 | ||
448 | parser->local.usage_minimum = data; | 448 | parser->local.usage_minimum = data; |
449 | return 0; | 449 | return 0; |
450 | 450 | ||
451 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: | 451 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: |
452 | 452 | ||
453 | if (parser->local.delimiter_branch > 1) { | 453 | if (parser->local.delimiter_branch > 1) { |
454 | dbg_hid("alternative usage ignored\n"); | 454 | dbg_hid("alternative usage ignored\n"); |
455 | return 0; | 455 | return 0; |
456 | } | 456 | } |
457 | 457 | ||
458 | if (item->size <= 2) | 458 | if (item->size <= 2) |
459 | data = (parser->global.usage_page << 16) + data; | 459 | data = (parser->global.usage_page << 16) + data; |
460 | 460 | ||
461 | for (n = parser->local.usage_minimum; n <= data; n++) | 461 | for (n = parser->local.usage_minimum; n <= data; n++) |
462 | if (hid_add_usage(parser, n)) { | 462 | if (hid_add_usage(parser, n)) { |
463 | dbg_hid("hid_add_usage failed\n"); | 463 | dbg_hid("hid_add_usage failed\n"); |
464 | return -1; | 464 | return -1; |
465 | } | 465 | } |
466 | return 0; | 466 | return 0; |
467 | 467 | ||
468 | default: | 468 | default: |
469 | 469 | ||
470 | dbg_hid("unknown local item tag 0x%x\n", item->tag); | 470 | dbg_hid("unknown local item tag 0x%x\n", item->tag); |
471 | return 0; | 471 | return 0; |
472 | } | 472 | } |
473 | return 0; | 473 | return 0; |
474 | } | 474 | } |
475 | 475 | ||
476 | /* | 476 | /* |
477 | * Process a main item. | 477 | * Process a main item. |
478 | */ | 478 | */ |
479 | 479 | ||
480 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) | 480 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) |
481 | { | 481 | { |
482 | __u32 data; | 482 | __u32 data; |
483 | int ret; | 483 | int ret; |
484 | 484 | ||
485 | data = item_udata(item); | 485 | data = item_udata(item); |
486 | 486 | ||
487 | switch (item->tag) { | 487 | switch (item->tag) { |
488 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: | 488 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: |
489 | ret = open_collection(parser, data & 0xff); | 489 | ret = open_collection(parser, data & 0xff); |
490 | break; | 490 | break; |
491 | case HID_MAIN_ITEM_TAG_END_COLLECTION: | 491 | case HID_MAIN_ITEM_TAG_END_COLLECTION: |
492 | ret = close_collection(parser); | 492 | ret = close_collection(parser); |
493 | break; | 493 | break; |
494 | case HID_MAIN_ITEM_TAG_INPUT: | 494 | case HID_MAIN_ITEM_TAG_INPUT: |
495 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); | 495 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); |
496 | break; | 496 | break; |
497 | case HID_MAIN_ITEM_TAG_OUTPUT: | 497 | case HID_MAIN_ITEM_TAG_OUTPUT: |
498 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); | 498 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); |
499 | break; | 499 | break; |
500 | case HID_MAIN_ITEM_TAG_FEATURE: | 500 | case HID_MAIN_ITEM_TAG_FEATURE: |
501 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); | 501 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); |
502 | break; | 502 | break; |
503 | default: | 503 | default: |
504 | dbg_hid("unknown main item tag 0x%x\n", item->tag); | 504 | dbg_hid("unknown main item tag 0x%x\n", item->tag); |
505 | ret = 0; | 505 | ret = 0; |
506 | } | 506 | } |
507 | 507 | ||
508 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ | 508 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ |
509 | 509 | ||
510 | return ret; | 510 | return ret; |
511 | } | 511 | } |
512 | 512 | ||
513 | /* | 513 | /* |
514 | * Process a reserved item. | 514 | * Process a reserved item. |
515 | */ | 515 | */ |
516 | 516 | ||
517 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) | 517 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) |
518 | { | 518 | { |
519 | dbg_hid("reserved item type, tag 0x%x\n", item->tag); | 519 | dbg_hid("reserved item type, tag 0x%x\n", item->tag); |
520 | return 0; | 520 | return 0; |
521 | } | 521 | } |
522 | 522 | ||
523 | /* | 523 | /* |
524 | * Free a report and all registered fields. The field->usage and | 524 | * Free a report and all registered fields. The field->usage and |
525 | * field->value table's are allocated behind the field, so we need | 525 | * field->value table's are allocated behind the field, so we need |
526 | * only to free(field) itself. | 526 | * only to free(field) itself. |
527 | */ | 527 | */ |
528 | 528 | ||
529 | static void hid_free_report(struct hid_report *report) | 529 | static void hid_free_report(struct hid_report *report) |
530 | { | 530 | { |
531 | unsigned n; | 531 | unsigned n; |
532 | 532 | ||
533 | for (n = 0; n < report->maxfield; n++) | 533 | for (n = 0; n < report->maxfield; n++) |
534 | kfree(report->field[n]); | 534 | kfree(report->field[n]); |
535 | kfree(report); | 535 | kfree(report); |
536 | } | 536 | } |
537 | 537 | ||
538 | /* | 538 | /* |
539 | * Free a device structure, all reports, and all fields. | 539 | * Free a device structure, all reports, and all fields. |
540 | */ | 540 | */ |
541 | 541 | ||
542 | static void hid_device_release(struct device *dev) | 542 | static void hid_device_release(struct device *dev) |
543 | { | 543 | { |
544 | struct hid_device *device = container_of(dev, struct hid_device, dev); | 544 | struct hid_device *device = container_of(dev, struct hid_device, dev); |
545 | unsigned i, j; | 545 | unsigned i, j; |
546 | 546 | ||
547 | for (i = 0; i < HID_REPORT_TYPES; i++) { | 547 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
548 | struct hid_report_enum *report_enum = device->report_enum + i; | 548 | struct hid_report_enum *report_enum = device->report_enum + i; |
549 | 549 | ||
550 | for (j = 0; j < 256; j++) { | 550 | for (j = 0; j < 256; j++) { |
551 | struct hid_report *report = report_enum->report_id_hash[j]; | 551 | struct hid_report *report = report_enum->report_id_hash[j]; |
552 | if (report) | 552 | if (report) |
553 | hid_free_report(report); | 553 | hid_free_report(report); |
554 | } | 554 | } |
555 | } | 555 | } |
556 | 556 | ||
557 | kfree(device->rdesc); | 557 | kfree(device->rdesc); |
558 | kfree(device->collection); | 558 | kfree(device->collection); |
559 | kfree(device); | 559 | kfree(device); |
560 | } | 560 | } |
561 | 561 | ||
562 | /* | 562 | /* |
563 | * Fetch a report description item from the data stream. We support long | 563 | * Fetch a report description item from the data stream. We support long |
564 | * items, though they are not used yet. | 564 | * items, though they are not used yet. |
565 | */ | 565 | */ |
566 | 566 | ||
567 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | 567 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) |
568 | { | 568 | { |
569 | u8 b; | 569 | u8 b; |
570 | 570 | ||
571 | if ((end - start) <= 0) | 571 | if ((end - start) <= 0) |
572 | return NULL; | 572 | return NULL; |
573 | 573 | ||
574 | b = *start++; | 574 | b = *start++; |
575 | 575 | ||
576 | item->type = (b >> 2) & 3; | 576 | item->type = (b >> 2) & 3; |
577 | item->tag = (b >> 4) & 15; | 577 | item->tag = (b >> 4) & 15; |
578 | 578 | ||
579 | if (item->tag == HID_ITEM_TAG_LONG) { | 579 | if (item->tag == HID_ITEM_TAG_LONG) { |
580 | 580 | ||
581 | item->format = HID_ITEM_FORMAT_LONG; | 581 | item->format = HID_ITEM_FORMAT_LONG; |
582 | 582 | ||
583 | if ((end - start) < 2) | 583 | if ((end - start) < 2) |
584 | return NULL; | 584 | return NULL; |
585 | 585 | ||
586 | item->size = *start++; | 586 | item->size = *start++; |
587 | item->tag = *start++; | 587 | item->tag = *start++; |
588 | 588 | ||
589 | if ((end - start) < item->size) | 589 | if ((end - start) < item->size) |
590 | return NULL; | 590 | return NULL; |
591 | 591 | ||
592 | item->data.longdata = start; | 592 | item->data.longdata = start; |
593 | start += item->size; | 593 | start += item->size; |
594 | return start; | 594 | return start; |
595 | } | 595 | } |
596 | 596 | ||
597 | item->format = HID_ITEM_FORMAT_SHORT; | 597 | item->format = HID_ITEM_FORMAT_SHORT; |
598 | item->size = b & 3; | 598 | item->size = b & 3; |
599 | 599 | ||
600 | switch (item->size) { | 600 | switch (item->size) { |
601 | case 0: | 601 | case 0: |
602 | return start; | 602 | return start; |
603 | 603 | ||
604 | case 1: | 604 | case 1: |
605 | if ((end - start) < 1) | 605 | if ((end - start) < 1) |
606 | return NULL; | 606 | return NULL; |
607 | item->data.u8 = *start++; | 607 | item->data.u8 = *start++; |
608 | return start; | 608 | return start; |
609 | 609 | ||
610 | case 2: | 610 | case 2: |
611 | if ((end - start) < 2) | 611 | if ((end - start) < 2) |
612 | return NULL; | 612 | return NULL; |
613 | item->data.u16 = get_unaligned_le16(start); | 613 | item->data.u16 = get_unaligned_le16(start); |
614 | start = (__u8 *)((__le16 *)start + 1); | 614 | start = (__u8 *)((__le16 *)start + 1); |
615 | return start; | 615 | return start; |
616 | 616 | ||
617 | case 3: | 617 | case 3: |
618 | item->size++; | 618 | item->size++; |
619 | if ((end - start) < 4) | 619 | if ((end - start) < 4) |
620 | return NULL; | 620 | return NULL; |
621 | item->data.u32 = get_unaligned_le32(start); | 621 | item->data.u32 = get_unaligned_le32(start); |
622 | start = (__u8 *)((__le32 *)start + 1); | 622 | start = (__u8 *)((__le32 *)start + 1); |
623 | return start; | 623 | return start; |
624 | } | 624 | } |
625 | 625 | ||
626 | return NULL; | 626 | return NULL; |
627 | } | 627 | } |
628 | 628 | ||
629 | /** | 629 | /** |
630 | * hid_parse_report - parse device report | 630 | * hid_parse_report - parse device report |
631 | * | 631 | * |
632 | * @device: hid device | 632 | * @device: hid device |
633 | * @start: report start | 633 | * @start: report start |
634 | * @size: report size | 634 | * @size: report size |
635 | * | 635 | * |
636 | * Parse a report description into a hid_device structure. Reports are | 636 | * Parse a report description into a hid_device structure. Reports are |
637 | * enumerated, fields are attached to these reports. | 637 | * enumerated, fields are attached to these reports. |
638 | * 0 returned on success, otherwise nonzero error value. | 638 | * 0 returned on success, otherwise nonzero error value. |
639 | */ | 639 | */ |
640 | int hid_parse_report(struct hid_device *device, __u8 *start, | 640 | int hid_parse_report(struct hid_device *device, __u8 *start, |
641 | unsigned size) | 641 | unsigned size) |
642 | { | 642 | { |
643 | struct hid_parser *parser; | 643 | struct hid_parser *parser; |
644 | struct hid_item item; | 644 | struct hid_item item; |
645 | __u8 *end; | 645 | __u8 *end; |
646 | int ret; | 646 | int ret; |
647 | static int (*dispatch_type[])(struct hid_parser *parser, | 647 | static int (*dispatch_type[])(struct hid_parser *parser, |
648 | struct hid_item *item) = { | 648 | struct hid_item *item) = { |
649 | hid_parser_main, | 649 | hid_parser_main, |
650 | hid_parser_global, | 650 | hid_parser_global, |
651 | hid_parser_local, | 651 | hid_parser_local, |
652 | hid_parser_reserved | 652 | hid_parser_reserved |
653 | }; | 653 | }; |
654 | 654 | ||
655 | if (device->driver->report_fixup) | 655 | if (device->driver->report_fixup) |
656 | device->driver->report_fixup(device, start, size); | 656 | device->driver->report_fixup(device, start, size); |
657 | 657 | ||
658 | device->rdesc = kmalloc(size, GFP_KERNEL); | 658 | device->rdesc = kmalloc(size, GFP_KERNEL); |
659 | if (device->rdesc == NULL) | 659 | if (device->rdesc == NULL) |
660 | return -ENOMEM; | 660 | return -ENOMEM; |
661 | memcpy(device->rdesc, start, size); | 661 | memcpy(device->rdesc, start, size); |
662 | device->rsize = size; | 662 | device->rsize = size; |
663 | 663 | ||
664 | parser = vmalloc(sizeof(struct hid_parser)); | 664 | parser = vmalloc(sizeof(struct hid_parser)); |
665 | if (!parser) { | 665 | if (!parser) { |
666 | ret = -ENOMEM; | 666 | ret = -ENOMEM; |
667 | goto err; | 667 | goto err; |
668 | } | 668 | } |
669 | 669 | ||
670 | memset(parser, 0, sizeof(struct hid_parser)); | 670 | memset(parser, 0, sizeof(struct hid_parser)); |
671 | parser->device = device; | 671 | parser->device = device; |
672 | 672 | ||
673 | end = start + size; | 673 | end = start + size; |
674 | ret = -EINVAL; | 674 | ret = -EINVAL; |
675 | while ((start = fetch_item(start, end, &item)) != NULL) { | 675 | while ((start = fetch_item(start, end, &item)) != NULL) { |
676 | 676 | ||
677 | if (item.format != HID_ITEM_FORMAT_SHORT) { | 677 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
678 | dbg_hid("unexpected long global item\n"); | 678 | dbg_hid("unexpected long global item\n"); |
679 | goto err; | 679 | goto err; |
680 | } | 680 | } |
681 | 681 | ||
682 | if (dispatch_type[item.type](parser, &item)) { | 682 | if (dispatch_type[item.type](parser, &item)) { |
683 | dbg_hid("item %u %u %u %u parsing failed\n", | 683 | dbg_hid("item %u %u %u %u parsing failed\n", |
684 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); | 684 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); |
685 | goto err; | 685 | goto err; |
686 | } | 686 | } |
687 | 687 | ||
688 | if (start == end) { | 688 | if (start == end) { |
689 | if (parser->collection_stack_ptr) { | 689 | if (parser->collection_stack_ptr) { |
690 | dbg_hid("unbalanced collection at end of report description\n"); | 690 | dbg_hid("unbalanced collection at end of report description\n"); |
691 | goto err; | 691 | goto err; |
692 | } | 692 | } |
693 | if (parser->local.delimiter_depth) { | 693 | if (parser->local.delimiter_depth) { |
694 | dbg_hid("unbalanced delimiter at end of report description\n"); | 694 | dbg_hid("unbalanced delimiter at end of report description\n"); |
695 | goto err; | 695 | goto err; |
696 | } | 696 | } |
697 | vfree(parser); | 697 | vfree(parser); |
698 | return 0; | 698 | return 0; |
699 | } | 699 | } |
700 | } | 700 | } |
701 | 701 | ||
702 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); | 702 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); |
703 | err: | 703 | err: |
704 | vfree(parser); | 704 | vfree(parser); |
705 | return ret; | 705 | return ret; |
706 | } | 706 | } |
707 | EXPORT_SYMBOL_GPL(hid_parse_report); | 707 | EXPORT_SYMBOL_GPL(hid_parse_report); |
708 | 708 | ||
709 | /* | 709 | /* |
710 | * Convert a signed n-bit integer to signed 32-bit integer. Common | 710 | * Convert a signed n-bit integer to signed 32-bit integer. Common |
711 | * cases are done through the compiler, the screwed things has to be | 711 | * cases are done through the compiler, the screwed things has to be |
712 | * done by hand. | 712 | * done by hand. |
713 | */ | 713 | */ |
714 | 714 | ||
715 | static s32 snto32(__u32 value, unsigned n) | 715 | static s32 snto32(__u32 value, unsigned n) |
716 | { | 716 | { |
717 | switch (n) { | 717 | switch (n) { |
718 | case 8: return ((__s8)value); | 718 | case 8: return ((__s8)value); |
719 | case 16: return ((__s16)value); | 719 | case 16: return ((__s16)value); |
720 | case 32: return ((__s32)value); | 720 | case 32: return ((__s32)value); |
721 | } | 721 | } |
722 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; | 722 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; |
723 | } | 723 | } |
724 | 724 | ||
725 | /* | 725 | /* |
726 | * Convert a signed 32-bit integer to a signed n-bit integer. | 726 | * Convert a signed 32-bit integer to a signed n-bit integer. |
727 | */ | 727 | */ |
728 | 728 | ||
729 | static u32 s32ton(__s32 value, unsigned n) | 729 | static u32 s32ton(__s32 value, unsigned n) |
730 | { | 730 | { |
731 | s32 a = value >> (n - 1); | 731 | s32 a = value >> (n - 1); |
732 | if (a && a != -1) | 732 | if (a && a != -1) |
733 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; | 733 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; |
734 | return value & ((1 << n) - 1); | 734 | return value & ((1 << n) - 1); |
735 | } | 735 | } |
736 | 736 | ||
737 | /* | 737 | /* |
738 | * Extract/implement a data field from/to a little endian report (bit array). | 738 | * Extract/implement a data field from/to a little endian report (bit array). |
739 | * | 739 | * |
740 | * Code sort-of follows HID spec: | 740 | * Code sort-of follows HID spec: |
741 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf | 741 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf |
742 | * | 742 | * |
743 | * While the USB HID spec allows unlimited length bit fields in "report | 743 | * While the USB HID spec allows unlimited length bit fields in "report |
744 | * descriptors", most devices never use more than 16 bits. | 744 | * descriptors", most devices never use more than 16 bits. |
745 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. | 745 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. |
746 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". | 746 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". |
747 | */ | 747 | */ |
748 | 748 | ||
749 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | 749 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) |
750 | { | 750 | { |
751 | u64 x; | 751 | u64 x; |
752 | 752 | ||
753 | if (n > 32) | 753 | if (n > 32) |
754 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", | 754 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", |
755 | n, current->comm); | 755 | n, current->comm); |
756 | 756 | ||
757 | report += offset >> 3; /* adjust byte index */ | 757 | report += offset >> 3; /* adjust byte index */ |
758 | offset &= 7; /* now only need bit offset into one byte */ | 758 | offset &= 7; /* now only need bit offset into one byte */ |
759 | x = get_unaligned_le64(report); | 759 | x = get_unaligned_le64(report); |
760 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ | 760 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ |
761 | return (u32) x; | 761 | return (u32) x; |
762 | } | 762 | } |
763 | 763 | ||
764 | /* | 764 | /* |
765 | * "implement" : set bits in a little endian bit stream. | 765 | * "implement" : set bits in a little endian bit stream. |
766 | * Same concepts as "extract" (see comments above). | 766 | * Same concepts as "extract" (see comments above). |
767 | * The data mangled in the bit stream remains in little endian | 767 | * The data mangled in the bit stream remains in little endian |
768 | * order the whole time. It make more sense to talk about | 768 | * order the whole time. It make more sense to talk about |
769 | * endianness of register values by considering a register | 769 | * endianness of register values by considering a register |
770 | * a "cached" copy of the little endiad bit stream. | 770 | * a "cached" copy of the little endiad bit stream. |
771 | */ | 771 | */ |
772 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | 772 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
773 | { | 773 | { |
774 | u64 x; | 774 | u64 x; |
775 | u64 m = (1ULL << n) - 1; | 775 | u64 m = (1ULL << n) - 1; |
776 | 776 | ||
777 | if (n > 32) | 777 | if (n > 32) |
778 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", | 778 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", |
779 | n, current->comm); | 779 | n, current->comm); |
780 | 780 | ||
781 | if (value > m) | 781 | if (value > m) |
782 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", | 782 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", |
783 | value, current->comm); | 783 | value, current->comm); |
784 | WARN_ON(value > m); | 784 | WARN_ON(value > m); |
785 | value &= m; | 785 | value &= m; |
786 | 786 | ||
787 | report += offset >> 3; | 787 | report += offset >> 3; |
788 | offset &= 7; | 788 | offset &= 7; |
789 | 789 | ||
790 | x = get_unaligned_le64(report); | 790 | x = get_unaligned_le64(report); |
791 | x &= ~(m << offset); | 791 | x &= ~(m << offset); |
792 | x |= ((u64)value) << offset; | 792 | x |= ((u64)value) << offset; |
793 | put_unaligned_le64(x, report); | 793 | put_unaligned_le64(x, report); |
794 | } | 794 | } |
795 | 795 | ||
796 | /* | 796 | /* |
797 | * Search an array for a value. | 797 | * Search an array for a value. |
798 | */ | 798 | */ |
799 | 799 | ||
800 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) | 800 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) |
801 | { | 801 | { |
802 | while (n--) { | 802 | while (n--) { |
803 | if (*array++ == value) | 803 | if (*array++ == value) |
804 | return 0; | 804 | return 0; |
805 | } | 805 | } |
806 | return -1; | 806 | return -1; |
807 | } | 807 | } |
808 | 808 | ||
809 | /** | 809 | /** |
810 | * hid_match_report - check if driver's raw_event should be called | 810 | * hid_match_report - check if driver's raw_event should be called |
811 | * | 811 | * |
812 | * @hid: hid device | 812 | * @hid: hid device |
813 | * @report_type: type to match against | 813 | * @report_type: type to match against |
814 | * | 814 | * |
815 | * compare hid->driver->report_table->report_type to report->type | 815 | * compare hid->driver->report_table->report_type to report->type |
816 | */ | 816 | */ |
817 | static int hid_match_report(struct hid_device *hid, struct hid_report *report) | 817 | static int hid_match_report(struct hid_device *hid, struct hid_report *report) |
818 | { | 818 | { |
819 | const struct hid_report_id *id = hid->driver->report_table; | 819 | const struct hid_report_id *id = hid->driver->report_table; |
820 | 820 | ||
821 | if (!id) /* NULL means all */ | 821 | if (!id) /* NULL means all */ |
822 | return 1; | 822 | return 1; |
823 | 823 | ||
824 | for (; id->report_type != HID_TERMINATOR; id++) | 824 | for (; id->report_type != HID_TERMINATOR; id++) |
825 | if (id->report_type == HID_ANY_ID || | 825 | if (id->report_type == HID_ANY_ID || |
826 | id->report_type == report->type) | 826 | id->report_type == report->type) |
827 | return 1; | 827 | return 1; |
828 | return 0; | 828 | return 0; |
829 | } | 829 | } |
830 | 830 | ||
831 | /** | 831 | /** |
832 | * hid_match_usage - check if driver's event should be called | 832 | * hid_match_usage - check if driver's event should be called |
833 | * | 833 | * |
834 | * @hid: hid device | 834 | * @hid: hid device |
835 | * @usage: usage to match against | 835 | * @usage: usage to match against |
836 | * | 836 | * |
837 | * compare hid->driver->usage_table->usage_{type,code} to | 837 | * compare hid->driver->usage_table->usage_{type,code} to |
838 | * usage->usage_{type,code} | 838 | * usage->usage_{type,code} |
839 | */ | 839 | */ |
840 | static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) | 840 | static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) |
841 | { | 841 | { |
842 | const struct hid_usage_id *id = hid->driver->usage_table; | 842 | const struct hid_usage_id *id = hid->driver->usage_table; |
843 | 843 | ||
844 | if (!id) /* NULL means all */ | 844 | if (!id) /* NULL means all */ |
845 | return 1; | 845 | return 1; |
846 | 846 | ||
847 | for (; id->usage_type != HID_ANY_ID - 1; id++) | 847 | for (; id->usage_type != HID_ANY_ID - 1; id++) |
848 | if ((id->usage_hid == HID_ANY_ID || | 848 | if ((id->usage_hid == HID_ANY_ID || |
849 | id->usage_hid == usage->hid) && | 849 | id->usage_hid == usage->hid) && |
850 | (id->usage_type == HID_ANY_ID || | 850 | (id->usage_type == HID_ANY_ID || |
851 | id->usage_type == usage->type) && | 851 | id->usage_type == usage->type) && |
852 | (id->usage_code == HID_ANY_ID || | 852 | (id->usage_code == HID_ANY_ID || |
853 | id->usage_code == usage->code)) | 853 | id->usage_code == usage->code)) |
854 | return 1; | 854 | return 1; |
855 | return 0; | 855 | return 0; |
856 | } | 856 | } |
857 | 857 | ||
858 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, | 858 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, |
859 | struct hid_usage *usage, __s32 value, int interrupt) | 859 | struct hid_usage *usage, __s32 value, int interrupt) |
860 | { | 860 | { |
861 | struct hid_driver *hdrv = hid->driver; | 861 | struct hid_driver *hdrv = hid->driver; |
862 | int ret; | 862 | int ret; |
863 | 863 | ||
864 | hid_dump_input(usage, value); | 864 | hid_dump_input(usage, value); |
865 | 865 | ||
866 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { | 866 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { |
867 | ret = hdrv->event(hid, field, usage, value); | 867 | ret = hdrv->event(hid, field, usage, value); |
868 | if (ret != 0) { | 868 | if (ret != 0) { |
869 | if (ret < 0) | 869 | if (ret < 0) |
870 | dbg_hid("%s's event failed with %d\n", | 870 | dbg_hid("%s's event failed with %d\n", |
871 | hdrv->name, ret); | 871 | hdrv->name, ret); |
872 | return; | 872 | return; |
873 | } | 873 | } |
874 | } | 874 | } |
875 | 875 | ||
876 | if (hid->claimed & HID_CLAIMED_INPUT) | 876 | if (hid->claimed & HID_CLAIMED_INPUT) |
877 | hidinput_hid_event(hid, field, usage, value); | 877 | hidinput_hid_event(hid, field, usage, value); |
878 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) | 878 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) |
879 | hid->hiddev_hid_event(hid, field, usage, value); | 879 | hid->hiddev_hid_event(hid, field, usage, value); |
880 | } | 880 | } |
881 | 881 | ||
882 | /* | 882 | /* |
883 | * Analyse a received field, and fetch the data from it. The field | 883 | * Analyse a received field, and fetch the data from it. The field |
884 | * content is stored for next report processing (we do differential | 884 | * content is stored for next report processing (we do differential |
885 | * reporting to the layer). | 885 | * reporting to the layer). |
886 | */ | 886 | */ |
887 | 887 | ||
888 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, | 888 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, |
889 | __u8 *data, int interrupt) | 889 | __u8 *data, int interrupt) |
890 | { | 890 | { |
891 | unsigned n; | 891 | unsigned n; |
892 | unsigned count = field->report_count; | 892 | unsigned count = field->report_count; |
893 | unsigned offset = field->report_offset; | 893 | unsigned offset = field->report_offset; |
894 | unsigned size = field->report_size; | 894 | unsigned size = field->report_size; |
895 | __s32 min = field->logical_minimum; | 895 | __s32 min = field->logical_minimum; |
896 | __s32 max = field->logical_maximum; | 896 | __s32 max = field->logical_maximum; |
897 | __s32 *value; | 897 | __s32 *value; |
898 | 898 | ||
899 | if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) | 899 | if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) |
900 | return; | 900 | return; |
901 | 901 | ||
902 | for (n = 0; n < count; n++) { | 902 | for (n = 0; n < count; n++) { |
903 | 903 | ||
904 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : | 904 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : |
905 | extract(data, offset + n * size, size); | 905 | extract(data, offset + n * size, size); |
906 | 906 | ||
907 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ | 907 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ |
908 | && value[n] >= min && value[n] <= max | 908 | && value[n] >= min && value[n] <= max |
909 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) | 909 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) |
910 | goto exit; | 910 | goto exit; |
911 | } | 911 | } |
912 | 912 | ||
913 | for (n = 0; n < count; n++) { | 913 | for (n = 0; n < count; n++) { |
914 | 914 | ||
915 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { | 915 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { |
916 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt); | 916 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt); |
917 | continue; | 917 | continue; |
918 | } | 918 | } |
919 | 919 | ||
920 | if (field->value[n] >= min && field->value[n] <= max | 920 | if (field->value[n] >= min && field->value[n] <= max |
921 | && field->usage[field->value[n] - min].hid | 921 | && field->usage[field->value[n] - min].hid |
922 | && search(value, field->value[n], count)) | 922 | && search(value, field->value[n], count)) |
923 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); | 923 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); |
924 | 924 | ||
925 | if (value[n] >= min && value[n] <= max | 925 | if (value[n] >= min && value[n] <= max |
926 | && field->usage[value[n] - min].hid | 926 | && field->usage[value[n] - min].hid |
927 | && search(field->value, value[n], count)) | 927 | && search(field->value, value[n], count)) |
928 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); | 928 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); |
929 | } | 929 | } |
930 | 930 | ||
931 | memcpy(field->value, value, count * sizeof(__s32)); | 931 | memcpy(field->value, value, count * sizeof(__s32)); |
932 | exit: | 932 | exit: |
933 | kfree(value); | 933 | kfree(value); |
934 | } | 934 | } |
935 | 935 | ||
936 | /* | 936 | /* |
937 | * Output the field into the report. | 937 | * Output the field into the report. |
938 | */ | 938 | */ |
939 | 939 | ||
940 | static void hid_output_field(struct hid_field *field, __u8 *data) | 940 | static void hid_output_field(struct hid_field *field, __u8 *data) |
941 | { | 941 | { |
942 | unsigned count = field->report_count; | 942 | unsigned count = field->report_count; |
943 | unsigned offset = field->report_offset; | 943 | unsigned offset = field->report_offset; |
944 | unsigned size = field->report_size; | 944 | unsigned size = field->report_size; |
945 | unsigned bitsused = offset + count * size; | 945 | unsigned bitsused = offset + count * size; |
946 | unsigned n; | 946 | unsigned n; |
947 | 947 | ||
948 | /* make sure the unused bits in the last byte are zeros */ | 948 | /* make sure the unused bits in the last byte are zeros */ |
949 | if (count > 0 && size > 0 && (bitsused % 8) != 0) | 949 | if (count > 0 && size > 0 && (bitsused % 8) != 0) |
950 | data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1; | 950 | data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1; |
951 | 951 | ||
952 | for (n = 0; n < count; n++) { | 952 | for (n = 0; n < count; n++) { |
953 | if (field->logical_minimum < 0) /* signed values */ | 953 | if (field->logical_minimum < 0) /* signed values */ |
954 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); | 954 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); |
955 | else /* unsigned values */ | 955 | else /* unsigned values */ |
956 | implement(data, offset + n * size, size, field->value[n]); | 956 | implement(data, offset + n * size, size, field->value[n]); |
957 | } | 957 | } |
958 | } | 958 | } |
959 | 959 | ||
960 | /* | 960 | /* |
961 | * Create a report. | 961 | * Create a report. |
962 | */ | 962 | */ |
963 | 963 | ||
964 | void hid_output_report(struct hid_report *report, __u8 *data) | 964 | void hid_output_report(struct hid_report *report, __u8 *data) |
965 | { | 965 | { |
966 | unsigned n; | 966 | unsigned n; |
967 | 967 | ||
968 | if (report->id > 0) | 968 | if (report->id > 0) |
969 | *data++ = report->id; | 969 | *data++ = report->id; |
970 | 970 | ||
971 | for (n = 0; n < report->maxfield; n++) | 971 | for (n = 0; n < report->maxfield; n++) |
972 | hid_output_field(report->field[n], data); | 972 | hid_output_field(report->field[n], data); |
973 | } | 973 | } |
974 | EXPORT_SYMBOL_GPL(hid_output_report); | 974 | EXPORT_SYMBOL_GPL(hid_output_report); |
975 | 975 | ||
976 | /* | 976 | /* |
977 | * Set a field value. The report this field belongs to has to be | 977 | * Set a field value. The report this field belongs to has to be |
978 | * created and transferred to the device, to set this value in the | 978 | * created and transferred to the device, to set this value in the |
979 | * device. | 979 | * device. |
980 | */ | 980 | */ |
981 | 981 | ||
982 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) | 982 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) |
983 | { | 983 | { |
984 | unsigned size = field->report_size; | 984 | unsigned size = field->report_size; |
985 | 985 | ||
986 | hid_dump_input(field->usage + offset, value); | 986 | hid_dump_input(field->usage + offset, value); |
987 | 987 | ||
988 | if (offset >= field->report_count) { | 988 | if (offset >= field->report_count) { |
989 | dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); | 989 | dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); |
990 | hid_dump_field(field, 8); | 990 | hid_dump_field(field, 8); |
991 | return -1; | 991 | return -1; |
992 | } | 992 | } |
993 | if (field->logical_minimum < 0) { | 993 | if (field->logical_minimum < 0) { |
994 | if (value != snto32(s32ton(value, size), size)) { | 994 | if (value != snto32(s32ton(value, size), size)) { |
995 | dbg_hid("value %d is out of range\n", value); | 995 | dbg_hid("value %d is out of range\n", value); |
996 | return -1; | 996 | return -1; |
997 | } | 997 | } |
998 | } | 998 | } |
999 | field->value[offset] = value; | 999 | field->value[offset] = value; |
1000 | return 0; | 1000 | return 0; |
1001 | } | 1001 | } |
1002 | EXPORT_SYMBOL_GPL(hid_set_field); | 1002 | EXPORT_SYMBOL_GPL(hid_set_field); |
1003 | 1003 | ||
1004 | static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, | 1004 | static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, |
1005 | const u8 *data) | 1005 | const u8 *data) |
1006 | { | 1006 | { |
1007 | struct hid_report *report; | 1007 | struct hid_report *report; |
1008 | unsigned int n = 0; /* Normally report number is 0 */ | 1008 | unsigned int n = 0; /* Normally report number is 0 */ |
1009 | 1009 | ||
1010 | /* Device uses numbered reports, data[0] is report number */ | 1010 | /* Device uses numbered reports, data[0] is report number */ |
1011 | if (report_enum->numbered) | 1011 | if (report_enum->numbered) |
1012 | n = *data; | 1012 | n = *data; |
1013 | 1013 | ||
1014 | report = report_enum->report_id_hash[n]; | 1014 | report = report_enum->report_id_hash[n]; |
1015 | if (report == NULL) | 1015 | if (report == NULL) |
1016 | dbg_hid("undefined report_id %u received\n", n); | 1016 | dbg_hid("undefined report_id %u received\n", n); |
1017 | 1017 | ||
1018 | return report; | 1018 | return report; |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 1021 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
1022 | int interrupt) | 1022 | int interrupt) |
1023 | { | 1023 | { |
1024 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1024 | struct hid_report_enum *report_enum = hid->report_enum + type; |
1025 | struct hid_report *report; | 1025 | struct hid_report *report; |
1026 | unsigned int a; | 1026 | unsigned int a; |
1027 | int rsize, csize = size; | 1027 | int rsize, csize = size; |
1028 | u8 *cdata = data; | 1028 | u8 *cdata = data; |
1029 | 1029 | ||
1030 | report = hid_get_report(report_enum, data); | 1030 | report = hid_get_report(report_enum, data); |
1031 | if (!report) | 1031 | if (!report) |
1032 | return; | 1032 | return; |
1033 | 1033 | ||
1034 | if (report_enum->numbered) { | 1034 | if (report_enum->numbered) { |
1035 | cdata++; | 1035 | cdata++; |
1036 | csize--; | 1036 | csize--; |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | rsize = ((report->size - 1) >> 3) + 1; | 1039 | rsize = ((report->size - 1) >> 3) + 1; |
1040 | 1040 | ||
1041 | if (csize < rsize) { | 1041 | if (csize < rsize) { |
1042 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, | 1042 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, |
1043 | csize, rsize); | 1043 | csize, rsize); |
1044 | memset(cdata + csize, 0, rsize - csize); | 1044 | memset(cdata + csize, 0, rsize - csize); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) | 1047 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) |
1048 | hid->hiddev_report_event(hid, report); | 1048 | hid->hiddev_report_event(hid, report); |
1049 | if (hid->claimed & HID_CLAIMED_HIDRAW) { | 1049 | if (hid->claimed & HID_CLAIMED_HIDRAW) { |
1050 | /* numbered reports need to be passed with the report num */ | 1050 | /* numbered reports need to be passed with the report num */ |
1051 | if (report_enum->numbered) | 1051 | if (report_enum->numbered) |
1052 | hidraw_report_event(hid, data - 1, size + 1); | 1052 | hidraw_report_event(hid, data - 1, size + 1); |
1053 | else | 1053 | else |
1054 | hidraw_report_event(hid, data, size); | 1054 | hidraw_report_event(hid, data, size); |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | for (a = 0; a < report->maxfield; a++) | 1057 | for (a = 0; a < report->maxfield; a++) |
1058 | hid_input_field(hid, report->field[a], cdata, interrupt); | 1058 | hid_input_field(hid, report->field[a], cdata, interrupt); |
1059 | 1059 | ||
1060 | if (hid->claimed & HID_CLAIMED_INPUT) | 1060 | if (hid->claimed & HID_CLAIMED_INPUT) |
1061 | hidinput_report_event(hid, report); | 1061 | hidinput_report_event(hid, report); |
1062 | } | 1062 | } |
1063 | EXPORT_SYMBOL_GPL(hid_report_raw_event); | 1063 | EXPORT_SYMBOL_GPL(hid_report_raw_event); |
1064 | 1064 | ||
1065 | /** | 1065 | /** |
1066 | * hid_input_report - report data from lower layer (usb, bt...) | 1066 | * hid_input_report - report data from lower layer (usb, bt...) |
1067 | * | 1067 | * |
1068 | * @hid: hid device | 1068 | * @hid: hid device |
1069 | * @type: HID report type (HID_*_REPORT) | 1069 | * @type: HID report type (HID_*_REPORT) |
1070 | * @data: report contents | 1070 | * @data: report contents |
1071 | * @size: size of data parameter | 1071 | * @size: size of data parameter |
1072 | * @interrupt: called from atomic? | 1072 | * @interrupt: called from atomic? |
1073 | * | 1073 | * |
1074 | * This is data entry for lower layers. | 1074 | * This is data entry for lower layers. |
1075 | */ | 1075 | */ |
1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | 1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) |
1077 | { | 1077 | { |
1078 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1078 | struct hid_report_enum *report_enum = hid->report_enum + type; |
1079 | struct hid_driver *hdrv = hid->driver; | 1079 | struct hid_driver *hdrv = hid->driver; |
1080 | struct hid_report *report; | 1080 | struct hid_report *report; |
1081 | unsigned int i; | 1081 | unsigned int i; |
1082 | int ret; | 1082 | int ret; |
1083 | 1083 | ||
1084 | if (!hid || !hid->driver) | 1084 | if (!hid || !hid->driver) |
1085 | return -ENODEV; | 1085 | return -ENODEV; |
1086 | 1086 | ||
1087 | if (!size) { | 1087 | if (!size) { |
1088 | dbg_hid("empty report\n"); | 1088 | dbg_hid("empty report\n"); |
1089 | return -1; | 1089 | return -1; |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); | 1092 | dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); |
1093 | 1093 | ||
1094 | report = hid_get_report(report_enum, data); | 1094 | report = hid_get_report(report_enum, data); |
1095 | if (!report) | 1095 | if (!report) |
1096 | return -1; | 1096 | return -1; |
1097 | 1097 | ||
1098 | /* dump the report */ | 1098 | /* dump the report */ |
1099 | dbg_hid("report %d (size %u) = ", report->id, size); | 1099 | dbg_hid("report %d (size %u) = ", report->id, size); |
1100 | for (i = 0; i < size; i++) | 1100 | for (i = 0; i < size; i++) |
1101 | dbg_hid_line(" %02x", data[i]); | 1101 | dbg_hid_line(" %02x", data[i]); |
1102 | dbg_hid_line("\n"); | 1102 | dbg_hid_line("\n"); |
1103 | 1103 | ||
1104 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { | 1104 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { |
1105 | ret = hdrv->raw_event(hid, report, data, size); | 1105 | ret = hdrv->raw_event(hid, report, data, size); |
1106 | if (ret != 0) | 1106 | if (ret != 0) |
1107 | return ret < 0 ? ret : 0; | 1107 | return ret < 0 ? ret : 0; |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | hid_report_raw_event(hid, type, data, size, interrupt); | 1110 | hid_report_raw_event(hid, type, data, size, interrupt); |
1111 | 1111 | ||
1112 | return 0; | 1112 | return 0; |
1113 | } | 1113 | } |
1114 | EXPORT_SYMBOL_GPL(hid_input_report); | 1114 | EXPORT_SYMBOL_GPL(hid_input_report); |
1115 | 1115 | ||
1116 | static bool hid_match_one_id(struct hid_device *hdev, | 1116 | static bool hid_match_one_id(struct hid_device *hdev, |
1117 | const struct hid_device_id *id) | 1117 | const struct hid_device_id *id) |
1118 | { | 1118 | { |
1119 | return id->bus == hdev->bus && | 1119 | return id->bus == hdev->bus && |
1120 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && | 1120 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && |
1121 | (id->product == HID_ANY_ID || id->product == hdev->product); | 1121 | (id->product == HID_ANY_ID || id->product == hdev->product); |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, | 1124 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, |
1125 | const struct hid_device_id *id) | 1125 | const struct hid_device_id *id) |
1126 | { | 1126 | { |
1127 | for (; id->bus; id++) | 1127 | for (; id->bus; id++) |
1128 | if (hid_match_one_id(hdev, id)) | 1128 | if (hid_match_one_id(hdev, id)) |
1129 | return id; | 1129 | return id; |
1130 | 1130 | ||
1131 | return NULL; | 1131 | return NULL; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | static const struct hid_device_id hid_hiddev_list[] = { | 1134 | static const struct hid_device_id hid_hiddev_list[] = { |
1135 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) }, | 1135 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) }, |
1136 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) }, | 1136 | { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) }, |
1137 | { } | 1137 | { } |
1138 | }; | 1138 | }; |
1139 | 1139 | ||
1140 | static bool hid_hiddev(struct hid_device *hdev) | 1140 | static bool hid_hiddev(struct hid_device *hdev) |
1141 | { | 1141 | { |
1142 | return !!hid_match_id(hdev, hid_hiddev_list); | 1142 | return !!hid_match_id(hdev, hid_hiddev_list); |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | 1145 | int hid_connect(struct hid_device *hdev, unsigned int connect_mask) |
1146 | { | 1146 | { |
1147 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", | 1147 | static const char *types[] = { "Device", "Pointer", "Mouse", "Device", |
1148 | "Joystick", "Gamepad", "Keyboard", "Keypad", | 1148 | "Joystick", "Gamepad", "Keyboard", "Keypad", |
1149 | "Multi-Axis Controller" | 1149 | "Multi-Axis Controller" |
1150 | }; | 1150 | }; |
1151 | const char *type, *bus; | 1151 | const char *type, *bus; |
1152 | char buf[64]; | 1152 | char buf[64]; |
1153 | unsigned int i; | 1153 | unsigned int i; |
1154 | int len; | 1154 | int len; |
1155 | 1155 | ||
1156 | if (hdev->bus != BUS_USB) | 1156 | if (hdev->bus != BUS_USB) |
1157 | connect_mask &= ~HID_CONNECT_HIDDEV; | 1157 | connect_mask &= ~HID_CONNECT_HIDDEV; |
1158 | if (hid_hiddev(hdev)) | 1158 | if (hid_hiddev(hdev)) |
1159 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | 1159 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; |
1160 | 1160 | ||
1161 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, | 1161 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, |
1162 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) | 1162 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) |
1163 | hdev->claimed |= HID_CLAIMED_INPUT; | 1163 | hdev->claimed |= HID_CLAIMED_INPUT; |
1164 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && | 1164 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && |
1165 | !hdev->hiddev_connect(hdev, | 1165 | !hdev->hiddev_connect(hdev, |
1166 | connect_mask & HID_CONNECT_HIDDEV_FORCE)) | 1166 | connect_mask & HID_CONNECT_HIDDEV_FORCE)) |
1167 | hdev->claimed |= HID_CLAIMED_HIDDEV; | 1167 | hdev->claimed |= HID_CLAIMED_HIDDEV; |
1168 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) | 1168 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) |
1169 | hdev->claimed |= HID_CLAIMED_HIDRAW; | 1169 | hdev->claimed |= HID_CLAIMED_HIDRAW; |
1170 | 1170 | ||
1171 | if (!hdev->claimed) { | 1171 | if (!hdev->claimed) { |
1172 | dev_err(&hdev->dev, "claimed by neither input, hiddev nor " | 1172 | dev_err(&hdev->dev, "claimed by neither input, hiddev nor " |
1173 | "hidraw\n"); | 1173 | "hidraw\n"); |
1174 | return -ENODEV; | 1174 | return -ENODEV; |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | if ((hdev->claimed & HID_CLAIMED_INPUT) && | 1177 | if ((hdev->claimed & HID_CLAIMED_INPUT) && |
1178 | (connect_mask & HID_CONNECT_FF) && hdev->ff_init) | 1178 | (connect_mask & HID_CONNECT_FF) && hdev->ff_init) |
1179 | hdev->ff_init(hdev); | 1179 | hdev->ff_init(hdev); |
1180 | 1180 | ||
1181 | len = 0; | 1181 | len = 0; |
1182 | if (hdev->claimed & HID_CLAIMED_INPUT) | 1182 | if (hdev->claimed & HID_CLAIMED_INPUT) |
1183 | len += sprintf(buf + len, "input"); | 1183 | len += sprintf(buf + len, "input"); |
1184 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | 1184 | if (hdev->claimed & HID_CLAIMED_HIDDEV) |
1185 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", | 1185 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", |
1186 | hdev->minor); | 1186 | hdev->minor); |
1187 | if (hdev->claimed & HID_CLAIMED_HIDRAW) | 1187 | if (hdev->claimed & HID_CLAIMED_HIDRAW) |
1188 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", | 1188 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", |
1189 | ((struct hidraw *)hdev->hidraw)->minor); | 1189 | ((struct hidraw *)hdev->hidraw)->minor); |
1190 | 1190 | ||
1191 | type = "Device"; | 1191 | type = "Device"; |
1192 | for (i = 0; i < hdev->maxcollection; i++) { | 1192 | for (i = 0; i < hdev->maxcollection; i++) { |
1193 | struct hid_collection *col = &hdev->collection[i]; | 1193 | struct hid_collection *col = &hdev->collection[i]; |
1194 | if (col->type == HID_COLLECTION_APPLICATION && | 1194 | if (col->type == HID_COLLECTION_APPLICATION && |
1195 | (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && | 1195 | (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && |
1196 | (col->usage & 0xffff) < ARRAY_SIZE(types)) { | 1196 | (col->usage & 0xffff) < ARRAY_SIZE(types)) { |
1197 | type = types[col->usage & 0xffff]; | 1197 | type = types[col->usage & 0xffff]; |
1198 | break; | 1198 | break; |
1199 | } | 1199 | } |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | switch (hdev->bus) { | 1202 | switch (hdev->bus) { |
1203 | case BUS_USB: | 1203 | case BUS_USB: |
1204 | bus = "USB"; | 1204 | bus = "USB"; |
1205 | break; | 1205 | break; |
1206 | case BUS_BLUETOOTH: | 1206 | case BUS_BLUETOOTH: |
1207 | bus = "BLUETOOTH"; | 1207 | bus = "BLUETOOTH"; |
1208 | break; | 1208 | break; |
1209 | default: | 1209 | default: |
1210 | bus = "<UNKNOWN>"; | 1210 | bus = "<UNKNOWN>"; |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", | 1213 | dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", |
1214 | buf, bus, hdev->version >> 8, hdev->version & 0xff, | 1214 | buf, bus, hdev->version >> 8, hdev->version & 0xff, |
1215 | type, hdev->name, hdev->phys); | 1215 | type, hdev->name, hdev->phys); |
1216 | 1216 | ||
1217 | return 0; | 1217 | return 0; |
1218 | } | 1218 | } |
1219 | EXPORT_SYMBOL_GPL(hid_connect); | 1219 | EXPORT_SYMBOL_GPL(hid_connect); |
1220 | 1220 | ||
1221 | /* a list of devices for which there is a specialized driver on HID bus */ | 1221 | /* a list of devices for which there is a specialized driver on HID bus */ |
1222 | static const struct hid_device_id hid_blacklist[] = { | 1222 | static const struct hid_device_id hid_blacklist[] = { |
1223 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1223 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
1224 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1224 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
1225 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | 1225 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, |
1226 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1226 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1227 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1227 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
1228 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1228 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
1229 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, | 1229 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, |
1230 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, | 1230 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, |
1231 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, | 1231 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, |
1232 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, | 1232 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, |
1233 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, | 1233 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, |
1234 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, | 1234 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, |
1235 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, | 1235 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, |
1236 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, | 1236 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, |
1237 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, | 1237 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, |
1238 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, | 1238 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, |
1239 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) }, | 1239 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) }, |
1240 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) }, | 1240 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) }, |
1241 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) }, | 1241 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) }, |
1242 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) }, | 1242 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) }, |
1243 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) }, | 1243 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) }, |
1244 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) }, | 1244 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) }, |
1245 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1245 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
1246 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1246 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
1247 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1247 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
1248 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, | 1248 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, |
1249 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, | 1249 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, |
1250 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, | 1250 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, |
1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, | 1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, |
1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, | 1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, |
1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, | 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, |
1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, |
1258 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, |
1259 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | 1259 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, |
1260 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1260 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1261 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1261 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1262 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1262 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1263 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1263 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
1264 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 1264 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
1265 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, | 1265 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, |
1266 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, | 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, |
1267 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1268 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1269 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1270 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1271 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1272 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1272 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1273 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1273 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1274 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1274 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1275 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1275 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1276 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1276 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1277 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1277 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
1278 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1278 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1279 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1279 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
1280 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, | 1280 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, |
1281 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1281 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
1282 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, | 1282 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, |
1283 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, | 1283 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, |
1284 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, | 1284 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, |
1285 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, | 1285 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, |
1286 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, | 1286 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, |
1287 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, | 1287 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, |
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, | 1288 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, |
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, | 1289 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, |
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, | 1290 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, |
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, | 1291 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, |
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, | 1292 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, |
1293 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, |
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, | 1294 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, |
1295 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, |
1296 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, | 1296 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, |
1297 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1297 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
1298 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, | 1298 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, |
1299 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, |
1300 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
1301 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1301 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1302 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1302 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1303 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1303 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1304 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1305 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 1305 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
1306 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1306 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1307 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1307 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
1308 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1308 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1309 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1309 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
1310 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1310 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
1311 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, | 1311 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, |
1312 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, | 1312 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, |
1313 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1313 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1314 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, | 1314 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, |
1315 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, | 1315 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, |
1316 | 1316 | ||
1317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, | 1317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, |
1318 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, | 1318 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, |
1319 | { } | 1319 | { } |
1320 | }; | 1320 | }; |
1321 | 1321 | ||
1322 | struct hid_dynid { | 1322 | struct hid_dynid { |
1323 | struct list_head list; | 1323 | struct list_head list; |
1324 | struct hid_device_id id; | 1324 | struct hid_device_id id; |
1325 | }; | 1325 | }; |
1326 | 1326 | ||
1327 | /** | 1327 | /** |
1328 | * store_new_id - add a new HID device ID to this driver and re-probe devices | 1328 | * store_new_id - add a new HID device ID to this driver and re-probe devices |
1329 | * @driver: target device driver | 1329 | * @driver: target device driver |
1330 | * @buf: buffer for scanning device ID data | 1330 | * @buf: buffer for scanning device ID data |
1331 | * @count: input size | 1331 | * @count: input size |
1332 | * | 1332 | * |
1333 | * Adds a new dynamic hid device ID to this driver, | 1333 | * Adds a new dynamic hid device ID to this driver, |
1334 | * and causes the driver to probe for all devices again. | 1334 | * and causes the driver to probe for all devices again. |
1335 | */ | 1335 | */ |
1336 | static ssize_t store_new_id(struct device_driver *drv, const char *buf, | 1336 | static ssize_t store_new_id(struct device_driver *drv, const char *buf, |
1337 | size_t count) | 1337 | size_t count) |
1338 | { | 1338 | { |
1339 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1339 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1340 | struct hid_dynid *dynid; | 1340 | struct hid_dynid *dynid; |
1341 | __u32 bus, vendor, product; | 1341 | __u32 bus, vendor, product; |
1342 | unsigned long driver_data = 0; | 1342 | unsigned long driver_data = 0; |
1343 | int ret; | 1343 | int ret; |
1344 | 1344 | ||
1345 | ret = sscanf(buf, "%x %x %x %lx", | 1345 | ret = sscanf(buf, "%x %x %x %lx", |
1346 | &bus, &vendor, &product, &driver_data); | 1346 | &bus, &vendor, &product, &driver_data); |
1347 | if (ret < 3) | 1347 | if (ret < 3) |
1348 | return -EINVAL; | 1348 | return -EINVAL; |
1349 | 1349 | ||
1350 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | 1350 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); |
1351 | if (!dynid) | 1351 | if (!dynid) |
1352 | return -ENOMEM; | 1352 | return -ENOMEM; |
1353 | 1353 | ||
1354 | dynid->id.bus = bus; | 1354 | dynid->id.bus = bus; |
1355 | dynid->id.vendor = vendor; | 1355 | dynid->id.vendor = vendor; |
1356 | dynid->id.product = product; | 1356 | dynid->id.product = product; |
1357 | dynid->id.driver_data = driver_data; | 1357 | dynid->id.driver_data = driver_data; |
1358 | 1358 | ||
1359 | spin_lock(&hdrv->dyn_lock); | 1359 | spin_lock(&hdrv->dyn_lock); |
1360 | list_add_tail(&dynid->list, &hdrv->dyn_list); | 1360 | list_add_tail(&dynid->list, &hdrv->dyn_list); |
1361 | spin_unlock(&hdrv->dyn_lock); | 1361 | spin_unlock(&hdrv->dyn_lock); |
1362 | 1362 | ||
1363 | ret = 0; | 1363 | ret = 0; |
1364 | if (get_driver(&hdrv->driver)) { | 1364 | if (get_driver(&hdrv->driver)) { |
1365 | ret = driver_attach(&hdrv->driver); | 1365 | ret = driver_attach(&hdrv->driver); |
1366 | put_driver(&hdrv->driver); | 1366 | put_driver(&hdrv->driver); |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | return ret ? : count; | 1369 | return ret ? : count; |
1370 | } | 1370 | } |
1371 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | 1371 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); |
1372 | 1372 | ||
1373 | static void hid_free_dynids(struct hid_driver *hdrv) | 1373 | static void hid_free_dynids(struct hid_driver *hdrv) |
1374 | { | 1374 | { |
1375 | struct hid_dynid *dynid, *n; | 1375 | struct hid_dynid *dynid, *n; |
1376 | 1376 | ||
1377 | spin_lock(&hdrv->dyn_lock); | 1377 | spin_lock(&hdrv->dyn_lock); |
1378 | list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) { | 1378 | list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) { |
1379 | list_del(&dynid->list); | 1379 | list_del(&dynid->list); |
1380 | kfree(dynid); | 1380 | kfree(dynid); |
1381 | } | 1381 | } |
1382 | spin_unlock(&hdrv->dyn_lock); | 1382 | spin_unlock(&hdrv->dyn_lock); |
1383 | } | 1383 | } |
1384 | 1384 | ||
1385 | static const struct hid_device_id *hid_match_device(struct hid_device *hdev, | 1385 | static const struct hid_device_id *hid_match_device(struct hid_device *hdev, |
1386 | struct hid_driver *hdrv) | 1386 | struct hid_driver *hdrv) |
1387 | { | 1387 | { |
1388 | struct hid_dynid *dynid; | 1388 | struct hid_dynid *dynid; |
1389 | 1389 | ||
1390 | spin_lock(&hdrv->dyn_lock); | 1390 | spin_lock(&hdrv->dyn_lock); |
1391 | list_for_each_entry(dynid, &hdrv->dyn_list, list) { | 1391 | list_for_each_entry(dynid, &hdrv->dyn_list, list) { |
1392 | if (hid_match_one_id(hdev, &dynid->id)) { | 1392 | if (hid_match_one_id(hdev, &dynid->id)) { |
1393 | spin_unlock(&hdrv->dyn_lock); | 1393 | spin_unlock(&hdrv->dyn_lock); |
1394 | return &dynid->id; | 1394 | return &dynid->id; |
1395 | } | 1395 | } |
1396 | } | 1396 | } |
1397 | spin_unlock(&hdrv->dyn_lock); | 1397 | spin_unlock(&hdrv->dyn_lock); |
1398 | 1398 | ||
1399 | return hid_match_id(hdev, hdrv->id_table); | 1399 | return hid_match_id(hdev, hdrv->id_table); |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | static int hid_bus_match(struct device *dev, struct device_driver *drv) | 1402 | static int hid_bus_match(struct device *dev, struct device_driver *drv) |
1403 | { | 1403 | { |
1404 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1404 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1405 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1405 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1406 | 1406 | ||
1407 | if (!hid_match_device(hdev, hdrv)) | 1407 | if (!hid_match_device(hdev, hdrv)) |
1408 | return 0; | 1408 | return 0; |
1409 | 1409 | ||
1410 | /* generic wants all non-blacklisted */ | 1410 | /* generic wants all non-blacklisted */ |
1411 | if (!strncmp(hdrv->name, "generic-", 8)) | 1411 | if (!strncmp(hdrv->name, "generic-", 8)) |
1412 | return !hid_match_id(hdev, hid_blacklist); | 1412 | return !hid_match_id(hdev, hid_blacklist); |
1413 | 1413 | ||
1414 | return 1; | 1414 | return 1; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | static int hid_device_probe(struct device *dev) | 1417 | static int hid_device_probe(struct device *dev) |
1418 | { | 1418 | { |
1419 | struct hid_driver *hdrv = container_of(dev->driver, | 1419 | struct hid_driver *hdrv = container_of(dev->driver, |
1420 | struct hid_driver, driver); | 1420 | struct hid_driver, driver); |
1421 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1421 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1422 | const struct hid_device_id *id; | 1422 | const struct hid_device_id *id; |
1423 | int ret = 0; | 1423 | int ret = 0; |
1424 | 1424 | ||
1425 | if (!hdev->driver) { | 1425 | if (!hdev->driver) { |
1426 | id = hid_match_device(hdev, hdrv); | 1426 | id = hid_match_device(hdev, hdrv); |
1427 | if (id == NULL) | 1427 | if (id == NULL) |
1428 | return -ENODEV; | 1428 | return -ENODEV; |
1429 | 1429 | ||
1430 | hdev->driver = hdrv; | 1430 | hdev->driver = hdrv; |
1431 | if (hdrv->probe) { | 1431 | if (hdrv->probe) { |
1432 | ret = hdrv->probe(hdev, id); | 1432 | ret = hdrv->probe(hdev, id); |
1433 | } else { /* default probe */ | 1433 | } else { /* default probe */ |
1434 | ret = hid_parse(hdev); | 1434 | ret = hid_parse(hdev); |
1435 | if (!ret) | 1435 | if (!ret) |
1436 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 1436 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
1437 | } | 1437 | } |
1438 | if (ret) | 1438 | if (ret) |
1439 | hdev->driver = NULL; | 1439 | hdev->driver = NULL; |
1440 | } | 1440 | } |
1441 | return ret; | 1441 | return ret; |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | static int hid_device_remove(struct device *dev) | 1444 | static int hid_device_remove(struct device *dev) |
1445 | { | 1445 | { |
1446 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1446 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1447 | struct hid_driver *hdrv = hdev->driver; | 1447 | struct hid_driver *hdrv = hdev->driver; |
1448 | 1448 | ||
1449 | if (hdrv) { | 1449 | if (hdrv) { |
1450 | if (hdrv->remove) | 1450 | if (hdrv->remove) |
1451 | hdrv->remove(hdev); | 1451 | hdrv->remove(hdev); |
1452 | else /* default remove */ | 1452 | else /* default remove */ |
1453 | hid_hw_stop(hdev); | 1453 | hid_hw_stop(hdev); |
1454 | hdev->driver = NULL; | 1454 | hdev->driver = NULL; |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | return 0; | 1457 | return 0; |
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | 1460 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) |
1461 | { | 1461 | { |
1462 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1462 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1463 | 1463 | ||
1464 | if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", | 1464 | if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", |
1465 | hdev->bus, hdev->vendor, hdev->product)) | 1465 | hdev->bus, hdev->vendor, hdev->product)) |
1466 | return -ENOMEM; | 1466 | return -ENOMEM; |
1467 | 1467 | ||
1468 | if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) | 1468 | if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) |
1469 | return -ENOMEM; | 1469 | return -ENOMEM; |
1470 | 1470 | ||
1471 | if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) | 1471 | if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) |
1472 | return -ENOMEM; | 1472 | return -ENOMEM; |
1473 | 1473 | ||
1474 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) | 1474 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) |
1475 | return -ENOMEM; | 1475 | return -ENOMEM; |
1476 | 1476 | ||
1477 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", | 1477 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", |
1478 | hdev->bus, hdev->vendor, hdev->product)) | 1478 | hdev->bus, hdev->vendor, hdev->product)) |
1479 | return -ENOMEM; | 1479 | return -ENOMEM; |
1480 | 1480 | ||
1481 | return 0; | 1481 | return 0; |
1482 | } | 1482 | } |
1483 | 1483 | ||
1484 | static struct bus_type hid_bus_type = { | 1484 | static struct bus_type hid_bus_type = { |
1485 | .name = "hid", | 1485 | .name = "hid", |
1486 | .match = hid_bus_match, | 1486 | .match = hid_bus_match, |
1487 | .probe = hid_device_probe, | 1487 | .probe = hid_device_probe, |
1488 | .remove = hid_device_remove, | 1488 | .remove = hid_device_remove, |
1489 | .uevent = hid_uevent, | 1489 | .uevent = hid_uevent, |
1490 | }; | 1490 | }; |
1491 | 1491 | ||
1492 | /* a list of devices that shouldn't be handled by HID core at all */ | 1492 | /* a list of devices that shouldn't be handled by HID core at all */ |
1493 | static const struct hid_device_id hid_ignore_list[] = { | 1493 | static const struct hid_device_id hid_ignore_list[] = { |
1494 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, | 1494 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, |
1495 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, | 1495 | { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, |
1496 | { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, | 1496 | { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, |
1497 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, | 1497 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, |
1498 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, | 1498 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, |
1499 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, | 1499 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, |
1500 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, | 1500 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, |
1501 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, | 1501 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, |
1502 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, | 1502 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, |
1503 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, | 1503 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, |
1504 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, | 1504 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, |
1505 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1505 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
1506 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, | 1506 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, |
1507 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, | 1507 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, |
1508 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | 1508 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, |
1509 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, | 1509 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, |
1510 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, | 1510 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, |
1511 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, | 1511 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, |
1512 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, | 1512 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, |
1513 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, | 1513 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, |
1514 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, | 1514 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, |
1515 | { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, | 1515 | { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, |
1516 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, | 1516 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, |
1517 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, | 1517 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, |
1518 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1518 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
1519 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | 1519 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, |
1520 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1520 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
1521 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | 1521 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, |
1522 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, | 1522 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, |
1523 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, | 1523 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, |
1524 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, | 1524 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, |
1525 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, | 1525 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, |
1526 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, | 1526 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, |
1527 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, | 1527 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, |
1528 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, | 1528 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, |
1529 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, | 1529 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, |
1530 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, | 1530 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, |
1531 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, | 1531 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, |
1532 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, | 1532 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, |
1533 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, | 1533 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, |
1534 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, | 1534 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, |
1535 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, | 1535 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, |
1536 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, | 1536 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, |
1537 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, | 1537 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, |
1538 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, | 1538 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, |
1539 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, | 1539 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, |
1540 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, | 1540 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, |
1541 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, | 1541 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, |
1542 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, | 1542 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, |
1543 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, | 1543 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, |
1544 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, | 1544 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, |
1545 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, | 1545 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, |
1546 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, | 1546 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, |
1547 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, | 1547 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, |
1548 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, | 1548 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, |
1549 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, | 1549 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, |
1550 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, | 1550 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, |
1551 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, | 1551 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, |
1552 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, | 1552 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, |
1553 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, | 1553 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, |
1554 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, | 1554 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, |
1555 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, | 1555 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, |
1556 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, | 1556 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, |
1557 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, | 1557 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, |
1558 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, | 1558 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, |
1559 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, | 1559 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, |
1560 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, | 1560 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, |
1561 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, | 1561 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, |
1562 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, | 1562 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, | 1563 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, |
1564 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, | 1564 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, |
1565 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, | 1565 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, |
1566 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, | 1566 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, |
1567 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, | 1567 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, |
1568 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, | 1568 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, |
1569 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, | 1569 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, |
1570 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, | 1570 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, |
1571 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, | 1571 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, |
1572 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, | 1572 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, |
1573 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, | 1573 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, |
1574 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, | 1574 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, |
1575 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, | 1575 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, |
1576 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, | 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, |
1577 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, | 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, |
1578 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, | 1578 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, |
1579 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, | 1579 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, |
1580 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, | 1580 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, |
1581 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, | 1581 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, |
1582 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 1582 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
1583 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 1583 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
1584 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 1584 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
1585 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | 1585 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, |
1586 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 1586 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
1587 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, | 1587 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
1588 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, | 1588 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, |
1589 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, | 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, |
1590 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, | 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, |
1591 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, | 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, |
1592 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, | 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, |
1593 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, | 1593 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, |
1594 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, | 1594 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, |
1595 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, | 1595 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, |
1596 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, | 1596 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, |
1597 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, | 1597 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, |
1598 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, | 1598 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, |
1599 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, | 1599 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, |
1600 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, | 1600 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, |
1601 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, | 1601 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, |
1602 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, | 1602 | { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, |
1603 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, | 1603 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, |
1604 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, | 1604 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, |
1605 | { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, | 1605 | { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, |
1606 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, | 1606 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, |
1607 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, | 1607 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, |
1608 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, | 1608 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, |
1609 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, | 1609 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, |
1610 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, | 1610 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, |
1611 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, | 1611 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, |
1612 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, | 1612 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, |
1613 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, | 1613 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, |
1614 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, | 1614 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, |
1615 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, | 1615 | { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, |
1616 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, | 1616 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, |
1617 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, | 1617 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, |
1618 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, | 1618 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, |
1619 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, | 1619 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, |
1620 | { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, | 1620 | { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, |
1621 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, | 1621 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, |
1622 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, | 1622 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, |
1623 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, | 1623 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, |
1624 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) }, | 1624 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) }, |
1625 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) }, | 1625 | { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) }, |
1626 | { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, | 1626 | { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, |
1627 | { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, | 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, |
1628 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, |
1629 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
1630 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 1630 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
1631 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | 1631 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, |
1632 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, | 1632 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, |
1633 | { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, | 1633 | { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, |
1634 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, | 1634 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, |
1635 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, | 1635 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, |
1636 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, | 1636 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, |
1637 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, | 1637 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, |
1638 | { } | 1638 | { } |
1639 | }; | 1639 | }; |
1640 | 1640 | ||
1641 | /** | 1641 | /** |
1642 | * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer | 1642 | * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer |
1643 | * | 1643 | * |
1644 | * There are composite devices for which we want to ignore only a certain | 1644 | * There are composite devices for which we want to ignore only a certain |
1645 | * interface. This is a list of devices for which only the mouse interface will | 1645 | * interface. This is a list of devices for which only the mouse interface will |
1646 | * be ignored. This allows a dedicated driver to take care of the interface. | 1646 | * be ignored. This allows a dedicated driver to take care of the interface. |
1647 | */ | 1647 | */ |
1648 | static const struct hid_device_id hid_mouse_ignore_list[] = { | 1648 | static const struct hid_device_id hid_mouse_ignore_list[] = { |
1649 | /* appletouch driver */ | 1649 | /* appletouch driver */ |
1650 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1650 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
1651 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, | 1651 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, |
1652 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, | 1652 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, |
1653 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, | 1653 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, |
1654 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, | 1654 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, |
1655 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, | 1655 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, |
1656 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, | 1656 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, |
1657 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, | 1657 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, |
1658 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, | 1658 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, |
1659 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, | 1659 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, |
1660 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, | 1660 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, |
1661 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1661 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
1662 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1662 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
1663 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1663 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
1664 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, | 1664 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, |
1665 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, | 1665 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, |
1666 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, | 1666 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, |
1667 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1667 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
1668 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1668 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
1669 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1669 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
1670 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | 1670 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, |
1671 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | 1671 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, |
1672 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | 1672 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, |
1673 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1673 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1674 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1674 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1675 | { } | 1675 | { } |
1676 | }; | 1676 | }; |
1677 | 1677 | ||
1678 | static bool hid_ignore(struct hid_device *hdev) | 1678 | static bool hid_ignore(struct hid_device *hdev) |
1679 | { | 1679 | { |
1680 | switch (hdev->vendor) { | 1680 | switch (hdev->vendor) { |
1681 | case USB_VENDOR_ID_CODEMERCS: | 1681 | case USB_VENDOR_ID_CODEMERCS: |
1682 | /* ignore all Code Mercenaries IOWarrior devices */ | 1682 | /* ignore all Code Mercenaries IOWarrior devices */ |
1683 | if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && | 1683 | if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && |
1684 | hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) | 1684 | hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) |
1685 | return true; | 1685 | return true; |
1686 | break; | 1686 | break; |
1687 | case USB_VENDOR_ID_LOGITECH: | 1687 | case USB_VENDOR_ID_LOGITECH: |
1688 | if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && | 1688 | if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && |
1689 | hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) | 1689 | hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) |
1690 | return true; | 1690 | return true; |
1691 | break; | 1691 | break; |
1692 | } | 1692 | } |
1693 | 1693 | ||
1694 | if (hdev->type == HID_TYPE_USBMOUSE && | 1694 | if (hdev->type == HID_TYPE_USBMOUSE && |
1695 | hid_match_id(hdev, hid_mouse_ignore_list)) | 1695 | hid_match_id(hdev, hid_mouse_ignore_list)) |
1696 | return true; | 1696 | return true; |
1697 | 1697 | ||
1698 | return !!hid_match_id(hdev, hid_ignore_list); | 1698 | return !!hid_match_id(hdev, hid_ignore_list); |
1699 | } | 1699 | } |
1700 | 1700 | ||
1701 | int hid_add_device(struct hid_device *hdev) | 1701 | int hid_add_device(struct hid_device *hdev) |
1702 | { | 1702 | { |
1703 | static atomic_t id = ATOMIC_INIT(0); | 1703 | static atomic_t id = ATOMIC_INIT(0); |
1704 | int ret; | 1704 | int ret; |
1705 | 1705 | ||
1706 | if (WARN_ON(hdev->status & HID_STAT_ADDED)) | 1706 | if (WARN_ON(hdev->status & HID_STAT_ADDED)) |
1707 | return -EBUSY; | 1707 | return -EBUSY; |
1708 | 1708 | ||
1709 | /* we need to kill them here, otherwise they will stay allocated to | 1709 | /* we need to kill them here, otherwise they will stay allocated to |
1710 | * wait for coming driver */ | 1710 | * wait for coming driver */ |
1711 | if (hid_ignore(hdev)) | 1711 | if (hid_ignore(hdev)) |
1712 | return -ENODEV; | 1712 | return -ENODEV; |
1713 | 1713 | ||
1714 | /* XXX hack, any other cleaner solution after the driver core | 1714 | /* XXX hack, any other cleaner solution after the driver core |
1715 | * is converted to allow more than 20 bytes as the device name? */ | 1715 | * is converted to allow more than 20 bytes as the device name? */ |
1716 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, | 1716 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, |
1717 | hdev->vendor, hdev->product, atomic_inc_return(&id)); | 1717 | hdev->vendor, hdev->product, atomic_inc_return(&id)); |
1718 | 1718 | ||
1719 | ret = device_add(&hdev->dev); | 1719 | ret = device_add(&hdev->dev); |
1720 | if (!ret) | 1720 | if (!ret) |
1721 | hdev->status |= HID_STAT_ADDED; | 1721 | hdev->status |= HID_STAT_ADDED; |
1722 | 1722 | ||
1723 | return ret; | 1723 | return ret; |
1724 | } | 1724 | } |
1725 | EXPORT_SYMBOL_GPL(hid_add_device); | 1725 | EXPORT_SYMBOL_GPL(hid_add_device); |
1726 | 1726 | ||
1727 | /** | 1727 | /** |
1728 | * hid_allocate_device - allocate new hid device descriptor | 1728 | * hid_allocate_device - allocate new hid device descriptor |
1729 | * | 1729 | * |
1730 | * Allocate and initialize hid device, so that hid_destroy_device might be | 1730 | * Allocate and initialize hid device, so that hid_destroy_device might be |
1731 | * used to free it. | 1731 | * used to free it. |
1732 | * | 1732 | * |
1733 | * New hid_device pointer is returned on success, otherwise ERR_PTR encoded | 1733 | * New hid_device pointer is returned on success, otherwise ERR_PTR encoded |
1734 | * error value. | 1734 | * error value. |
1735 | */ | 1735 | */ |
1736 | struct hid_device *hid_allocate_device(void) | 1736 | struct hid_device *hid_allocate_device(void) |
1737 | { | 1737 | { |
1738 | struct hid_device *hdev; | 1738 | struct hid_device *hdev; |
1739 | unsigned int i; | 1739 | unsigned int i; |
1740 | int ret = -ENOMEM; | 1740 | int ret = -ENOMEM; |
1741 | 1741 | ||
1742 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); | 1742 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); |
1743 | if (hdev == NULL) | 1743 | if (hdev == NULL) |
1744 | return ERR_PTR(ret); | 1744 | return ERR_PTR(ret); |
1745 | 1745 | ||
1746 | device_initialize(&hdev->dev); | 1746 | device_initialize(&hdev->dev); |
1747 | hdev->dev.release = hid_device_release; | 1747 | hdev->dev.release = hid_device_release; |
1748 | hdev->dev.bus = &hid_bus_type; | 1748 | hdev->dev.bus = &hid_bus_type; |
1749 | 1749 | ||
1750 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, | 1750 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, |
1751 | sizeof(struct hid_collection), GFP_KERNEL); | 1751 | sizeof(struct hid_collection), GFP_KERNEL); |
1752 | if (hdev->collection == NULL) | 1752 | if (hdev->collection == NULL) |
1753 | goto err; | 1753 | goto err; |
1754 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | 1754 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; |
1755 | 1755 | ||
1756 | for (i = 0; i < HID_REPORT_TYPES; i++) | 1756 | for (i = 0; i < HID_REPORT_TYPES; i++) |
1757 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); | 1757 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); |
1758 | 1758 | ||
1759 | return hdev; | 1759 | return hdev; |
1760 | err: | 1760 | err: |
1761 | put_device(&hdev->dev); | 1761 | put_device(&hdev->dev); |
1762 | return ERR_PTR(ret); | 1762 | return ERR_PTR(ret); |
1763 | } | 1763 | } |
1764 | EXPORT_SYMBOL_GPL(hid_allocate_device); | 1764 | EXPORT_SYMBOL_GPL(hid_allocate_device); |
1765 | 1765 | ||
1766 | static void hid_remove_device(struct hid_device *hdev) | 1766 | static void hid_remove_device(struct hid_device *hdev) |
1767 | { | 1767 | { |
1768 | if (hdev->status & HID_STAT_ADDED) { | 1768 | if (hdev->status & HID_STAT_ADDED) { |
1769 | device_del(&hdev->dev); | 1769 | device_del(&hdev->dev); |
1770 | hdev->status &= ~HID_STAT_ADDED; | 1770 | hdev->status &= ~HID_STAT_ADDED; |
1771 | } | 1771 | } |
1772 | } | 1772 | } |
1773 | 1773 | ||
1774 | /** | 1774 | /** |
1775 | * hid_destroy_device - free previously allocated device | 1775 | * hid_destroy_device - free previously allocated device |
1776 | * | 1776 | * |
1777 | * @hdev: hid device | 1777 | * @hdev: hid device |
1778 | * | 1778 | * |
1779 | * If you allocate hid_device through hid_allocate_device, you should ever | 1779 | * If you allocate hid_device through hid_allocate_device, you should ever |
1780 | * free by this function. | 1780 | * free by this function. |
1781 | */ | 1781 | */ |
1782 | void hid_destroy_device(struct hid_device *hdev) | 1782 | void hid_destroy_device(struct hid_device *hdev) |
1783 | { | 1783 | { |
1784 | hid_remove_device(hdev); | 1784 | hid_remove_device(hdev); |
1785 | put_device(&hdev->dev); | 1785 | put_device(&hdev->dev); |
1786 | } | 1786 | } |
1787 | EXPORT_SYMBOL_GPL(hid_destroy_device); | 1787 | EXPORT_SYMBOL_GPL(hid_destroy_device); |
1788 | 1788 | ||
1789 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, | 1789 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, |
1790 | const char *mod_name) | 1790 | const char *mod_name) |
1791 | { | 1791 | { |
1792 | int ret; | 1792 | int ret; |
1793 | 1793 | ||
1794 | hdrv->driver.name = hdrv->name; | 1794 | hdrv->driver.name = hdrv->name; |
1795 | hdrv->driver.bus = &hid_bus_type; | 1795 | hdrv->driver.bus = &hid_bus_type; |
1796 | hdrv->driver.owner = owner; | 1796 | hdrv->driver.owner = owner; |
1797 | hdrv->driver.mod_name = mod_name; | 1797 | hdrv->driver.mod_name = mod_name; |
1798 | 1798 | ||
1799 | INIT_LIST_HEAD(&hdrv->dyn_list); | 1799 | INIT_LIST_HEAD(&hdrv->dyn_list); |
1800 | spin_lock_init(&hdrv->dyn_lock); | 1800 | spin_lock_init(&hdrv->dyn_lock); |
1801 | 1801 | ||
1802 | ret = driver_register(&hdrv->driver); | 1802 | ret = driver_register(&hdrv->driver); |
1803 | if (ret) | 1803 | if (ret) |
1804 | return ret; | 1804 | return ret; |
1805 | 1805 | ||
1806 | ret = driver_create_file(&hdrv->driver, &driver_attr_new_id); | 1806 | ret = driver_create_file(&hdrv->driver, &driver_attr_new_id); |
1807 | if (ret) | 1807 | if (ret) |
1808 | driver_unregister(&hdrv->driver); | 1808 | driver_unregister(&hdrv->driver); |
1809 | 1809 | ||
1810 | return ret; | 1810 | return ret; |
1811 | } | 1811 | } |
1812 | EXPORT_SYMBOL_GPL(__hid_register_driver); | 1812 | EXPORT_SYMBOL_GPL(__hid_register_driver); |
1813 | 1813 | ||
1814 | void hid_unregister_driver(struct hid_driver *hdrv) | 1814 | void hid_unregister_driver(struct hid_driver *hdrv) |
1815 | { | 1815 | { |
1816 | driver_remove_file(&hdrv->driver, &driver_attr_new_id); | 1816 | driver_remove_file(&hdrv->driver, &driver_attr_new_id); |
1817 | driver_unregister(&hdrv->driver); | 1817 | driver_unregister(&hdrv->driver); |
1818 | hid_free_dynids(hdrv); | 1818 | hid_free_dynids(hdrv); |
1819 | } | 1819 | } |
1820 | EXPORT_SYMBOL_GPL(hid_unregister_driver); | 1820 | EXPORT_SYMBOL_GPL(hid_unregister_driver); |
1821 | 1821 | ||
1822 | #ifdef CONFIG_HID_COMPAT | ||
1823 | static void hid_compat_load(struct work_struct *ws) | ||
1824 | { | ||
1825 | request_module("hid-dummy"); | ||
1826 | } | ||
1827 | static DECLARE_WORK(hid_compat_work, hid_compat_load); | ||
1828 | static struct workqueue_struct *hid_compat_wq; | ||
1829 | #endif | ||
1830 | |||
1831 | static int __init hid_init(void) | 1822 | static int __init hid_init(void) |
1832 | { | 1823 | { |
1833 | int ret; | 1824 | int ret; |
1834 | 1825 | ||
1835 | ret = bus_register(&hid_bus_type); | 1826 | ret = bus_register(&hid_bus_type); |
1836 | if (ret) { | 1827 | if (ret) { |
1837 | printk(KERN_ERR "HID: can't register hid bus\n"); | 1828 | printk(KERN_ERR "HID: can't register hid bus\n"); |
1838 | goto err; | 1829 | goto err; |
1839 | } | 1830 | } |
1840 | 1831 | ||
1841 | ret = hidraw_init(); | 1832 | ret = hidraw_init(); |
1842 | if (ret) | 1833 | if (ret) |
1843 | goto err_bus; | 1834 | goto err_bus; |
1844 | 1835 | ||
1845 | #ifdef CONFIG_HID_COMPAT | ||
1846 | hid_compat_wq = create_singlethread_workqueue("hid_compat"); | ||
1847 | if (!hid_compat_wq) { | ||
1848 | hidraw_exit(); | ||
1849 | goto err; | ||
1850 | } | ||
1851 | queue_work(hid_compat_wq, &hid_compat_work); | ||
1852 | #endif | ||
1853 | |||
1854 | return 0; | 1836 | return 0; |
1855 | err_bus: | 1837 | err_bus: |
1856 | bus_unregister(&hid_bus_type); | 1838 | bus_unregister(&hid_bus_type); |
1857 | err: | 1839 | err: |
1858 | return ret; | 1840 | return ret; |
1859 | } | 1841 | } |
1860 | 1842 | ||
1861 | static void __exit hid_exit(void) | 1843 | static void __exit hid_exit(void) |
1862 | { | 1844 | { |
1863 | #ifdef CONFIG_HID_COMPAT | ||
1864 | destroy_workqueue(hid_compat_wq); | ||
1865 | #endif | ||
1866 | hidraw_exit(); | 1845 | hidraw_exit(); |
1867 | bus_unregister(&hid_bus_type); | 1846 | bus_unregister(&hid_bus_type); |
1868 | } | 1847 | } |
1869 | 1848 | ||
1870 | module_init(hid_init); | 1849 | module_init(hid_init); |
1871 | module_exit(hid_exit); | 1850 | module_exit(hid_exit); |
1872 | 1851 | ||
1873 | MODULE_LICENSE(DRIVER_LICENSE); | 1852 | MODULE_LICENSE(DRIVER_LICENSE); |
1874 | 1853 | ||
1875 | 1854 |
drivers/hid/hid-cypress.c
1 | /* | 1 | /* |
2 | * HID driver for some cypress "special" devices | 2 | * HID driver for some cypress "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define CP_RDESC_SWAPPED_MIN_MAX 0x01 | 26 | #define CP_RDESC_SWAPPED_MIN_MAX 0x01 |
27 | #define CP_2WHEEL_MOUSE_HACK 0x02 | 27 | #define CP_2WHEEL_MOUSE_HACK 0x02 |
28 | #define CP_2WHEEL_MOUSE_HACK_ON 0x04 | 28 | #define CP_2WHEEL_MOUSE_HACK_ON 0x04 |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * Some USB barcode readers from cypress have usage min and usage max in | 31 | * Some USB barcode readers from cypress have usage min and usage max in |
32 | * the wrong order | 32 | * the wrong order |
33 | */ | 33 | */ |
34 | static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 34 | static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
35 | unsigned int rsize) | 35 | unsigned int rsize) |
36 | { | 36 | { |
37 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 37 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
38 | unsigned int i; | 38 | unsigned int i; |
39 | 39 | ||
40 | if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) | 40 | if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) |
41 | return; | 41 | return; |
42 | 42 | ||
43 | for (i = 0; i < rsize - 4; i++) | 43 | for (i = 0; i < rsize - 4; i++) |
44 | if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) { | 44 | if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) { |
45 | __u8 tmp; | 45 | __u8 tmp; |
46 | 46 | ||
47 | rdesc[i] = 0x19; | 47 | rdesc[i] = 0x19; |
48 | rdesc[i + 2] = 0x29; | 48 | rdesc[i + 2] = 0x29; |
49 | tmp = rdesc[i + 3]; | 49 | tmp = rdesc[i + 3]; |
50 | rdesc[i + 3] = rdesc[i + 1]; | 50 | rdesc[i + 3] = rdesc[i + 1]; |
51 | rdesc[i + 1] = tmp; | 51 | rdesc[i + 1] = tmp; |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 55 | static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
56 | struct hid_field *field, struct hid_usage *usage, | 56 | struct hid_field *field, struct hid_usage *usage, |
57 | unsigned long **bit, int *max) | 57 | unsigned long **bit, int *max) |
58 | { | 58 | { |
59 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 59 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
60 | 60 | ||
61 | if (!(quirks & CP_2WHEEL_MOUSE_HACK)) | 61 | if (!(quirks & CP_2WHEEL_MOUSE_HACK)) |
62 | return 0; | 62 | return 0; |
63 | 63 | ||
64 | if (usage->type == EV_REL && usage->code == REL_WHEEL) | 64 | if (usage->type == EV_REL && usage->code == REL_WHEEL) |
65 | set_bit(REL_HWHEEL, *bit); | 65 | set_bit(REL_HWHEEL, *bit); |
66 | if (usage->hid == 0x00090005) | 66 | if (usage->hid == 0x00090005) |
67 | return -1; | 67 | return -1; |
68 | 68 | ||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int cp_event(struct hid_device *hdev, struct hid_field *field, | 72 | static int cp_event(struct hid_device *hdev, struct hid_field *field, |
73 | struct hid_usage *usage, __s32 value) | 73 | struct hid_usage *usage, __s32 value) |
74 | { | 74 | { |
75 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 75 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
76 | 76 | ||
77 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | 77 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
78 | !usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK)) | 78 | !usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK)) |
79 | return 0; | 79 | return 0; |
80 | 80 | ||
81 | if (usage->hid == 0x00090005) { | 81 | if (usage->hid == 0x00090005) { |
82 | if (value) | 82 | if (value) |
83 | quirks |= CP_2WHEEL_MOUSE_HACK_ON; | 83 | quirks |= CP_2WHEEL_MOUSE_HACK_ON; |
84 | else | 84 | else |
85 | quirks &= ~CP_2WHEEL_MOUSE_HACK_ON; | 85 | quirks &= ~CP_2WHEEL_MOUSE_HACK_ON; |
86 | hid_set_drvdata(hdev, (void *)quirks); | 86 | hid_set_drvdata(hdev, (void *)quirks); |
87 | return 1; | 87 | return 1; |
88 | } | 88 | } |
89 | 89 | ||
90 | if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) { | 90 | if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) { |
91 | struct input_dev *input = field->hidinput->input; | 91 | struct input_dev *input = field->hidinput->input; |
92 | 92 | ||
93 | input_event(input, usage->type, REL_HWHEEL, value); | 93 | input_event(input, usage->type, REL_HWHEEL, value); |
94 | return 1; | 94 | return 1; |
95 | } | 95 | } |
96 | 96 | ||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) | 100 | static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) |
101 | { | 101 | { |
102 | unsigned long quirks = id->driver_data; | 102 | unsigned long quirks = id->driver_data; |
103 | int ret; | 103 | int ret; |
104 | 104 | ||
105 | hid_set_drvdata(hdev, (void *)quirks); | 105 | hid_set_drvdata(hdev, (void *)quirks); |
106 | 106 | ||
107 | ret = hid_parse(hdev); | 107 | ret = hid_parse(hdev); |
108 | if (ret) { | 108 | if (ret) { |
109 | dev_err(&hdev->dev, "parse failed\n"); | 109 | dev_err(&hdev->dev, "parse failed\n"); |
110 | goto err_free; | 110 | goto err_free; |
111 | } | 111 | } |
112 | 112 | ||
113 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 113 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
114 | if (ret) { | 114 | if (ret) { |
115 | dev_err(&hdev->dev, "hw start failed\n"); | 115 | dev_err(&hdev->dev, "hw start failed\n"); |
116 | goto err_free; | 116 | goto err_free; |
117 | } | 117 | } |
118 | 118 | ||
119 | return 0; | 119 | return 0; |
120 | err_free: | 120 | err_free: |
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | 123 | ||
124 | static const struct hid_device_id cp_devices[] = { | 124 | static const struct hid_device_id cp_devices[] = { |
125 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1), | 125 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1), |
126 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, | 126 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, |
127 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2), | 127 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2), |
128 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, | 128 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, |
129 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), | 129 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), |
130 | .driver_data = CP_2WHEEL_MOUSE_HACK }, | 130 | .driver_data = CP_2WHEEL_MOUSE_HACK }, |
131 | { } | 131 | { } |
132 | }; | 132 | }; |
133 | MODULE_DEVICE_TABLE(hid, cp_devices); | 133 | MODULE_DEVICE_TABLE(hid, cp_devices); |
134 | 134 | ||
135 | static struct hid_driver cp_driver = { | 135 | static struct hid_driver cp_driver = { |
136 | .name = "cypress", | 136 | .name = "cypress", |
137 | .id_table = cp_devices, | 137 | .id_table = cp_devices, |
138 | .report_fixup = cp_report_fixup, | 138 | .report_fixup = cp_report_fixup, |
139 | .input_mapped = cp_input_mapped, | 139 | .input_mapped = cp_input_mapped, |
140 | .event = cp_event, | 140 | .event = cp_event, |
141 | .probe = cp_probe, | 141 | .probe = cp_probe, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static int cp_init(void) | 144 | static int cp_init(void) |
145 | { | 145 | { |
146 | return hid_register_driver(&cp_driver); | 146 | return hid_register_driver(&cp_driver); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void cp_exit(void) | 149 | static void cp_exit(void) |
150 | { | 150 | { |
151 | hid_unregister_driver(&cp_driver); | 151 | hid_unregister_driver(&cp_driver); |
152 | } | 152 | } |
153 | 153 | ||
154 | module_init(cp_init); | 154 | module_init(cp_init); |
155 | module_exit(cp_exit); | 155 | module_exit(cp_exit); |
156 | MODULE_LICENSE("GPL"); | 156 | MODULE_LICENSE("GPL"); |
157 | |||
158 | HID_COMPAT_LOAD_DRIVER(cypress); | ||
159 | 157 |
drivers/hid/hid-drff.c
1 | /* | 1 | /* |
2 | * Force feedback support for DragonRise Inc. game controllers | 2 | * Force feedback support for DragonRise Inc. game controllers |
3 | * | 3 | * |
4 | * From what I have gathered, these devices are mass produced in China and are | 4 | * From what I have gathered, these devices are mass produced in China and are |
5 | * distributed under several vendors. They often share the same design as | 5 | * distributed under several vendors. They often share the same design as |
6 | * the original PlayStation DualShock controller. | 6 | * the original PlayStation DualShock controller. |
7 | * | 7 | * |
8 | * 0079:0006 "DragonRise Inc. Generic USB Joystick " | 8 | * 0079:0006 "DragonRise Inc. Generic USB Joystick " |
9 | * - tested with a Tesun USB-703 game controller. | 9 | * - tested with a Tesun USB-703 game controller. |
10 | * | 10 | * |
11 | * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com> | 11 | * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
17 | * the Free Software Foundation; either version 2 of the License, or | 17 | * the Free Software Foundation; either version 2 of the License, or |
18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
19 | * | 19 | * |
20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
24 | * | 24 | * |
25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
26 | * along with this program; if not, write to the Free Software | 26 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | 33 | ||
34 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
35 | #include "usbhid/usbhid.h" | 35 | #include "usbhid/usbhid.h" |
36 | 36 | ||
37 | struct drff_device { | 37 | struct drff_device { |
38 | struct hid_report *report; | 38 | struct hid_report *report; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static int drff_play(struct input_dev *dev, void *data, | 41 | static int drff_play(struct input_dev *dev, void *data, |
42 | struct ff_effect *effect) | 42 | struct ff_effect *effect) |
43 | { | 43 | { |
44 | struct hid_device *hid = input_get_drvdata(dev); | 44 | struct hid_device *hid = input_get_drvdata(dev); |
45 | struct drff_device *drff = data; | 45 | struct drff_device *drff = data; |
46 | int strong, weak; | 46 | int strong, weak; |
47 | 47 | ||
48 | strong = effect->u.rumble.strong_magnitude; | 48 | strong = effect->u.rumble.strong_magnitude; |
49 | weak = effect->u.rumble.weak_magnitude; | 49 | weak = effect->u.rumble.weak_magnitude; |
50 | 50 | ||
51 | dbg_hid("called with 0x%04x 0x%04x", strong, weak); | 51 | dbg_hid("called with 0x%04x 0x%04x", strong, weak); |
52 | 52 | ||
53 | if (strong || weak) { | 53 | if (strong || weak) { |
54 | strong = strong * 0xff / 0xffff; | 54 | strong = strong * 0xff / 0xffff; |
55 | weak = weak * 0xff / 0xffff; | 55 | weak = weak * 0xff / 0xffff; |
56 | 56 | ||
57 | /* While reverse engineering this device, I found that when | 57 | /* While reverse engineering this device, I found that when |
58 | this value is set, it causes the strong rumble to function | 58 | this value is set, it causes the strong rumble to function |
59 | at a near maximum speed, so we'll bypass it. */ | 59 | at a near maximum speed, so we'll bypass it. */ |
60 | if (weak == 0x0a) | 60 | if (weak == 0x0a) |
61 | weak = 0x0b; | 61 | weak = 0x0b; |
62 | 62 | ||
63 | drff->report->field[0]->value[0] = 0x51; | 63 | drff->report->field[0]->value[0] = 0x51; |
64 | drff->report->field[0]->value[1] = 0x00; | 64 | drff->report->field[0]->value[1] = 0x00; |
65 | drff->report->field[0]->value[2] = weak; | 65 | drff->report->field[0]->value[2] = weak; |
66 | drff->report->field[0]->value[4] = strong; | 66 | drff->report->field[0]->value[4] = strong; |
67 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 67 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); |
68 | 68 | ||
69 | drff->report->field[0]->value[0] = 0xfa; | 69 | drff->report->field[0]->value[0] = 0xfa; |
70 | drff->report->field[0]->value[1] = 0xfe; | 70 | drff->report->field[0]->value[1] = 0xfe; |
71 | } else { | 71 | } else { |
72 | drff->report->field[0]->value[0] = 0xf3; | 72 | drff->report->field[0]->value[0] = 0xf3; |
73 | drff->report->field[0]->value[1] = 0x00; | 73 | drff->report->field[0]->value[1] = 0x00; |
74 | } | 74 | } |
75 | 75 | ||
76 | drff->report->field[0]->value[2] = 0x00; | 76 | drff->report->field[0]->value[2] = 0x00; |
77 | drff->report->field[0]->value[4] = 0x00; | 77 | drff->report->field[0]->value[4] = 0x00; |
78 | dbg_hid("running with 0x%02x 0x%02x", strong, weak); | 78 | dbg_hid("running with 0x%02x 0x%02x", strong, weak); |
79 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 79 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); |
80 | 80 | ||
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | 83 | ||
84 | static int drff_init(struct hid_device *hid) | 84 | static int drff_init(struct hid_device *hid) |
85 | { | 85 | { |
86 | struct drff_device *drff; | 86 | struct drff_device *drff; |
87 | struct hid_report *report; | 87 | struct hid_report *report; |
88 | struct hid_input *hidinput = list_first_entry(&hid->inputs, | 88 | struct hid_input *hidinput = list_first_entry(&hid->inputs, |
89 | struct hid_input, list); | 89 | struct hid_input, list); |
90 | struct list_head *report_list = | 90 | struct list_head *report_list = |
91 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 91 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
92 | struct input_dev *dev = hidinput->input; | 92 | struct input_dev *dev = hidinput->input; |
93 | int error; | 93 | int error; |
94 | 94 | ||
95 | if (list_empty(report_list)) { | 95 | if (list_empty(report_list)) { |
96 | dev_err(&hid->dev, "no output reports found\n"); | 96 | dev_err(&hid->dev, "no output reports found\n"); |
97 | return -ENODEV; | 97 | return -ENODEV; |
98 | } | 98 | } |
99 | 99 | ||
100 | report = list_first_entry(report_list, struct hid_report, list); | 100 | report = list_first_entry(report_list, struct hid_report, list); |
101 | if (report->maxfield < 1) { | 101 | if (report->maxfield < 1) { |
102 | dev_err(&hid->dev, "no fields in the report\n"); | 102 | dev_err(&hid->dev, "no fields in the report\n"); |
103 | return -ENODEV; | 103 | return -ENODEV; |
104 | } | 104 | } |
105 | 105 | ||
106 | if (report->field[0]->report_count < 7) { | 106 | if (report->field[0]->report_count < 7) { |
107 | dev_err(&hid->dev, "not enough values in the field\n"); | 107 | dev_err(&hid->dev, "not enough values in the field\n"); |
108 | return -ENODEV; | 108 | return -ENODEV; |
109 | } | 109 | } |
110 | 110 | ||
111 | drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL); | 111 | drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL); |
112 | if (!drff) | 112 | if (!drff) |
113 | return -ENOMEM; | 113 | return -ENOMEM; |
114 | 114 | ||
115 | set_bit(FF_RUMBLE, dev->ffbit); | 115 | set_bit(FF_RUMBLE, dev->ffbit); |
116 | 116 | ||
117 | error = input_ff_create_memless(dev, drff, drff_play); | 117 | error = input_ff_create_memless(dev, drff, drff_play); |
118 | if (error) { | 118 | if (error) { |
119 | kfree(drff); | 119 | kfree(drff); |
120 | return error; | 120 | return error; |
121 | } | 121 | } |
122 | 122 | ||
123 | drff->report = report; | 123 | drff->report = report; |
124 | drff->report->field[0]->value[0] = 0xf3; | 124 | drff->report->field[0]->value[0] = 0xf3; |
125 | drff->report->field[0]->value[1] = 0x00; | 125 | drff->report->field[0]->value[1] = 0x00; |
126 | drff->report->field[0]->value[2] = 0x00; | 126 | drff->report->field[0]->value[2] = 0x00; |
127 | drff->report->field[0]->value[3] = 0x00; | 127 | drff->report->field[0]->value[3] = 0x00; |
128 | drff->report->field[0]->value[4] = 0x00; | 128 | drff->report->field[0]->value[4] = 0x00; |
129 | drff->report->field[0]->value[5] = 0x00; | 129 | drff->report->field[0]->value[5] = 0x00; |
130 | drff->report->field[0]->value[6] = 0x00; | 130 | drff->report->field[0]->value[6] = 0x00; |
131 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 131 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); |
132 | 132 | ||
133 | dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game " | 133 | dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game " |
134 | "controllers by Richard Walmsley <richwalm@gmail.com>\n"); | 134 | "controllers by Richard Walmsley <richwalm@gmail.com>\n"); |
135 | 135 | ||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) | 139 | static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) |
140 | { | 140 | { |
141 | int ret; | 141 | int ret; |
142 | 142 | ||
143 | dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe..."); | 143 | dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe..."); |
144 | 144 | ||
145 | ret = hid_parse(hdev); | 145 | ret = hid_parse(hdev); |
146 | if (ret) { | 146 | if (ret) { |
147 | dev_err(&hdev->dev, "parse failed\n"); | 147 | dev_err(&hdev->dev, "parse failed\n"); |
148 | goto err; | 148 | goto err; |
149 | } | 149 | } |
150 | 150 | ||
151 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 151 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
152 | if (ret) { | 152 | if (ret) { |
153 | dev_err(&hdev->dev, "hw start failed\n"); | 153 | dev_err(&hdev->dev, "hw start failed\n"); |
154 | goto err; | 154 | goto err; |
155 | } | 155 | } |
156 | 156 | ||
157 | drff_init(hdev); | 157 | drff_init(hdev); |
158 | 158 | ||
159 | return 0; | 159 | return 0; |
160 | err: | 160 | err: |
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
163 | 163 | ||
164 | static const struct hid_device_id dr_devices[] = { | 164 | static const struct hid_device_id dr_devices[] = { |
165 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), }, | 165 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), }, |
166 | { } | 166 | { } |
167 | }; | 167 | }; |
168 | MODULE_DEVICE_TABLE(hid, dr_devices); | 168 | MODULE_DEVICE_TABLE(hid, dr_devices); |
169 | 169 | ||
170 | static struct hid_driver dr_driver = { | 170 | static struct hid_driver dr_driver = { |
171 | .name = "dragonrise", | 171 | .name = "dragonrise", |
172 | .id_table = dr_devices, | 172 | .id_table = dr_devices, |
173 | .probe = dr_probe, | 173 | .probe = dr_probe, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static int __init dr_init(void) | 176 | static int __init dr_init(void) |
177 | { | 177 | { |
178 | return hid_register_driver(&dr_driver); | 178 | return hid_register_driver(&dr_driver); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void __exit dr_exit(void) | 181 | static void __exit dr_exit(void) |
182 | { | 182 | { |
183 | hid_unregister_driver(&dr_driver); | 183 | hid_unregister_driver(&dr_driver); |
184 | } | 184 | } |
185 | 185 | ||
186 | module_init(dr_init); | 186 | module_init(dr_init); |
187 | module_exit(dr_exit); | 187 | module_exit(dr_exit); |
188 | MODULE_LICENSE("GPL"); | 188 | MODULE_LICENSE("GPL"); |
189 | |||
190 | HID_COMPAT_LOAD_DRIVER(dragonrise); | ||
191 | 189 |
drivers/hid/hid-dummy.c
1 | #include <linux/autoconf.h> | File was deleted | |
2 | #include <linux/module.h> | ||
3 | #include <linux/hid.h> | ||
4 | |||
5 | static int __init hid_dummy_init(void) | ||
6 | { | ||
7 | #ifdef CONFIG_HID_A4TECH_MODULE | ||
8 | HID_COMPAT_CALL_DRIVER(a4tech); | ||
9 | #endif | ||
10 | #ifdef CONFIG_HID_APPLE_MODULE | ||
11 | HID_COMPAT_CALL_DRIVER(apple); | ||
12 | #endif | ||
13 | #ifdef CONFIG_HID_BELKIN_MODULE | ||
14 | HID_COMPAT_CALL_DRIVER(belkin); | ||
15 | #endif | ||
16 | #ifdef CONFIG_HID_BRIGHT_MODULE | ||
17 | HID_COMPAT_CALL_DRIVER(bright); | ||
18 | #endif | ||
19 | #ifdef CONFIG_HID_CHERRY_MODULE | ||
20 | HID_COMPAT_CALL_DRIVER(cherry); | ||
21 | #endif | ||
22 | #ifdef CONFIG_HID_CHICONY_MODULE | ||
23 | HID_COMPAT_CALL_DRIVER(chicony); | ||
24 | #endif | ||
25 | #ifdef CONFIG_HID_CYPRESS_MODULE | ||
26 | HID_COMPAT_CALL_DRIVER(cypress); | ||
27 | #endif | ||
28 | #ifdef CONFIG_HID_DELL_MODULE | ||
29 | HID_COMPAT_CALL_DRIVER(dell); | ||
30 | #endif | ||
31 | #ifdef CONFIG_DRAGONRISE_FF_MODULE | ||
32 | HID_COMPAT_CALL_DRIVER(dragonrise); | ||
33 | #endif | ||
34 | #ifdef CONFIG_HID_EZKEY_MODULE | ||
35 | HID_COMPAT_CALL_DRIVER(ezkey); | ||
36 | #endif | ||
37 | #ifdef CONFIG_HID_KYE_MODULE | ||
38 | HID_COMPAT_CALL_DRIVER(kye); | ||
39 | #endif | ||
40 | #ifdef CONFIG_HID_GYRATION_MODULE | ||
41 | HID_COMPAT_CALL_DRIVER(gyration); | ||
42 | #endif | ||
43 | #ifdef CONFIG_HID_KENSINGTON_MODULE | ||
44 | HID_COMPAT_CALL_DRIVER(kensington); | ||
45 | #endif | ||
46 | #ifdef CONFIG_HID_LOGITECH_MODULE | ||
47 | HID_COMPAT_CALL_DRIVER(logitech); | ||
48 | #endif | ||
49 | #ifdef CONFIG_HID_MICROSOFT_MODULE | ||
50 | HID_COMPAT_CALL_DRIVER(microsoft); | ||
51 | #endif | ||
52 | #ifdef CONFIG_HID_MONTEREY_MODULE | ||
53 | HID_COMPAT_CALL_DRIVER(monterey); | ||
54 | #endif | ||
55 | #ifdef CONFIG_HID_NTRIG_MODULE | ||
56 | HID_COMPAT_CALL_DRIVER(ntrig); | ||
57 | #endif | ||
58 | #ifdef CONFIG_HID_PANTHERLORD_MODULE | ||
59 | HID_COMPAT_CALL_DRIVER(pantherlord); | ||
60 | #endif | ||
61 | #ifdef CONFIG_HID_PETALYNX_MODULE | ||
62 | HID_COMPAT_CALL_DRIVER(petalynx); | ||
63 | #endif | ||
64 | #ifdef CONFIG_HID_SAMSUNG_MODULE | ||
65 | HID_COMPAT_CALL_DRIVER(samsung); | ||
66 | #endif | ||
67 | #ifdef CONFIG_HID_SONY_MODULE | ||
68 | HID_COMPAT_CALL_DRIVER(sony); | ||
69 | #endif | ||
70 | #ifdef CONFIG_HID_SUNPLUS_MODULE | ||
71 | HID_COMPAT_CALL_DRIVER(sunplus); | ||
72 | #endif | ||
73 | #ifdef CONFIG_GREENASIA_FF_MODULE | ||
74 | HID_COMPAT_CALL_DRIVER(greenasia); | ||
75 | #endif | ||
76 | #ifdef CONFIG_THRUSTMASTER_FF_MODULE | ||
77 | HID_COMPAT_CALL_DRIVER(thrustmaster); | ||
78 | #endif | ||
79 | #ifdef CONFIG_ZEROPLUS_FF_MODULE | ||
80 | HID_COMPAT_CALL_DRIVER(zeroplus); | ||
81 | #endif | ||
82 | |||
83 | return -EIO; | ||
84 | } | ||
85 | module_init(hid_dummy_init); | ||
86 | |||
87 | MODULE_LICENSE("GPL"); | ||
88 | 1 | #include <linux/autoconf.h> |
drivers/hid/hid-ezkey.c
1 | /* | 1 | /* |
2 | * HID driver for some ezkey "special" devices | 2 | * HID driver for some ezkey "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define ez_map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c)) | 26 | #define ez_map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c)) |
27 | #define ez_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) | 27 | #define ez_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) |
28 | 28 | ||
29 | static int ez_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 29 | static int ez_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
30 | struct hid_field *field, struct hid_usage *usage, | 30 | struct hid_field *field, struct hid_usage *usage, |
31 | unsigned long **bit, int *max) | 31 | unsigned long **bit, int *max) |
32 | { | 32 | { |
33 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 33 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
34 | return 0; | 34 | return 0; |
35 | 35 | ||
36 | switch (usage->hid & HID_USAGE) { | 36 | switch (usage->hid & HID_USAGE) { |
37 | case 0x230: ez_map_key(BTN_MOUSE); break; | 37 | case 0x230: ez_map_key(BTN_MOUSE); break; |
38 | case 0x231: ez_map_rel(REL_WHEEL); break; | 38 | case 0x231: ez_map_rel(REL_WHEEL); break; |
39 | /* | 39 | /* |
40 | * this keyboard has a scrollwheel implemented in | 40 | * this keyboard has a scrollwheel implemented in |
41 | * totally broken way. We map this usage temporarily | 41 | * totally broken way. We map this usage temporarily |
42 | * to HWHEEL and handle it in the event quirk handler | 42 | * to HWHEEL and handle it in the event quirk handler |
43 | */ | 43 | */ |
44 | case 0x232: ez_map_rel(REL_HWHEEL); break; | 44 | case 0x232: ez_map_rel(REL_HWHEEL); break; |
45 | default: | 45 | default: |
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int ez_event(struct hid_device *hdev, struct hid_field *field, | 51 | static int ez_event(struct hid_device *hdev, struct hid_field *field, |
52 | struct hid_usage *usage, __s32 value) | 52 | struct hid_usage *usage, __s32 value) |
53 | { | 53 | { |
54 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | 54 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
55 | !usage->type) | 55 | !usage->type) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | /* handle the temporary quirky mapping to HWHEEL */ | 58 | /* handle the temporary quirky mapping to HWHEEL */ |
59 | if (usage->type == EV_REL && usage->code == REL_HWHEEL) { | 59 | if (usage->type == EV_REL && usage->code == REL_HWHEEL) { |
60 | struct input_dev *input = field->hidinput->input; | 60 | struct input_dev *input = field->hidinput->input; |
61 | input_event(input, usage->type, REL_WHEEL, -value); | 61 | input_event(input, usage->type, REL_WHEEL, -value); |
62 | return 1; | 62 | return 1; |
63 | } | 63 | } |
64 | 64 | ||
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | 67 | ||
68 | static const struct hid_device_id ez_devices[] = { | 68 | static const struct hid_device_id ez_devices[] = { |
69 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 69 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
70 | { } | 70 | { } |
71 | }; | 71 | }; |
72 | MODULE_DEVICE_TABLE(hid, ez_devices); | 72 | MODULE_DEVICE_TABLE(hid, ez_devices); |
73 | 73 | ||
74 | static struct hid_driver ez_driver = { | 74 | static struct hid_driver ez_driver = { |
75 | .name = "ezkey", | 75 | .name = "ezkey", |
76 | .id_table = ez_devices, | 76 | .id_table = ez_devices, |
77 | .input_mapping = ez_input_mapping, | 77 | .input_mapping = ez_input_mapping, |
78 | .event = ez_event, | 78 | .event = ez_event, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static int ez_init(void) | 81 | static int ez_init(void) |
82 | { | 82 | { |
83 | return hid_register_driver(&ez_driver); | 83 | return hid_register_driver(&ez_driver); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void ez_exit(void) | 86 | static void ez_exit(void) |
87 | { | 87 | { |
88 | hid_unregister_driver(&ez_driver); | 88 | hid_unregister_driver(&ez_driver); |
89 | } | 89 | } |
90 | 90 | ||
91 | module_init(ez_init); | 91 | module_init(ez_init); |
92 | module_exit(ez_exit); | 92 | module_exit(ez_exit); |
93 | MODULE_LICENSE("GPL"); | 93 | MODULE_LICENSE("GPL"); |
94 | |||
95 | HID_COMPAT_LOAD_DRIVER(ezkey); | ||
96 | 94 |
drivers/hid/hid-gaff.c
1 | /* | 1 | /* |
2 | * Force feedback support for GreenAsia (Product ID 0x12) based devices | 2 | * Force feedback support for GreenAsia (Product ID 0x12) based devices |
3 | * | 3 | * |
4 | * The devices are distributed under various names and the same USB device ID | 4 | * The devices are distributed under various names and the same USB device ID |
5 | * can be used in many game controllers. | 5 | * can be used in many game controllers. |
6 | * | 6 | * |
7 | * | 7 | * |
8 | * 0e8f:0012 "GreenAsia Inc. USB Joystick " | 8 | * 0e8f:0012 "GreenAsia Inc. USB Joystick " |
9 | * - tested with MANTA Warior MM816 and SpeedLink Strike2 SL-6635. | 9 | * - tested with MANTA Warior MM816 and SpeedLink Strike2 SL-6635. |
10 | * | 10 | * |
11 | * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info> | 11 | * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
17 | * the Free Software Foundation; either version 2 of the License, or | 17 | * the Free Software Foundation; either version 2 of the License, or |
18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
19 | * | 19 | * |
20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
24 | * | 24 | * |
25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
26 | * along with this program; if not, write to the Free Software | 26 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | #include "hid-ids.h" | 33 | #include "hid-ids.h" |
34 | #include "usbhid/usbhid.h" | 34 | #include "usbhid/usbhid.h" |
35 | 35 | ||
36 | struct gaff_device { | 36 | struct gaff_device { |
37 | struct hid_report *report; | 37 | struct hid_report *report; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static int hid_gaff_play(struct input_dev *dev, void *data, | 40 | static int hid_gaff_play(struct input_dev *dev, void *data, |
41 | struct ff_effect *effect) | 41 | struct ff_effect *effect) |
42 | { | 42 | { |
43 | struct hid_device *hid = input_get_drvdata(dev); | 43 | struct hid_device *hid = input_get_drvdata(dev); |
44 | struct gaff_device *gaff = data; | 44 | struct gaff_device *gaff = data; |
45 | int left, right; | 45 | int left, right; |
46 | 46 | ||
47 | left = effect->u.rumble.strong_magnitude; | 47 | left = effect->u.rumble.strong_magnitude; |
48 | right = effect->u.rumble.weak_magnitude; | 48 | right = effect->u.rumble.weak_magnitude; |
49 | 49 | ||
50 | dbg_hid("called with 0x%04x 0x%04x", left, right); | 50 | dbg_hid("called with 0x%04x 0x%04x", left, right); |
51 | 51 | ||
52 | left = left * 0xfe / 0xffff; | 52 | left = left * 0xfe / 0xffff; |
53 | right = right * 0xfe / 0xffff; | 53 | right = right * 0xfe / 0xffff; |
54 | 54 | ||
55 | gaff->report->field[0]->value[0] = 0x51; | 55 | gaff->report->field[0]->value[0] = 0x51; |
56 | gaff->report->field[0]->value[1] = 0x0; | 56 | gaff->report->field[0]->value[1] = 0x0; |
57 | gaff->report->field[0]->value[2] = right; | 57 | gaff->report->field[0]->value[2] = right; |
58 | gaff->report->field[0]->value[3] = 0; | 58 | gaff->report->field[0]->value[3] = 0; |
59 | gaff->report->field[0]->value[4] = left; | 59 | gaff->report->field[0]->value[4] = left; |
60 | gaff->report->field[0]->value[5] = 0; | 60 | gaff->report->field[0]->value[5] = 0; |
61 | dbg_hid("running with 0x%02x 0x%02x", left, right); | 61 | dbg_hid("running with 0x%02x 0x%02x", left, right); |
62 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 62 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); |
63 | 63 | ||
64 | gaff->report->field[0]->value[0] = 0xfa; | 64 | gaff->report->field[0]->value[0] = 0xfa; |
65 | gaff->report->field[0]->value[1] = 0xfe; | 65 | gaff->report->field[0]->value[1] = 0xfe; |
66 | gaff->report->field[0]->value[2] = 0x0; | 66 | gaff->report->field[0]->value[2] = 0x0; |
67 | gaff->report->field[0]->value[4] = 0x0; | 67 | gaff->report->field[0]->value[4] = 0x0; |
68 | 68 | ||
69 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 69 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); |
70 | 70 | ||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int gaff_init(struct hid_device *hid) | 74 | static int gaff_init(struct hid_device *hid) |
75 | { | 75 | { |
76 | struct gaff_device *gaff; | 76 | struct gaff_device *gaff; |
77 | struct hid_report *report; | 77 | struct hid_report *report; |
78 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 78 | struct hid_input *hidinput = list_entry(hid->inputs.next, |
79 | struct hid_input, list); | 79 | struct hid_input, list); |
80 | struct list_head *report_list = | 80 | struct list_head *report_list = |
81 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 81 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
82 | struct list_head *report_ptr = report_list; | 82 | struct list_head *report_ptr = report_list; |
83 | struct input_dev *dev = hidinput->input; | 83 | struct input_dev *dev = hidinput->input; |
84 | int error; | 84 | int error; |
85 | 85 | ||
86 | if (list_empty(report_list)) { | 86 | if (list_empty(report_list)) { |
87 | dev_err(&hid->dev, "no output reports found\n"); | 87 | dev_err(&hid->dev, "no output reports found\n"); |
88 | return -ENODEV; | 88 | return -ENODEV; |
89 | } | 89 | } |
90 | 90 | ||
91 | report_ptr = report_ptr->next; | 91 | report_ptr = report_ptr->next; |
92 | 92 | ||
93 | report = list_entry(report_ptr, struct hid_report, list); | 93 | report = list_entry(report_ptr, struct hid_report, list); |
94 | if (report->maxfield < 1) { | 94 | if (report->maxfield < 1) { |
95 | dev_err(&hid->dev, "no fields in the report\n"); | 95 | dev_err(&hid->dev, "no fields in the report\n"); |
96 | return -ENODEV; | 96 | return -ENODEV; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (report->field[0]->report_count < 6) { | 99 | if (report->field[0]->report_count < 6) { |
100 | dev_err(&hid->dev, "not enough values in the field\n"); | 100 | dev_err(&hid->dev, "not enough values in the field\n"); |
101 | return -ENODEV; | 101 | return -ENODEV; |
102 | } | 102 | } |
103 | 103 | ||
104 | gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL); | 104 | gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL); |
105 | if (!gaff) | 105 | if (!gaff) |
106 | return -ENOMEM; | 106 | return -ENOMEM; |
107 | 107 | ||
108 | set_bit(FF_RUMBLE, dev->ffbit); | 108 | set_bit(FF_RUMBLE, dev->ffbit); |
109 | 109 | ||
110 | error = input_ff_create_memless(dev, gaff, hid_gaff_play); | 110 | error = input_ff_create_memless(dev, gaff, hid_gaff_play); |
111 | if (error) { | 111 | if (error) { |
112 | kfree(gaff); | 112 | kfree(gaff); |
113 | return error; | 113 | return error; |
114 | } | 114 | } |
115 | 115 | ||
116 | gaff->report = report; | 116 | gaff->report = report; |
117 | gaff->report->field[0]->value[0] = 0x51; | 117 | gaff->report->field[0]->value[0] = 0x51; |
118 | gaff->report->field[0]->value[1] = 0x00; | 118 | gaff->report->field[0]->value[1] = 0x00; |
119 | gaff->report->field[0]->value[2] = 0x00; | 119 | gaff->report->field[0]->value[2] = 0x00; |
120 | gaff->report->field[0]->value[3] = 0x00; | 120 | gaff->report->field[0]->value[3] = 0x00; |
121 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 121 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); |
122 | 122 | ||
123 | gaff->report->field[0]->value[0] = 0xfa; | 123 | gaff->report->field[0]->value[0] = 0xfa; |
124 | gaff->report->field[0]->value[1] = 0xfe; | 124 | gaff->report->field[0]->value[1] = 0xfe; |
125 | 125 | ||
126 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 126 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); |
127 | 127 | ||
128 | dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12" | 128 | dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12" |
129 | " devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n"); | 129 | " devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n"); |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | 133 | ||
134 | static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id) | 134 | static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id) |
135 | { | 135 | { |
136 | int ret; | 136 | int ret; |
137 | 137 | ||
138 | dev_dbg(&hdev->dev, "Greenasia HID hardware probe..."); | 138 | dev_dbg(&hdev->dev, "Greenasia HID hardware probe..."); |
139 | 139 | ||
140 | ret = hid_parse(hdev); | 140 | ret = hid_parse(hdev); |
141 | if (ret) { | 141 | if (ret) { |
142 | dev_err(&hdev->dev, "parse failed\n"); | 142 | dev_err(&hdev->dev, "parse failed\n"); |
143 | goto err; | 143 | goto err; |
144 | } | 144 | } |
145 | 145 | ||
146 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 146 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
147 | if (ret) { | 147 | if (ret) { |
148 | dev_err(&hdev->dev, "hw start failed\n"); | 148 | dev_err(&hdev->dev, "hw start failed\n"); |
149 | goto err; | 149 | goto err; |
150 | } | 150 | } |
151 | 151 | ||
152 | gaff_init(hdev); | 152 | gaff_init(hdev); |
153 | 153 | ||
154 | return 0; | 154 | return 0; |
155 | err: | 155 | err: |
156 | return ret; | 156 | return ret; |
157 | } | 157 | } |
158 | 158 | ||
159 | static const struct hid_device_id ga_devices[] = { | 159 | static const struct hid_device_id ga_devices[] = { |
160 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012), }, | 160 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012), }, |
161 | { } | 161 | { } |
162 | }; | 162 | }; |
163 | MODULE_DEVICE_TABLE(hid, ga_devices); | 163 | MODULE_DEVICE_TABLE(hid, ga_devices); |
164 | 164 | ||
165 | static struct hid_driver ga_driver = { | 165 | static struct hid_driver ga_driver = { |
166 | .name = "greenasia", | 166 | .name = "greenasia", |
167 | .id_table = ga_devices, | 167 | .id_table = ga_devices, |
168 | .probe = ga_probe, | 168 | .probe = ga_probe, |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static int __init ga_init(void) | 171 | static int __init ga_init(void) |
172 | { | 172 | { |
173 | return hid_register_driver(&ga_driver); | 173 | return hid_register_driver(&ga_driver); |
174 | } | 174 | } |
175 | 175 | ||
176 | static void __exit ga_exit(void) | 176 | static void __exit ga_exit(void) |
177 | { | 177 | { |
178 | hid_unregister_driver(&ga_driver); | 178 | hid_unregister_driver(&ga_driver); |
179 | } | 179 | } |
180 | 180 | ||
181 | module_init(ga_init); | 181 | module_init(ga_init); |
182 | module_exit(ga_exit); | 182 | module_exit(ga_exit); |
183 | MODULE_LICENSE("GPL"); | 183 | MODULE_LICENSE("GPL"); |
184 | |||
185 | HID_COMPAT_LOAD_DRIVER(greenasia); | ||
186 | 184 |
drivers/hid/hid-gyration.c
1 | /* | 1 | /* |
2 | * HID driver for some gyration "special" devices | 2 | * HID driver for some gyration "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) 2007 Paul Walmsley | 7 | * Copyright (c) 2007 Paul Walmsley |
8 | * Copyright (c) 2008 Jiri Slaby | 8 | * Copyright (c) 2008 Jiri Slaby |
9 | * Copyright (c) 2006-2008 Jiri Kosina | 9 | * Copyright (c) 2006-2008 Jiri Kosina |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define gy_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 26 | #define gy_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
27 | EV_KEY, (c)) | 27 | EV_KEY, (c)) |
28 | static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 28 | static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
29 | struct hid_field *field, struct hid_usage *usage, | 29 | struct hid_field *field, struct hid_usage *usage, |
30 | unsigned long **bit, int *max) | 30 | unsigned long **bit, int *max) |
31 | { | 31 | { |
32 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | 32 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) |
33 | return 0; | 33 | return 0; |
34 | 34 | ||
35 | set_bit(EV_REP, hi->input->evbit); | 35 | set_bit(EV_REP, hi->input->evbit); |
36 | switch (usage->hid & HID_USAGE) { | 36 | switch (usage->hid & HID_USAGE) { |
37 | /* Reported on Gyration MCE Remote */ | 37 | /* Reported on Gyration MCE Remote */ |
38 | case 0x00d: gy_map_key_clear(KEY_HOME); break; | 38 | case 0x00d: gy_map_key_clear(KEY_HOME); break; |
39 | case 0x024: gy_map_key_clear(KEY_DVD); break; | 39 | case 0x024: gy_map_key_clear(KEY_DVD); break; |
40 | case 0x025: gy_map_key_clear(KEY_PVR); break; | 40 | case 0x025: gy_map_key_clear(KEY_PVR); break; |
41 | case 0x046: gy_map_key_clear(KEY_MEDIA); break; | 41 | case 0x046: gy_map_key_clear(KEY_MEDIA); break; |
42 | case 0x047: gy_map_key_clear(KEY_MP3); break; | 42 | case 0x047: gy_map_key_clear(KEY_MP3); break; |
43 | case 0x048: gy_map_key_clear(KEY_MEDIA); break; | 43 | case 0x048: gy_map_key_clear(KEY_MEDIA); break; |
44 | case 0x049: gy_map_key_clear(KEY_CAMERA); break; | 44 | case 0x049: gy_map_key_clear(KEY_CAMERA); break; |
45 | case 0x04a: gy_map_key_clear(KEY_VIDEO); break; | 45 | case 0x04a: gy_map_key_clear(KEY_VIDEO); break; |
46 | 46 | ||
47 | default: | 47 | default: |
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | return 1; | 50 | return 1; |
51 | } | 51 | } |
52 | 52 | ||
53 | static int gyration_event(struct hid_device *hdev, struct hid_field *field, | 53 | static int gyration_event(struct hid_device *hdev, struct hid_field *field, |
54 | struct hid_usage *usage, __s32 value) | 54 | struct hid_usage *usage, __s32 value) |
55 | { | 55 | { |
56 | struct input_dev *input = field->hidinput->input; | 56 | struct input_dev *input = field->hidinput->input; |
57 | 57 | ||
58 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && | 58 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && |
59 | (usage->hid & 0xff) == 0x82) { | 59 | (usage->hid & 0xff) == 0x82) { |
60 | input_event(input, usage->type, usage->code, 1); | 60 | input_event(input, usage->type, usage->code, 1); |
61 | input_sync(input); | 61 | input_sync(input); |
62 | input_event(input, usage->type, usage->code, 0); | 62 | input_event(input, usage->type, usage->code, 0); |
63 | input_sync(input); | 63 | input_sync(input); |
64 | return 1; | 64 | return 1; |
65 | } | 65 | } |
66 | 66 | ||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | static const struct hid_device_id gyration_devices[] = { | 70 | static const struct hid_device_id gyration_devices[] = { |
71 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 71 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
72 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 72 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
73 | { } | 73 | { } |
74 | }; | 74 | }; |
75 | MODULE_DEVICE_TABLE(hid, gyration_devices); | 75 | MODULE_DEVICE_TABLE(hid, gyration_devices); |
76 | 76 | ||
77 | static struct hid_driver gyration_driver = { | 77 | static struct hid_driver gyration_driver = { |
78 | .name = "gyration", | 78 | .name = "gyration", |
79 | .id_table = gyration_devices, | 79 | .id_table = gyration_devices, |
80 | .input_mapping = gyration_input_mapping, | 80 | .input_mapping = gyration_input_mapping, |
81 | .event = gyration_event, | 81 | .event = gyration_event, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static int gyration_init(void) | 84 | static int gyration_init(void) |
85 | { | 85 | { |
86 | return hid_register_driver(&gyration_driver); | 86 | return hid_register_driver(&gyration_driver); |
87 | } | 87 | } |
88 | 88 | ||
89 | static void gyration_exit(void) | 89 | static void gyration_exit(void) |
90 | { | 90 | { |
91 | hid_unregister_driver(&gyration_driver); | 91 | hid_unregister_driver(&gyration_driver); |
92 | } | 92 | } |
93 | 93 | ||
94 | module_init(gyration_init); | 94 | module_init(gyration_init); |
95 | module_exit(gyration_exit); | 95 | module_exit(gyration_exit); |
96 | MODULE_LICENSE("GPL"); | 96 | MODULE_LICENSE("GPL"); |
97 | |||
98 | HID_COMPAT_LOAD_DRIVER(gyration); | ||
99 | 97 |
drivers/hid/hid-kensington.c
1 | /* | 1 | /* |
2 | * HID driver for Kensigton Slimblade Trackball | 2 | * HID driver for Kensigton Slimblade Trackball |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Jiri Kosina | 4 | * Copyright (c) 2009 Jiri Kosina |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 11 | * any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/hid.h> | 16 | #include <linux/hid.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include "hid-ids.h" | 19 | #include "hid-ids.h" |
20 | 20 | ||
21 | #define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) | 21 | #define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) |
22 | 22 | ||
23 | static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 23 | static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
24 | struct hid_field *field, struct hid_usage *usage, | 24 | struct hid_field *field, struct hid_usage *usage, |
25 | unsigned long **bit, int *max) | 25 | unsigned long **bit, int *max) |
26 | { | 26 | { |
27 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | 27 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) |
28 | return 0; | 28 | return 0; |
29 | 29 | ||
30 | switch (usage->hid & HID_USAGE) { | 30 | switch (usage->hid & HID_USAGE) { |
31 | case 0x01: ks_map_key(BTN_MIDDLE); break; | 31 | case 0x01: ks_map_key(BTN_MIDDLE); break; |
32 | case 0x02: ks_map_key(BTN_SIDE); break; | 32 | case 0x02: ks_map_key(BTN_SIDE); break; |
33 | default: | 33 | default: |
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | return 1; | 36 | return 1; |
37 | } | 37 | } |
38 | 38 | ||
39 | static const struct hid_device_id ks_devices[] = { | 39 | static const struct hid_device_id ks_devices[] = { |
40 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 40 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
41 | { } | 41 | { } |
42 | }; | 42 | }; |
43 | MODULE_DEVICE_TABLE(hid, ks_devices); | 43 | MODULE_DEVICE_TABLE(hid, ks_devices); |
44 | 44 | ||
45 | static struct hid_driver ks_driver = { | 45 | static struct hid_driver ks_driver = { |
46 | .name = "kensington", | 46 | .name = "kensington", |
47 | .id_table = ks_devices, | 47 | .id_table = ks_devices, |
48 | .input_mapping = ks_input_mapping, | 48 | .input_mapping = ks_input_mapping, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static int ks_init(void) | 51 | static int ks_init(void) |
52 | { | 52 | { |
53 | return hid_register_driver(&ks_driver); | 53 | return hid_register_driver(&ks_driver); |
54 | } | 54 | } |
55 | 55 | ||
56 | static void ks_exit(void) | 56 | static void ks_exit(void) |
57 | { | 57 | { |
58 | hid_unregister_driver(&ks_driver); | 58 | hid_unregister_driver(&ks_driver); |
59 | } | 59 | } |
60 | 60 | ||
61 | module_init(ks_init); | 61 | module_init(ks_init); |
62 | module_exit(ks_exit); | 62 | module_exit(ks_exit); |
63 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
64 | |||
65 | HID_COMPAT_LOAD_DRIVER(kensington); | ||
66 | 64 |
drivers/hid/hid-kye.c
1 | /* | 1 | /* |
2 | * HID driver for Kye/Genius devices not fully compliant with HID standard | 2 | * HID driver for Kye/Genius devices not fully compliant with HID standard |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Jiri Kosina | 4 | * Copyright (c) 2009 Jiri Kosina |
5 | * Copyright (c) 2009 Tomas Hanak | 5 | * Copyright (c) 2009 Tomas Hanak |
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 | 18 | ||
19 | #include "hid-ids.h" | 19 | #include "hid-ids.h" |
20 | 20 | ||
21 | /* the fixups that need to be done: | 21 | /* the fixups that need to be done: |
22 | * - change led usage page to button for extra buttons | 22 | * - change led usage page to button for extra buttons |
23 | * - report size 8 count 1 must be size 1 count 8 for button bitfield | 23 | * - report size 8 count 1 must be size 1 count 8 for button bitfield |
24 | * - change the button usage range to 4-7 for the extra buttons | 24 | * - change the button usage range to 4-7 for the extra buttons |
25 | */ | 25 | */ |
26 | static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 26 | static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
27 | unsigned int rsize) | 27 | unsigned int rsize) |
28 | { | 28 | { |
29 | if (rsize >= 74 && | 29 | if (rsize >= 74 && |
30 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | 30 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && |
31 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | 31 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && |
32 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | 32 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && |
33 | rdesc[71] == 0x75 && rdesc[72] == 0x08 && | 33 | rdesc[71] == 0x75 && rdesc[72] == 0x08 && |
34 | rdesc[73] == 0x95 && rdesc[74] == 0x01) { | 34 | rdesc[73] == 0x95 && rdesc[74] == 0x01) { |
35 | dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report " | 35 | dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report " |
36 | "descriptor\n"); | 36 | "descriptor\n"); |
37 | rdesc[62] = 0x09; | 37 | rdesc[62] = 0x09; |
38 | rdesc[64] = 0x04; | 38 | rdesc[64] = 0x04; |
39 | rdesc[66] = 0x07; | 39 | rdesc[66] = 0x07; |
40 | rdesc[72] = 0x01; | 40 | rdesc[72] = 0x01; |
41 | rdesc[74] = 0x08; | 41 | rdesc[74] = 0x08; |
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | ||
45 | static const struct hid_device_id kye_devices[] = { | 45 | static const struct hid_device_id kye_devices[] = { |
46 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 46 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
47 | { } | 47 | { } |
48 | }; | 48 | }; |
49 | MODULE_DEVICE_TABLE(hid, kye_devices); | 49 | MODULE_DEVICE_TABLE(hid, kye_devices); |
50 | 50 | ||
51 | static struct hid_driver kye_driver = { | 51 | static struct hid_driver kye_driver = { |
52 | .name = "kye", | 52 | .name = "kye", |
53 | .id_table = kye_devices, | 53 | .id_table = kye_devices, |
54 | .report_fixup = kye_report_fixup, | 54 | .report_fixup = kye_report_fixup, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static int kye_init(void) | 57 | static int kye_init(void) |
58 | { | 58 | { |
59 | return hid_register_driver(&kye_driver); | 59 | return hid_register_driver(&kye_driver); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void kye_exit(void) | 62 | static void kye_exit(void) |
63 | { | 63 | { |
64 | hid_unregister_driver(&kye_driver); | 64 | hid_unregister_driver(&kye_driver); |
65 | } | 65 | } |
66 | 66 | ||
67 | module_init(kye_init); | 67 | module_init(kye_init); |
68 | module_exit(kye_exit); | 68 | module_exit(kye_exit); |
69 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
70 | |||
71 | HID_COMPAT_LOAD_DRIVER(kye); | ||
72 | 70 |
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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | #include "hid-lg.h" | 24 | #include "hid-lg.h" |
25 | 25 | ||
26 | #define LG_RDESC 0x001 | 26 | #define LG_RDESC 0x001 |
27 | #define LG_BAD_RELATIVE_KEYS 0x002 | 27 | #define LG_BAD_RELATIVE_KEYS 0x002 |
28 | #define LG_DUPLICATE_USAGES 0x004 | 28 | #define LG_DUPLICATE_USAGES 0x004 |
29 | #define LG_EXPANDED_KEYMAP 0x010 | 29 | #define LG_EXPANDED_KEYMAP 0x010 |
30 | #define LG_IGNORE_DOUBLED_WHEEL 0x020 | 30 | #define LG_IGNORE_DOUBLED_WHEEL 0x020 |
31 | #define LG_WIRELESS 0x040 | 31 | #define LG_WIRELESS 0x040 |
32 | #define LG_INVERT_HWHEEL 0x080 | 32 | #define LG_INVERT_HWHEEL 0x080 |
33 | #define LG_NOGET 0x100 | 33 | #define LG_NOGET 0x100 |
34 | #define LG_FF 0x200 | 34 | #define LG_FF 0x200 |
35 | #define LG_FF2 0x400 | 35 | #define LG_FF2 0x400 |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Certain Logitech keyboards send in report #3 keys which are far | 38 | * Certain Logitech keyboards send in report #3 keys which are far |
39 | * above the logical maximum described in descriptor. This extends | 39 | * above the logical maximum described in descriptor. This extends |
40 | * the original value of 0x28c of logical maximum to 0x104d | 40 | * the original value of 0x28c of logical maximum to 0x104d |
41 | */ | 41 | */ |
42 | static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 42 | static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
43 | unsigned int rsize) | 43 | unsigned int rsize) |
44 | { | 44 | { |
45 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 45 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
46 | 46 | ||
47 | if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && | 47 | if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && |
48 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 48 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
49 | dev_info(&hdev->dev, "fixing up Logitech keyboard report " | 49 | dev_info(&hdev->dev, "fixing up Logitech keyboard report " |
50 | "descriptor\n"); | 50 | "descriptor\n"); |
51 | rdesc[84] = rdesc[89] = 0x4d; | 51 | rdesc[84] = rdesc[89] = 0x4d; |
52 | rdesc[85] = rdesc[90] = 0x10; | 52 | rdesc[85] = rdesc[90] = 0x10; |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 56 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
57 | EV_KEY, (c)) | 57 | EV_KEY, (c)) |
58 | 58 | ||
59 | static int lg_ultrax_remote_mapping(struct hid_input *hi, | 59 | static int lg_ultrax_remote_mapping(struct hid_input *hi, |
60 | struct hid_usage *usage, unsigned long **bit, int *max) | 60 | struct hid_usage *usage, unsigned long **bit, int *max) |
61 | { | 61 | { |
62 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | 62 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) |
63 | return 0; | 63 | return 0; |
64 | 64 | ||
65 | set_bit(EV_REP, hi->input->evbit); | 65 | set_bit(EV_REP, hi->input->evbit); |
66 | switch (usage->hid & HID_USAGE) { | 66 | switch (usage->hid & HID_USAGE) { |
67 | /* Reported on Logitech Ultra X Media Remote */ | 67 | /* Reported on Logitech Ultra X Media Remote */ |
68 | case 0x004: lg_map_key_clear(KEY_AGAIN); break; | 68 | case 0x004: lg_map_key_clear(KEY_AGAIN); break; |
69 | case 0x00d: lg_map_key_clear(KEY_HOME); break; | 69 | case 0x00d: lg_map_key_clear(KEY_HOME); break; |
70 | case 0x024: lg_map_key_clear(KEY_SHUFFLE); break; | 70 | case 0x024: lg_map_key_clear(KEY_SHUFFLE); break; |
71 | case 0x025: lg_map_key_clear(KEY_TV); break; | 71 | case 0x025: lg_map_key_clear(KEY_TV); break; |
72 | case 0x026: lg_map_key_clear(KEY_MENU); break; | 72 | case 0x026: lg_map_key_clear(KEY_MENU); break; |
73 | case 0x031: lg_map_key_clear(KEY_AUDIO); break; | 73 | case 0x031: lg_map_key_clear(KEY_AUDIO); break; |
74 | case 0x032: lg_map_key_clear(KEY_TEXT); break; | 74 | case 0x032: lg_map_key_clear(KEY_TEXT); break; |
75 | case 0x033: lg_map_key_clear(KEY_LAST); break; | 75 | case 0x033: lg_map_key_clear(KEY_LAST); break; |
76 | case 0x047: lg_map_key_clear(KEY_MP3); break; | 76 | case 0x047: lg_map_key_clear(KEY_MP3); break; |
77 | case 0x048: lg_map_key_clear(KEY_DVD); break; | 77 | case 0x048: lg_map_key_clear(KEY_DVD); break; |
78 | case 0x049: lg_map_key_clear(KEY_MEDIA); break; | 78 | case 0x049: lg_map_key_clear(KEY_MEDIA); break; |
79 | case 0x04a: lg_map_key_clear(KEY_VIDEO); break; | 79 | case 0x04a: lg_map_key_clear(KEY_VIDEO); break; |
80 | case 0x04b: lg_map_key_clear(KEY_ANGLE); break; | 80 | case 0x04b: lg_map_key_clear(KEY_ANGLE); break; |
81 | case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break; | 81 | case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break; |
82 | case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break; | 82 | case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break; |
83 | case 0x051: lg_map_key_clear(KEY_RED); break; | 83 | case 0x051: lg_map_key_clear(KEY_RED); break; |
84 | case 0x052: lg_map_key_clear(KEY_CLOSE); break; | 84 | case 0x052: lg_map_key_clear(KEY_CLOSE); break; |
85 | 85 | ||
86 | default: | 86 | default: |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | return 1; | 89 | return 1; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, | 92 | static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, |
93 | unsigned long **bit, int *max) | 93 | unsigned long **bit, int *max) |
94 | { | 94 | { |
95 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 95 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
96 | return 0; | 96 | return 0; |
97 | 97 | ||
98 | switch (usage->hid & HID_USAGE) { | 98 | switch (usage->hid & HID_USAGE) { |
99 | case 0x1001: lg_map_key_clear(KEY_MESSENGER); break; | 99 | case 0x1001: lg_map_key_clear(KEY_MESSENGER); break; |
100 | case 0x1003: lg_map_key_clear(KEY_SOUND); break; | 100 | case 0x1003: lg_map_key_clear(KEY_SOUND); break; |
101 | case 0x1004: lg_map_key_clear(KEY_VIDEO); break; | 101 | case 0x1004: lg_map_key_clear(KEY_VIDEO); break; |
102 | case 0x1005: lg_map_key_clear(KEY_AUDIO); break; | 102 | case 0x1005: lg_map_key_clear(KEY_AUDIO); break; |
103 | case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; | 103 | case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; |
104 | case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; | 104 | case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; |
105 | case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; | 105 | case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; |
106 | case 0x1013: lg_map_key_clear(KEY_CAMERA); break; | 106 | case 0x1013: lg_map_key_clear(KEY_CAMERA); break; |
107 | case 0x1014: lg_map_key_clear(KEY_MESSENGER); break; | 107 | case 0x1014: lg_map_key_clear(KEY_MESSENGER); break; |
108 | case 0x1015: lg_map_key_clear(KEY_RECORD); break; | 108 | case 0x1015: lg_map_key_clear(KEY_RECORD); break; |
109 | case 0x1016: lg_map_key_clear(KEY_PLAYER); break; | 109 | case 0x1016: lg_map_key_clear(KEY_PLAYER); break; |
110 | case 0x1017: lg_map_key_clear(KEY_EJECTCD); break; | 110 | case 0x1017: lg_map_key_clear(KEY_EJECTCD); break; |
111 | case 0x1018: lg_map_key_clear(KEY_MEDIA); break; | 111 | case 0x1018: lg_map_key_clear(KEY_MEDIA); break; |
112 | case 0x1019: lg_map_key_clear(KEY_PROG1); break; | 112 | case 0x1019: lg_map_key_clear(KEY_PROG1); break; |
113 | case 0x101a: lg_map_key_clear(KEY_PROG2); break; | 113 | case 0x101a: lg_map_key_clear(KEY_PROG2); break; |
114 | case 0x101b: lg_map_key_clear(KEY_PROG3); break; | 114 | case 0x101b: lg_map_key_clear(KEY_PROG3); break; |
115 | case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; | 115 | case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; |
116 | case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; | 116 | case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; |
117 | case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; | 117 | case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; |
118 | case 0x1023: lg_map_key_clear(KEY_CLOSE); break; | 118 | case 0x1023: lg_map_key_clear(KEY_CLOSE); break; |
119 | case 0x1027: lg_map_key_clear(KEY_MENU); break; | 119 | case 0x1027: lg_map_key_clear(KEY_MENU); break; |
120 | /* this one is marked as 'Rotate' */ | 120 | /* this one is marked as 'Rotate' */ |
121 | case 0x1028: lg_map_key_clear(KEY_ANGLE); break; | 121 | case 0x1028: lg_map_key_clear(KEY_ANGLE); break; |
122 | case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; | 122 | case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; |
123 | case 0x102a: lg_map_key_clear(KEY_BACK); break; | 123 | case 0x102a: lg_map_key_clear(KEY_BACK); break; |
124 | case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; | 124 | case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; |
125 | case 0x1041: lg_map_key_clear(KEY_BATTERY); break; | 125 | case 0x1041: lg_map_key_clear(KEY_BATTERY); break; |
126 | case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; | 126 | case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; |
127 | case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; | 127 | case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; |
128 | case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break; | 128 | case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break; |
129 | case 0x1045: lg_map_key_clear(KEY_UNDO); break; | 129 | case 0x1045: lg_map_key_clear(KEY_UNDO); break; |
130 | case 0x1046: lg_map_key_clear(KEY_REDO); break; | 130 | case 0x1046: lg_map_key_clear(KEY_REDO); break; |
131 | case 0x1047: lg_map_key_clear(KEY_PRINT); break; | 131 | case 0x1047: lg_map_key_clear(KEY_PRINT); break; |
132 | case 0x1048: lg_map_key_clear(KEY_SAVE); break; | 132 | case 0x1048: lg_map_key_clear(KEY_SAVE); break; |
133 | case 0x1049: lg_map_key_clear(KEY_PROG1); break; | 133 | case 0x1049: lg_map_key_clear(KEY_PROG1); break; |
134 | case 0x104a: lg_map_key_clear(KEY_PROG2); break; | 134 | case 0x104a: lg_map_key_clear(KEY_PROG2); break; |
135 | case 0x104b: lg_map_key_clear(KEY_PROG3); break; | 135 | case 0x104b: lg_map_key_clear(KEY_PROG3); break; |
136 | case 0x104c: lg_map_key_clear(KEY_PROG4); break; | 136 | case 0x104c: lg_map_key_clear(KEY_PROG4); break; |
137 | 137 | ||
138 | default: | 138 | default: |
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | return 1; | 141 | return 1; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 144 | static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
145 | struct hid_field *field, struct hid_usage *usage, | 145 | struct hid_field *field, struct hid_usage *usage, |
146 | unsigned long **bit, int *max) | 146 | unsigned long **bit, int *max) |
147 | { | 147 | { |
148 | /* extended mapping for certain Logitech hardware (Logitech cordless | 148 | /* extended mapping for certain Logitech hardware (Logitech cordless |
149 | desktop LX500) */ | 149 | desktop LX500) */ |
150 | static const u8 e_keymap[] = { | 150 | static const u8 e_keymap[] = { |
151 | 0,216, 0,213,175,156, 0, 0, 0, 0, | 151 | 0,216, 0,213,175,156, 0, 0, 0, 0, |
152 | 144, 0, 0, 0, 0, 0, 0, 0, 0,212, | 152 | 144, 0, 0, 0, 0, 0, 0, 0, 0,212, |
153 | 174,167,152,161,112, 0, 0, 0,154, 0, | 153 | 174,167,152,161,112, 0, 0, 0,154, 0, |
154 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 154 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
155 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 155 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
156 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 156 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
157 | 0, 0, 0, 0, 0,183,184,185,186,187, | 157 | 0, 0, 0, 0, 0,183,184,185,186,187, |
158 | 188,189,190,191,192,193,194, 0, 0, 0 | 158 | 188,189,190,191,192,193,194, 0, 0, 0 |
159 | }; | 159 | }; |
160 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 160 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
161 | unsigned int hid = usage->hid; | 161 | unsigned int hid = usage->hid; |
162 | 162 | ||
163 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && | 163 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && |
164 | lg_ultrax_remote_mapping(hi, usage, bit, max)) | 164 | lg_ultrax_remote_mapping(hi, usage, bit, max)) |
165 | return 1; | 165 | return 1; |
166 | 166 | ||
167 | if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) | 167 | if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) |
168 | return 1; | 168 | return 1; |
169 | 169 | ||
170 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | 170 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) |
171 | return 0; | 171 | return 0; |
172 | 172 | ||
173 | hid &= HID_USAGE; | 173 | hid &= HID_USAGE; |
174 | 174 | ||
175 | /* Special handling for Logitech Cordless Desktop */ | 175 | /* Special handling for Logitech Cordless Desktop */ |
176 | if (field->application == HID_GD_MOUSE) { | 176 | if (field->application == HID_GD_MOUSE) { |
177 | if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && | 177 | if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && |
178 | (hid == 7 || hid == 8)) | 178 | (hid == 7 || hid == 8)) |
179 | return -1; | 179 | return -1; |
180 | } else { | 180 | } else { |
181 | if ((quirks & LG_EXPANDED_KEYMAP) && | 181 | if ((quirks & LG_EXPANDED_KEYMAP) && |
182 | hid < ARRAY_SIZE(e_keymap) && | 182 | hid < ARRAY_SIZE(e_keymap) && |
183 | e_keymap[hid] != 0) { | 183 | e_keymap[hid] != 0) { |
184 | hid_map_usage(hi, usage, bit, max, EV_KEY, | 184 | hid_map_usage(hi, usage, bit, max, EV_KEY, |
185 | e_keymap[hid]); | 185 | e_keymap[hid]); |
186 | return 1; | 186 | return 1; |
187 | } | 187 | } |
188 | } | 188 | } |
189 | 189 | ||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 193 | static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
194 | struct hid_field *field, struct hid_usage *usage, | 194 | struct hid_field *field, struct hid_usage *usage, |
195 | unsigned long **bit, int *max) | 195 | unsigned long **bit, int *max) |
196 | { | 196 | { |
197 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 197 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
198 | 198 | ||
199 | if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && | 199 | if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && |
200 | (field->flags & HID_MAIN_ITEM_RELATIVE)) | 200 | (field->flags & HID_MAIN_ITEM_RELATIVE)) |
201 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; | 201 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; |
202 | 202 | ||
203 | if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || | 203 | if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || |
204 | usage->type == EV_REL || usage->type == EV_ABS)) | 204 | usage->type == EV_REL || usage->type == EV_ABS)) |
205 | clear_bit(usage->code, *bit); | 205 | clear_bit(usage->code, *bit); |
206 | 206 | ||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static int lg_event(struct hid_device *hdev, struct hid_field *field, | 210 | static int lg_event(struct hid_device *hdev, struct hid_field *field, |
211 | struct hid_usage *usage, __s32 value) | 211 | struct hid_usage *usage, __s32 value) |
212 | { | 212 | { |
213 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 213 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
214 | 214 | ||
215 | if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { | 215 | if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { |
216 | input_event(field->hidinput->input, usage->type, usage->code, | 216 | input_event(field->hidinput->input, usage->type, usage->code, |
217 | -value); | 217 | -value); |
218 | return 1; | 218 | return 1; |
219 | } | 219 | } |
220 | 220 | ||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | 224 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) |
225 | { | 225 | { |
226 | unsigned long quirks = id->driver_data; | 226 | unsigned long quirks = id->driver_data; |
227 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 227 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
228 | int ret; | 228 | int ret; |
229 | 229 | ||
230 | hid_set_drvdata(hdev, (void *)quirks); | 230 | hid_set_drvdata(hdev, (void *)quirks); |
231 | 231 | ||
232 | if (quirks & LG_NOGET) | 232 | if (quirks & LG_NOGET) |
233 | hdev->quirks |= HID_QUIRK_NOGET; | 233 | hdev->quirks |= HID_QUIRK_NOGET; |
234 | 234 | ||
235 | ret = hid_parse(hdev); | 235 | ret = hid_parse(hdev); |
236 | if (ret) { | 236 | if (ret) { |
237 | dev_err(&hdev->dev, "parse failed\n"); | 237 | dev_err(&hdev->dev, "parse failed\n"); |
238 | goto err_free; | 238 | goto err_free; |
239 | } | 239 | } |
240 | 240 | ||
241 | if (quirks & (LG_FF | LG_FF2)) | 241 | if (quirks & (LG_FF | LG_FF2)) |
242 | connect_mask &= ~HID_CONNECT_FF; | 242 | connect_mask &= ~HID_CONNECT_FF; |
243 | 243 | ||
244 | ret = hid_hw_start(hdev, connect_mask); | 244 | ret = hid_hw_start(hdev, connect_mask); |
245 | if (ret) { | 245 | if (ret) { |
246 | dev_err(&hdev->dev, "hw start failed\n"); | 246 | dev_err(&hdev->dev, "hw start failed\n"); |
247 | goto err_free; | 247 | goto err_free; |
248 | } | 248 | } |
249 | 249 | ||
250 | if (quirks & LG_FF) | 250 | if (quirks & LG_FF) |
251 | lgff_init(hdev); | 251 | lgff_init(hdev); |
252 | if (quirks & LG_FF2) | 252 | if (quirks & LG_FF2) |
253 | lg2ff_init(hdev); | 253 | lg2ff_init(hdev); |
254 | 254 | ||
255 | return 0; | 255 | return 0; |
256 | err_free: | 256 | err_free: |
257 | return ret; | 257 | return ret; |
258 | } | 258 | } |
259 | 259 | ||
260 | static const struct hid_device_id lg_devices[] = { | 260 | static const struct hid_device_id lg_devices[] = { |
261 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), | 261 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), |
262 | .driver_data = LG_RDESC | LG_WIRELESS }, | 262 | .driver_data = LG_RDESC | LG_WIRELESS }, |
263 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), | 263 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), |
264 | .driver_data = LG_RDESC | LG_WIRELESS }, | 264 | .driver_data = LG_RDESC | LG_WIRELESS }, |
265 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), | 265 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), |
266 | .driver_data = LG_RDESC | LG_WIRELESS }, | 266 | .driver_data = LG_RDESC | LG_WIRELESS }, |
267 | 267 | ||
268 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), | 268 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), |
269 | .driver_data = LG_BAD_RELATIVE_KEYS }, | 269 | .driver_data = LG_BAD_RELATIVE_KEYS }, |
270 | 270 | ||
271 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), | 271 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), |
272 | .driver_data = LG_DUPLICATE_USAGES }, | 272 | .driver_data = LG_DUPLICATE_USAGES }, |
273 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), | 273 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), |
274 | .driver_data = LG_DUPLICATE_USAGES }, | 274 | .driver_data = LG_DUPLICATE_USAGES }, |
275 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), | 275 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), |
276 | .driver_data = LG_DUPLICATE_USAGES }, | 276 | .driver_data = LG_DUPLICATE_USAGES }, |
277 | 277 | ||
278 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), | 278 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), |
279 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, | 279 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, |
280 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), | 280 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), |
281 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, | 281 | .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, |
282 | 282 | ||
283 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), | 283 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), |
284 | .driver_data = LG_NOGET }, | 284 | .driver_data = LG_NOGET }, |
285 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), | 285 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), |
286 | .driver_data = LG_NOGET | LG_FF }, | 286 | .driver_data = LG_NOGET | LG_FF }, |
287 | 287 | ||
288 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), | 288 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), |
289 | .driver_data = LG_FF }, | 289 | .driver_data = LG_FF }, |
290 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), | 290 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), |
291 | .driver_data = LG_FF }, | 291 | .driver_data = LG_FF }, |
292 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), | 292 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), |
293 | .driver_data = LG_FF }, | 293 | .driver_data = LG_FF }, |
294 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), | 294 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), |
295 | .driver_data = LG_FF }, | 295 | .driver_data = LG_FF }, |
296 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), | 296 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), |
297 | .driver_data = LG_FF }, | 297 | .driver_data = LG_FF }, |
298 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), | 298 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), |
299 | .driver_data = LG_FF }, | 299 | .driver_data = LG_FF }, |
300 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), | 300 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), |
301 | .driver_data = LG_FF2 }, | 301 | .driver_data = LG_FF2 }, |
302 | { } | 302 | { } |
303 | }; | 303 | }; |
304 | MODULE_DEVICE_TABLE(hid, lg_devices); | 304 | MODULE_DEVICE_TABLE(hid, lg_devices); |
305 | 305 | ||
306 | static struct hid_driver lg_driver = { | 306 | static struct hid_driver lg_driver = { |
307 | .name = "logitech", | 307 | .name = "logitech", |
308 | .id_table = lg_devices, | 308 | .id_table = lg_devices, |
309 | .report_fixup = lg_report_fixup, | 309 | .report_fixup = lg_report_fixup, |
310 | .input_mapping = lg_input_mapping, | 310 | .input_mapping = lg_input_mapping, |
311 | .input_mapped = lg_input_mapped, | 311 | .input_mapped = lg_input_mapped, |
312 | .event = lg_event, | 312 | .event = lg_event, |
313 | .probe = lg_probe, | 313 | .probe = lg_probe, |
314 | }; | 314 | }; |
315 | 315 | ||
316 | static int lg_init(void) | 316 | static int lg_init(void) |
317 | { | 317 | { |
318 | return hid_register_driver(&lg_driver); | 318 | return hid_register_driver(&lg_driver); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void lg_exit(void) | 321 | static void lg_exit(void) |
322 | { | 322 | { |
323 | hid_unregister_driver(&lg_driver); | 323 | hid_unregister_driver(&lg_driver); |
324 | } | 324 | } |
325 | 325 | ||
326 | module_init(lg_init); | 326 | module_init(lg_init); |
327 | module_exit(lg_exit); | 327 | module_exit(lg_exit); |
328 | MODULE_LICENSE("GPL"); | 328 | MODULE_LICENSE("GPL"); |
329 | |||
330 | HID_COMPAT_LOAD_DRIVER(logitech); | ||
331 | 329 |
drivers/hid/hid-microsoft.c
1 | /* | 1 | /* |
2 | * HID driver for some microsoft "special" devices | 2 | * HID driver for some microsoft "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define MS_HIDINPUT 0x01 | 26 | #define MS_HIDINPUT 0x01 |
27 | #define MS_ERGONOMY 0x02 | 27 | #define MS_ERGONOMY 0x02 |
28 | #define MS_PRESENTER 0x04 | 28 | #define MS_PRESENTER 0x04 |
29 | #define MS_RDESC 0x08 | 29 | #define MS_RDESC 0x08 |
30 | #define MS_NOGET 0x10 | 30 | #define MS_NOGET 0x10 |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Microsoft Wireless Desktop Receiver (Model 1028) has | 33 | * Microsoft Wireless Desktop Receiver (Model 1028) has |
34 | * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | 34 | * 'Usage Min/Max' where it ought to have 'Physical Min/Max' |
35 | */ | 35 | */ |
36 | static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 36 | static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
37 | unsigned int rsize) | 37 | unsigned int rsize) |
38 | { | 38 | { |
39 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 39 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
40 | 40 | ||
41 | if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && | 41 | if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && |
42 | rdesc[559] == 0x29) { | 42 | rdesc[559] == 0x29) { |
43 | dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " | 43 | dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " |
44 | "Model 1028 report descriptor\n"); | 44 | "Model 1028 report descriptor\n"); |
45 | rdesc[557] = 0x35; | 45 | rdesc[557] = 0x35; |
46 | rdesc[559] = 0x45; | 46 | rdesc[559] = 0x45; |
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
50 | #define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 50 | #define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
51 | EV_KEY, (c)) | 51 | EV_KEY, (c)) |
52 | static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage, | 52 | static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage, |
53 | unsigned long **bit, int *max) | 53 | unsigned long **bit, int *max) |
54 | { | 54 | { |
55 | struct input_dev *input = hi->input; | 55 | struct input_dev *input = hi->input; |
56 | 56 | ||
57 | switch (usage->hid & HID_USAGE) { | 57 | switch (usage->hid & HID_USAGE) { |
58 | case 0xfd06: ms_map_key_clear(KEY_CHAT); break; | 58 | case 0xfd06: ms_map_key_clear(KEY_CHAT); break; |
59 | case 0xfd07: ms_map_key_clear(KEY_PHONE); break; | 59 | case 0xfd07: ms_map_key_clear(KEY_PHONE); break; |
60 | case 0xff05: | 60 | case 0xff05: |
61 | set_bit(EV_REP, input->evbit); | 61 | set_bit(EV_REP, input->evbit); |
62 | ms_map_key_clear(KEY_F13); | 62 | ms_map_key_clear(KEY_F13); |
63 | set_bit(KEY_F14, input->keybit); | 63 | set_bit(KEY_F14, input->keybit); |
64 | set_bit(KEY_F15, input->keybit); | 64 | set_bit(KEY_F15, input->keybit); |
65 | set_bit(KEY_F16, input->keybit); | 65 | set_bit(KEY_F16, input->keybit); |
66 | set_bit(KEY_F17, input->keybit); | 66 | set_bit(KEY_F17, input->keybit); |
67 | set_bit(KEY_F18, input->keybit); | 67 | set_bit(KEY_F18, input->keybit); |
68 | default: | 68 | default: |
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | return 1; | 71 | return 1; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage, | 74 | static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage, |
75 | unsigned long **bit, int *max) | 75 | unsigned long **bit, int *max) |
76 | { | 76 | { |
77 | set_bit(EV_REP, hi->input->evbit); | 77 | set_bit(EV_REP, hi->input->evbit); |
78 | switch (usage->hid & HID_USAGE) { | 78 | switch (usage->hid & HID_USAGE) { |
79 | case 0xfd08: ms_map_key_clear(KEY_FORWARD); break; | 79 | case 0xfd08: ms_map_key_clear(KEY_FORWARD); break; |
80 | case 0xfd09: ms_map_key_clear(KEY_BACK); break; | 80 | case 0xfd09: ms_map_key_clear(KEY_BACK); break; |
81 | case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE); break; | 81 | case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE); break; |
82 | case 0xfd0e: ms_map_key_clear(KEY_CLOSE); break; | 82 | case 0xfd0e: ms_map_key_clear(KEY_CLOSE); break; |
83 | case 0xfd0f: ms_map_key_clear(KEY_PLAY); break; | 83 | case 0xfd0f: ms_map_key_clear(KEY_PLAY); break; |
84 | default: | 84 | default: |
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | return 1; | 87 | return 1; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 90 | static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
91 | struct hid_field *field, struct hid_usage *usage, | 91 | struct hid_field *field, struct hid_usage *usage, |
92 | unsigned long **bit, int *max) | 92 | unsigned long **bit, int *max) |
93 | { | 93 | { |
94 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 94 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
95 | 95 | ||
96 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | 96 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) |
97 | return 0; | 97 | return 0; |
98 | 98 | ||
99 | if (quirks & MS_ERGONOMY) { | 99 | if (quirks & MS_ERGONOMY) { |
100 | int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max); | 100 | int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max); |
101 | if (ret) | 101 | if (ret) |
102 | return ret; | 102 | return ret; |
103 | } | 103 | } |
104 | 104 | ||
105 | if ((quirks & MS_PRESENTER) && | 105 | if ((quirks & MS_PRESENTER) && |
106 | ms_presenter_8k_quirk(hi, usage, bit, max)) | 106 | ms_presenter_8k_quirk(hi, usage, bit, max)) |
107 | return 1; | 107 | return 1; |
108 | 108 | ||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static int ms_event(struct hid_device *hdev, struct hid_field *field, | 112 | static int ms_event(struct hid_device *hdev, struct hid_field *field, |
113 | struct hid_usage *usage, __s32 value) | 113 | struct hid_usage *usage, __s32 value) |
114 | { | 114 | { |
115 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 115 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
116 | 116 | ||
117 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | 117 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
118 | !usage->type) | 118 | !usage->type) |
119 | return 0; | 119 | return 0; |
120 | 120 | ||
121 | /* Handling MS keyboards special buttons */ | 121 | /* Handling MS keyboards special buttons */ |
122 | if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | 122 | if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { |
123 | struct input_dev *input = field->hidinput->input; | 123 | struct input_dev *input = field->hidinput->input; |
124 | static unsigned int last_key = 0; | 124 | static unsigned int last_key = 0; |
125 | unsigned int key = 0; | 125 | unsigned int key = 0; |
126 | switch (value) { | 126 | switch (value) { |
127 | case 0x01: key = KEY_F14; break; | 127 | case 0x01: key = KEY_F14; break; |
128 | case 0x02: key = KEY_F15; break; | 128 | case 0x02: key = KEY_F15; break; |
129 | case 0x04: key = KEY_F16; break; | 129 | case 0x04: key = KEY_F16; break; |
130 | case 0x08: key = KEY_F17; break; | 130 | case 0x08: key = KEY_F17; break; |
131 | case 0x10: key = KEY_F18; break; | 131 | case 0x10: key = KEY_F18; break; |
132 | } | 132 | } |
133 | if (key) { | 133 | if (key) { |
134 | input_event(input, usage->type, key, 1); | 134 | input_event(input, usage->type, key, 1); |
135 | last_key = key; | 135 | last_key = key; |
136 | } else | 136 | } else |
137 | input_event(input, usage->type, last_key, 0); | 137 | input_event(input, usage->type, last_key, 0); |
138 | 138 | ||
139 | return 1; | 139 | return 1; |
140 | } | 140 | } |
141 | 141 | ||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) | 145 | static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) |
146 | { | 146 | { |
147 | unsigned long quirks = id->driver_data; | 147 | unsigned long quirks = id->driver_data; |
148 | int ret; | 148 | int ret; |
149 | 149 | ||
150 | hid_set_drvdata(hdev, (void *)quirks); | 150 | hid_set_drvdata(hdev, (void *)quirks); |
151 | 151 | ||
152 | if (quirks & MS_NOGET) | 152 | if (quirks & MS_NOGET) |
153 | hdev->quirks |= HID_QUIRK_NOGET; | 153 | hdev->quirks |= HID_QUIRK_NOGET; |
154 | 154 | ||
155 | ret = hid_parse(hdev); | 155 | ret = hid_parse(hdev); |
156 | if (ret) { | 156 | if (ret) { |
157 | dev_err(&hdev->dev, "parse failed\n"); | 157 | dev_err(&hdev->dev, "parse failed\n"); |
158 | goto err_free; | 158 | goto err_free; |
159 | } | 159 | } |
160 | 160 | ||
161 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? | 161 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? |
162 | HID_CONNECT_HIDINPUT_FORCE : 0)); | 162 | HID_CONNECT_HIDINPUT_FORCE : 0)); |
163 | if (ret) { | 163 | if (ret) { |
164 | dev_err(&hdev->dev, "hw start failed\n"); | 164 | dev_err(&hdev->dev, "hw start failed\n"); |
165 | goto err_free; | 165 | goto err_free; |
166 | } | 166 | } |
167 | 167 | ||
168 | return 0; | 168 | return 0; |
169 | err_free: | 169 | err_free: |
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | static const struct hid_device_id ms_devices[] = { | 173 | static const struct hid_device_id ms_devices[] = { |
174 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV), | 174 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV), |
175 | .driver_data = MS_HIDINPUT }, | 175 | .driver_data = MS_HIDINPUT }, |
176 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), | 176 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), |
177 | .driver_data = MS_ERGONOMY }, | 177 | .driver_data = MS_ERGONOMY }, |
178 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), | 178 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), |
179 | .driver_data = MS_ERGONOMY | MS_RDESC }, | 179 | .driver_data = MS_ERGONOMY | MS_RDESC }, |
180 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), | 180 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
181 | .driver_data = MS_PRESENTER }, | 181 | .driver_data = MS_PRESENTER }, |
182 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), | 182 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), |
183 | .driver_data = MS_NOGET }, | 183 | .driver_data = MS_NOGET }, |
184 | 184 | ||
185 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 185 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
186 | .driver_data = MS_PRESENTER }, | 186 | .driver_data = MS_PRESENTER }, |
187 | { } | 187 | { } |
188 | }; | 188 | }; |
189 | MODULE_DEVICE_TABLE(hid, ms_devices); | 189 | MODULE_DEVICE_TABLE(hid, ms_devices); |
190 | 190 | ||
191 | static struct hid_driver ms_driver = { | 191 | static struct hid_driver ms_driver = { |
192 | .name = "microsoft", | 192 | .name = "microsoft", |
193 | .id_table = ms_devices, | 193 | .id_table = ms_devices, |
194 | .report_fixup = ms_report_fixup, | 194 | .report_fixup = ms_report_fixup, |
195 | .input_mapping = ms_input_mapping, | 195 | .input_mapping = ms_input_mapping, |
196 | .event = ms_event, | 196 | .event = ms_event, |
197 | .probe = ms_probe, | 197 | .probe = ms_probe, |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static int ms_init(void) | 200 | static int ms_init(void) |
201 | { | 201 | { |
202 | return hid_register_driver(&ms_driver); | 202 | return hid_register_driver(&ms_driver); |
203 | } | 203 | } |
204 | 204 | ||
205 | static void ms_exit(void) | 205 | static void ms_exit(void) |
206 | { | 206 | { |
207 | hid_unregister_driver(&ms_driver); | 207 | hid_unregister_driver(&ms_driver); |
208 | } | 208 | } |
209 | 209 | ||
210 | module_init(ms_init); | 210 | module_init(ms_init); |
211 | module_exit(ms_exit); | 211 | module_exit(ms_exit); |
212 | MODULE_LICENSE("GPL"); | 212 | MODULE_LICENSE("GPL"); |
213 | |||
214 | HID_COMPAT_LOAD_DRIVER(microsoft); | ||
215 | 213 |
drivers/hid/hid-monterey.c
1 | /* | 1 | /* |
2 | * HID driver for some monterey "special" devices | 2 | * HID driver for some monterey "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 25 | static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
26 | unsigned int rsize) | 26 | unsigned int rsize) |
27 | { | 27 | { |
28 | if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | 28 | if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { |
29 | dev_info(&hdev->dev, "fixing up button/consumer in HID report " | 29 | dev_info(&hdev->dev, "fixing up button/consumer in HID report " |
30 | "descriptor\n"); | 30 | "descriptor\n"); |
31 | rdesc[30] = 0x0c; | 31 | rdesc[30] = 0x0c; |
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | #define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 35 | #define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
36 | EV_KEY, (c)) | 36 | EV_KEY, (c)) |
37 | static int mr_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 37 | static int mr_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 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 41 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
42 | return 0; | 42 | return 0; |
43 | 43 | ||
44 | switch (usage->hid & HID_USAGE) { | 44 | switch (usage->hid & HID_USAGE) { |
45 | case 0x156: mr_map_key_clear(KEY_WORDPROCESSOR); break; | 45 | case 0x156: mr_map_key_clear(KEY_WORDPROCESSOR); break; |
46 | case 0x157: mr_map_key_clear(KEY_SPREADSHEET); break; | 46 | case 0x157: mr_map_key_clear(KEY_SPREADSHEET); break; |
47 | case 0x158: mr_map_key_clear(KEY_PRESENTATION); break; | 47 | case 0x158: mr_map_key_clear(KEY_PRESENTATION); break; |
48 | case 0x15c: mr_map_key_clear(KEY_STOP); break; | 48 | case 0x15c: mr_map_key_clear(KEY_STOP); break; |
49 | default: | 49 | default: |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | return 1; | 52 | return 1; |
53 | } | 53 | } |
54 | 54 | ||
55 | static const struct hid_device_id mr_devices[] = { | 55 | static const struct hid_device_id mr_devices[] = { |
56 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 56 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
57 | { } | 57 | { } |
58 | }; | 58 | }; |
59 | MODULE_DEVICE_TABLE(hid, mr_devices); | 59 | MODULE_DEVICE_TABLE(hid, mr_devices); |
60 | 60 | ||
61 | static struct hid_driver mr_driver = { | 61 | static struct hid_driver mr_driver = { |
62 | .name = "monterey", | 62 | .name = "monterey", |
63 | .id_table = mr_devices, | 63 | .id_table = mr_devices, |
64 | .report_fixup = mr_report_fixup, | 64 | .report_fixup = mr_report_fixup, |
65 | .input_mapping = mr_input_mapping, | 65 | .input_mapping = mr_input_mapping, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static int mr_init(void) | 68 | static int mr_init(void) |
69 | { | 69 | { |
70 | return hid_register_driver(&mr_driver); | 70 | return hid_register_driver(&mr_driver); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void mr_exit(void) | 73 | static void mr_exit(void) |
74 | { | 74 | { |
75 | hid_unregister_driver(&mr_driver); | 75 | hid_unregister_driver(&mr_driver); |
76 | } | 76 | } |
77 | 77 | ||
78 | module_init(mr_init); | 78 | module_init(mr_init); |
79 | module_exit(mr_exit); | 79 | module_exit(mr_exit); |
80 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
81 | |||
82 | HID_COMPAT_LOAD_DRIVER(monterey); | ||
83 | 81 |
drivers/hid/hid-ntrig.c
1 | /* | 1 | /* |
2 | * HID driver for some ntrig "special" devices | 2 | * HID driver for some ntrig "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) 2008 Rafi Rubin | 10 | * Copyright (c) 2008 Rafi Rubin |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * This program is free software; you can redistribute it and/or modify it | 15 | * This program is free software; you can redistribute it and/or modify it |
16 | * under the terms of the GNU General Public License as published by the Free | 16 | * under the terms of the GNU General Public License as published by the Free |
17 | * Software Foundation; either version 2 of the License, or (at your option) | 17 | * Software Foundation; either version 2 of the License, or (at your option) |
18 | * any later version. | 18 | * any later version. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/hid.h> | 22 | #include <linux/hid.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | 24 | ||
25 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
26 | 26 | ||
27 | #define NTRIG_DUPLICATE_USAGES 0x001 | 27 | #define NTRIG_DUPLICATE_USAGES 0x001 |
28 | 28 | ||
29 | #define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 29 | #define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
30 | EV_KEY, (c)) | 30 | EV_KEY, (c)) |
31 | 31 | ||
32 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 32 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
33 | struct hid_field *field, struct hid_usage *usage, | 33 | struct hid_field *field, struct hid_usage *usage, |
34 | unsigned long **bit, int *max) | 34 | unsigned long **bit, int *max) |
35 | { | 35 | { |
36 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_DIGITIZER && | 36 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_DIGITIZER && |
37 | (usage->hid & 0xff) == 0x47) { | 37 | (usage->hid & 0xff) == 0x47) { |
38 | nt_map_key_clear(BTN_TOOL_DOUBLETAP); | 38 | nt_map_key_clear(BTN_TOOL_DOUBLETAP); |
39 | return 1; | 39 | return 1; |
40 | } | 40 | } |
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 44 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
45 | struct hid_field *field, struct hid_usage *usage, | 45 | struct hid_field *field, struct hid_usage *usage, |
46 | unsigned long **bit, int *max) | 46 | unsigned long **bit, int *max) |
47 | { | 47 | { |
48 | if (usage->type == EV_KEY || usage->type == EV_REL | 48 | if (usage->type == EV_KEY || usage->type == EV_REL |
49 | || usage->type == EV_ABS) | 49 | || usage->type == EV_ABS) |
50 | clear_bit(usage->code, *bit); | 50 | clear_bit(usage->code, *bit); |
51 | 51 | ||
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | static const struct hid_device_id ntrig_devices[] = { | 54 | static const struct hid_device_id ntrig_devices[] = { |
55 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), | 55 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), |
56 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 56 | .driver_data = NTRIG_DUPLICATE_USAGES }, |
57 | { } | 57 | { } |
58 | }; | 58 | }; |
59 | MODULE_DEVICE_TABLE(hid, ntrig_devices); | 59 | MODULE_DEVICE_TABLE(hid, ntrig_devices); |
60 | 60 | ||
61 | static struct hid_driver ntrig_driver = { | 61 | static struct hid_driver ntrig_driver = { |
62 | .name = "ntrig", | 62 | .name = "ntrig", |
63 | .id_table = ntrig_devices, | 63 | .id_table = ntrig_devices, |
64 | .input_mapping = ntrig_input_mapping, | 64 | .input_mapping = ntrig_input_mapping, |
65 | .input_mapped = ntrig_input_mapped, | 65 | .input_mapped = ntrig_input_mapped, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static int ntrig_init(void) | 68 | static int ntrig_init(void) |
69 | { | 69 | { |
70 | return hid_register_driver(&ntrig_driver); | 70 | return hid_register_driver(&ntrig_driver); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void ntrig_exit(void) | 73 | static void ntrig_exit(void) |
74 | { | 74 | { |
75 | hid_unregister_driver(&ntrig_driver); | 75 | hid_unregister_driver(&ntrig_driver); |
76 | } | 76 | } |
77 | 77 | ||
78 | module_init(ntrig_init); | 78 | module_init(ntrig_init); |
79 | module_exit(ntrig_exit); | 79 | module_exit(ntrig_exit); |
80 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
81 | |||
82 | HID_COMPAT_LOAD_DRIVER(ntrig); | ||
83 | 81 |
drivers/hid/hid-petalynx.c
1 | /* | 1 | /* |
2 | * HID driver for some petalynx "special" devices | 2 | * HID driver for some petalynx "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ | 25 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ |
26 | static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 26 | static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
27 | unsigned int rsize) | 27 | unsigned int rsize) |
28 | { | 28 | { |
29 | if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | 29 | if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && |
30 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && | 30 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && |
31 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { | 31 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { |
32 | dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " | 32 | dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " |
33 | "descriptor\n"); | 33 | "descriptor\n"); |
34 | rdesc[60] = 0xfa; | 34 | rdesc[60] = 0xfa; |
35 | rdesc[40] = 0xfa; | 35 | rdesc[40] = 0xfa; |
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | #define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 39 | #define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
40 | EV_KEY, (c)) | 40 | EV_KEY, (c)) |
41 | static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 41 | static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
42 | struct hid_field *field, struct hid_usage *usage, | 42 | struct hid_field *field, struct hid_usage *usage, |
43 | unsigned long **bit, int *max) | 43 | unsigned long **bit, int *max) |
44 | { | 44 | { |
45 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) { | 45 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) { |
46 | switch (usage->hid & HID_USAGE) { | 46 | switch (usage->hid & HID_USAGE) { |
47 | case 0x05a: pl_map_key_clear(KEY_TEXT); break; | 47 | case 0x05a: pl_map_key_clear(KEY_TEXT); break; |
48 | case 0x05b: pl_map_key_clear(KEY_RED); break; | 48 | case 0x05b: pl_map_key_clear(KEY_RED); break; |
49 | case 0x05c: pl_map_key_clear(KEY_GREEN); break; | 49 | case 0x05c: pl_map_key_clear(KEY_GREEN); break; |
50 | case 0x05d: pl_map_key_clear(KEY_YELLOW); break; | 50 | case 0x05d: pl_map_key_clear(KEY_YELLOW); break; |
51 | case 0x05e: pl_map_key_clear(KEY_BLUE); break; | 51 | case 0x05e: pl_map_key_clear(KEY_BLUE); break; |
52 | default: | 52 | default: |
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | return 1; | 55 | return 1; |
56 | } | 56 | } |
57 | 57 | ||
58 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { | 58 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { |
59 | switch (usage->hid & HID_USAGE) { | 59 | switch (usage->hid & HID_USAGE) { |
60 | case 0x0f6: pl_map_key_clear(KEY_NEXT); break; | 60 | case 0x0f6: pl_map_key_clear(KEY_NEXT); break; |
61 | case 0x0fa: pl_map_key_clear(KEY_BACK); break; | 61 | case 0x0fa: pl_map_key_clear(KEY_BACK); break; |
62 | default: | 62 | default: |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | return 1; | 65 | return 1; |
66 | } | 66 | } |
67 | 67 | ||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) | 71 | static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) |
72 | { | 72 | { |
73 | int ret; | 73 | int ret; |
74 | 74 | ||
75 | hdev->quirks |= HID_QUIRK_NOGET; | 75 | hdev->quirks |= HID_QUIRK_NOGET; |
76 | 76 | ||
77 | ret = hid_parse(hdev); | 77 | ret = hid_parse(hdev); |
78 | if (ret) { | 78 | if (ret) { |
79 | dev_err(&hdev->dev, "parse failed\n"); | 79 | dev_err(&hdev->dev, "parse failed\n"); |
80 | goto err_free; | 80 | goto err_free; |
81 | } | 81 | } |
82 | 82 | ||
83 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 83 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
84 | if (ret) { | 84 | if (ret) { |
85 | dev_err(&hdev->dev, "hw start failed\n"); | 85 | dev_err(&hdev->dev, "hw start failed\n"); |
86 | goto err_free; | 86 | goto err_free; |
87 | } | 87 | } |
88 | 88 | ||
89 | return 0; | 89 | return 0; |
90 | err_free: | 90 | err_free: |
91 | return ret; | 91 | return ret; |
92 | } | 92 | } |
93 | 93 | ||
94 | static const struct hid_device_id pl_devices[] = { | 94 | static const struct hid_device_id pl_devices[] = { |
95 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 95 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
96 | { } | 96 | { } |
97 | }; | 97 | }; |
98 | MODULE_DEVICE_TABLE(hid, pl_devices); | 98 | MODULE_DEVICE_TABLE(hid, pl_devices); |
99 | 99 | ||
100 | static struct hid_driver pl_driver = { | 100 | static struct hid_driver pl_driver = { |
101 | .name = "petalynx", | 101 | .name = "petalynx", |
102 | .id_table = pl_devices, | 102 | .id_table = pl_devices, |
103 | .report_fixup = pl_report_fixup, | 103 | .report_fixup = pl_report_fixup, |
104 | .input_mapping = pl_input_mapping, | 104 | .input_mapping = pl_input_mapping, |
105 | .probe = pl_probe, | 105 | .probe = pl_probe, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static int pl_init(void) | 108 | static int pl_init(void) |
109 | { | 109 | { |
110 | return hid_register_driver(&pl_driver); | 110 | return hid_register_driver(&pl_driver); |
111 | } | 111 | } |
112 | 112 | ||
113 | static void pl_exit(void) | 113 | static void pl_exit(void) |
114 | { | 114 | { |
115 | hid_unregister_driver(&pl_driver); | 115 | hid_unregister_driver(&pl_driver); |
116 | } | 116 | } |
117 | 117 | ||
118 | module_init(pl_init); | 118 | module_init(pl_init); |
119 | module_exit(pl_exit); | 119 | module_exit(pl_exit); |
120 | MODULE_LICENSE("GPL"); | 120 | MODULE_LICENSE("GPL"); |
121 | |||
122 | HID_COMPAT_LOAD_DRIVER(petalynx); | ||
123 | 121 |
drivers/hid/hid-pl.c
1 | /* | 1 | /* |
2 | * Force feedback support for PantherLord/GreenAsia based devices | 2 | * Force feedback support for PantherLord/GreenAsia based devices |
3 | * | 3 | * |
4 | * The devices are distributed under various names and the same USB device ID | 4 | * The devices are distributed under various names and the same USB device ID |
5 | * can be used in both adapters and actual game controllers. | 5 | * can be used in both adapters and actual game controllers. |
6 | * | 6 | * |
7 | * 0810:0001 "Twin USB Joystick" | 7 | * 0810:0001 "Twin USB Joystick" |
8 | * - tested with PantherLord USB/PS2 2in1 Adapter | 8 | * - tested with PantherLord USB/PS2 2in1 Adapter |
9 | * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT) | 9 | * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT) |
10 | * | 10 | * |
11 | * 0e8f:0003 "GreenAsia Inc. USB Joystick " | 11 | * 0e8f:0003 "GreenAsia Inc. USB Joystick " |
12 | * - tested with Kรถnig Gaming gamepad | 12 | * - tested with Kรถnig Gaming gamepad |
13 | * | 13 | * |
14 | * 0e8f:0003 "GASIA USB Gamepad" | 14 | * 0e8f:0003 "GASIA USB Gamepad" |
15 | * - another version of the Kรถnig gamepad | 15 | * - another version of the Kรถnig gamepad |
16 | * | 16 | * |
17 | * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com> | 17 | * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com> |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * This program is free software; you can redistribute it and/or modify | 21 | * This program is free software; you can redistribute it and/or modify |
22 | * it under the terms of the GNU General Public License as published by | 22 | * it under the terms of the GNU General Public License as published by |
23 | * the Free Software Foundation; either version 2 of the License, or | 23 | * the Free Software Foundation; either version 2 of the License, or |
24 | * (at your option) any later version. | 24 | * (at your option) any later version. |
25 | * | 25 | * |
26 | * This program is distributed in the hope that it will be useful, | 26 | * This program is distributed in the hope that it will be useful, |
27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 | * GNU General Public License for more details. | 29 | * GNU General Public License for more details. |
30 | * | 30 | * |
31 | * You should have received a copy of the GNU General Public License | 31 | * You should have received a copy of the GNU General Public License |
32 | * along with this program; if not, write to the Free Software | 32 | * along with this program; if not, write to the Free Software |
33 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 33 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
34 | */ | 34 | */ |
35 | 35 | ||
36 | 36 | ||
37 | /* #define DEBUG */ | 37 | /* #define DEBUG */ |
38 | 38 | ||
39 | #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg) | 39 | #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg) |
40 | 40 | ||
41 | #include <linux/input.h> | 41 | #include <linux/input.h> |
42 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
43 | #include <linux/hid.h> | 43 | #include <linux/hid.h> |
44 | 44 | ||
45 | #include "hid-ids.h" | 45 | #include "hid-ids.h" |
46 | 46 | ||
47 | #ifdef CONFIG_PANTHERLORD_FF | 47 | #ifdef CONFIG_PANTHERLORD_FF |
48 | #include "usbhid/usbhid.h" | 48 | #include "usbhid/usbhid.h" |
49 | 49 | ||
50 | struct plff_device { | 50 | struct plff_device { |
51 | struct hid_report *report; | 51 | struct hid_report *report; |
52 | s32 *strong; | 52 | s32 *strong; |
53 | s32 *weak; | 53 | s32 *weak; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static int hid_plff_play(struct input_dev *dev, void *data, | 56 | static int hid_plff_play(struct input_dev *dev, void *data, |
57 | struct ff_effect *effect) | 57 | struct ff_effect *effect) |
58 | { | 58 | { |
59 | struct hid_device *hid = input_get_drvdata(dev); | 59 | struct hid_device *hid = input_get_drvdata(dev); |
60 | struct plff_device *plff = data; | 60 | struct plff_device *plff = data; |
61 | int left, right; | 61 | int left, right; |
62 | 62 | ||
63 | left = effect->u.rumble.strong_magnitude; | 63 | left = effect->u.rumble.strong_magnitude; |
64 | right = effect->u.rumble.weak_magnitude; | 64 | right = effect->u.rumble.weak_magnitude; |
65 | debug("called with 0x%04x 0x%04x", left, right); | 65 | debug("called with 0x%04x 0x%04x", left, right); |
66 | 66 | ||
67 | left = left * 0x7f / 0xffff; | 67 | left = left * 0x7f / 0xffff; |
68 | right = right * 0x7f / 0xffff; | 68 | right = right * 0x7f / 0xffff; |
69 | 69 | ||
70 | *plff->strong = left; | 70 | *plff->strong = left; |
71 | *plff->weak = right; | 71 | *plff->weak = right; |
72 | debug("running with 0x%02x 0x%02x", left, right); | 72 | debug("running with 0x%02x 0x%02x", left, right); |
73 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 73 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); |
74 | 74 | ||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int plff_init(struct hid_device *hid) | 78 | static int plff_init(struct hid_device *hid) |
79 | { | 79 | { |
80 | struct plff_device *plff; | 80 | struct plff_device *plff; |
81 | struct hid_report *report; | 81 | struct hid_report *report; |
82 | struct hid_input *hidinput; | 82 | struct hid_input *hidinput; |
83 | struct list_head *report_list = | 83 | struct list_head *report_list = |
84 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 84 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
85 | struct list_head *report_ptr = report_list; | 85 | struct list_head *report_ptr = report_list; |
86 | struct input_dev *dev; | 86 | struct input_dev *dev; |
87 | int error; | 87 | int error; |
88 | s32 *strong; | 88 | s32 *strong; |
89 | s32 *weak; | 89 | s32 *weak; |
90 | 90 | ||
91 | /* The device contains one output report per physical device, all | 91 | /* The device contains one output report per physical device, all |
92 | containing 1 field, which contains 4 ff00.0002 usages and 4 16bit | 92 | containing 1 field, which contains 4 ff00.0002 usages and 4 16bit |
93 | absolute values. | 93 | absolute values. |
94 | 94 | ||
95 | The input reports also contain a field which contains | 95 | The input reports also contain a field which contains |
96 | 8 ff00.0001 usages and 8 boolean values. Their meaning is | 96 | 8 ff00.0001 usages and 8 boolean values. Their meaning is |
97 | currently unknown. | 97 | currently unknown. |
98 | 98 | ||
99 | A version of the 0e8f:0003 exists that has all the values in | 99 | A version of the 0e8f:0003 exists that has all the values in |
100 | separate fields and misses the extra input field, thus resembling | 100 | separate fields and misses the extra input field, thus resembling |
101 | Zeroplus (hid-zpff) devices. | 101 | Zeroplus (hid-zpff) devices. |
102 | */ | 102 | */ |
103 | 103 | ||
104 | if (list_empty(report_list)) { | 104 | if (list_empty(report_list)) { |
105 | dev_err(&hid->dev, "no output reports found\n"); | 105 | dev_err(&hid->dev, "no output reports found\n"); |
106 | return -ENODEV; | 106 | return -ENODEV; |
107 | } | 107 | } |
108 | 108 | ||
109 | list_for_each_entry(hidinput, &hid->inputs, list) { | 109 | list_for_each_entry(hidinput, &hid->inputs, list) { |
110 | 110 | ||
111 | report_ptr = report_ptr->next; | 111 | report_ptr = report_ptr->next; |
112 | 112 | ||
113 | if (report_ptr == report_list) { | 113 | if (report_ptr == report_list) { |
114 | dev_err(&hid->dev, "required output report is " | 114 | dev_err(&hid->dev, "required output report is " |
115 | "missing\n"); | 115 | "missing\n"); |
116 | return -ENODEV; | 116 | return -ENODEV; |
117 | } | 117 | } |
118 | 118 | ||
119 | report = list_entry(report_ptr, struct hid_report, list); | 119 | report = list_entry(report_ptr, struct hid_report, list); |
120 | if (report->maxfield < 1) { | 120 | if (report->maxfield < 1) { |
121 | dev_err(&hid->dev, "no fields in the report\n"); | 121 | dev_err(&hid->dev, "no fields in the report\n"); |
122 | return -ENODEV; | 122 | return -ENODEV; |
123 | } | 123 | } |
124 | 124 | ||
125 | if (report->field[0]->report_count >= 4) { | 125 | if (report->field[0]->report_count >= 4) { |
126 | report->field[0]->value[0] = 0x00; | 126 | report->field[0]->value[0] = 0x00; |
127 | report->field[0]->value[1] = 0x00; | 127 | report->field[0]->value[1] = 0x00; |
128 | strong = &report->field[0]->value[2]; | 128 | strong = &report->field[0]->value[2]; |
129 | weak = &report->field[0]->value[3]; | 129 | weak = &report->field[0]->value[3]; |
130 | debug("detected single-field device"); | 130 | debug("detected single-field device"); |
131 | } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && | 131 | } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && |
132 | report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { | 132 | report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { |
133 | report->field[0]->value[0] = 0x00; | 133 | report->field[0]->value[0] = 0x00; |
134 | report->field[1]->value[0] = 0x00; | 134 | report->field[1]->value[0] = 0x00; |
135 | strong = &report->field[2]->value[0]; | 135 | strong = &report->field[2]->value[0]; |
136 | weak = &report->field[3]->value[0]; | 136 | weak = &report->field[3]->value[0]; |
137 | debug("detected 4-field device"); | 137 | debug("detected 4-field device"); |
138 | } else { | 138 | } else { |
139 | dev_err(&hid->dev, "not enough fields or values\n"); | 139 | dev_err(&hid->dev, "not enough fields or values\n"); |
140 | return -ENODEV; | 140 | return -ENODEV; |
141 | } | 141 | } |
142 | 142 | ||
143 | plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL); | 143 | plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL); |
144 | if (!plff) | 144 | if (!plff) |
145 | return -ENOMEM; | 145 | return -ENOMEM; |
146 | 146 | ||
147 | dev = hidinput->input; | 147 | dev = hidinput->input; |
148 | 148 | ||
149 | set_bit(FF_RUMBLE, dev->ffbit); | 149 | set_bit(FF_RUMBLE, dev->ffbit); |
150 | 150 | ||
151 | error = input_ff_create_memless(dev, plff, hid_plff_play); | 151 | error = input_ff_create_memless(dev, plff, hid_plff_play); |
152 | if (error) { | 152 | if (error) { |
153 | kfree(plff); | 153 | kfree(plff); |
154 | return error; | 154 | return error; |
155 | } | 155 | } |
156 | 156 | ||
157 | plff->report = report; | 157 | plff->report = report; |
158 | plff->strong = strong; | 158 | plff->strong = strong; |
159 | plff->weak = weak; | 159 | plff->weak = weak; |
160 | 160 | ||
161 | *strong = 0x00; | 161 | *strong = 0x00; |
162 | *weak = 0x00; | 162 | *weak = 0x00; |
163 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 163 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); |
164 | } | 164 | } |
165 | 165 | ||
166 | dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia " | 166 | dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia " |
167 | "devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); | 167 | "devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); |
168 | 168 | ||
169 | return 0; | 169 | return 0; |
170 | } | 170 | } |
171 | #else | 171 | #else |
172 | static inline int plff_init(struct hid_device *hid) | 172 | static inline int plff_init(struct hid_device *hid) |
173 | { | 173 | { |
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) | 178 | static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) |
179 | { | 179 | { |
180 | int ret; | 180 | int ret; |
181 | 181 | ||
182 | if (id->driver_data) | 182 | if (id->driver_data) |
183 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | 183 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; |
184 | 184 | ||
185 | ret = hid_parse(hdev); | 185 | ret = hid_parse(hdev); |
186 | if (ret) { | 186 | if (ret) { |
187 | dev_err(&hdev->dev, "parse failed\n"); | 187 | dev_err(&hdev->dev, "parse failed\n"); |
188 | goto err; | 188 | goto err; |
189 | } | 189 | } |
190 | 190 | ||
191 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 191 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
192 | if (ret) { | 192 | if (ret) { |
193 | dev_err(&hdev->dev, "hw start failed\n"); | 193 | dev_err(&hdev->dev, "hw start failed\n"); |
194 | goto err; | 194 | goto err; |
195 | } | 195 | } |
196 | 196 | ||
197 | plff_init(hdev); | 197 | plff_init(hdev); |
198 | 198 | ||
199 | return 0; | 199 | return 0; |
200 | err: | 200 | err: |
201 | return ret; | 201 | return ret; |
202 | } | 202 | } |
203 | 203 | ||
204 | static const struct hid_device_id pl_devices[] = { | 204 | static const struct hid_device_id pl_devices[] = { |
205 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR), | 205 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR), |
206 | .driver_data = 1 }, /* Twin USB Joystick */ | 206 | .driver_data = 1 }, /* Twin USB Joystick */ |
207 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), | 207 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), |
208 | .driver_data = 1 }, /* Twin USB Joystick */ | 208 | .driver_data = 1 }, /* Twin USB Joystick */ |
209 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, | 209 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, |
210 | { } | 210 | { } |
211 | }; | 211 | }; |
212 | MODULE_DEVICE_TABLE(hid, pl_devices); | 212 | MODULE_DEVICE_TABLE(hid, pl_devices); |
213 | 213 | ||
214 | static struct hid_driver pl_driver = { | 214 | static struct hid_driver pl_driver = { |
215 | .name = "pantherlord", | 215 | .name = "pantherlord", |
216 | .id_table = pl_devices, | 216 | .id_table = pl_devices, |
217 | .probe = pl_probe, | 217 | .probe = pl_probe, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | static int pl_init(void) | 220 | static int pl_init(void) |
221 | { | 221 | { |
222 | return hid_register_driver(&pl_driver); | 222 | return hid_register_driver(&pl_driver); |
223 | } | 223 | } |
224 | 224 | ||
225 | static void pl_exit(void) | 225 | static void pl_exit(void) |
226 | { | 226 | { |
227 | hid_unregister_driver(&pl_driver); | 227 | hid_unregister_driver(&pl_driver); |
228 | } | 228 | } |
229 | 229 | ||
230 | module_init(pl_init); | 230 | module_init(pl_init); |
231 | module_exit(pl_exit); | 231 | module_exit(pl_exit); |
232 | MODULE_LICENSE("GPL"); | 232 | MODULE_LICENSE("GPL"); |
233 | |||
234 | HID_COMPAT_LOAD_DRIVER(pantherlord); | ||
235 | 233 |
drivers/hid/hid-samsung.c
1 | /* | 1 | /* |
2 | * HID driver for some samsung "special" devices | 2 | * HID driver for some samsung "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Samsung IrDA remote controller (reports as Cypress USB Mouse). | 26 | * Samsung IrDA remote controller (reports as Cypress USB Mouse). |
27 | * | 27 | * |
28 | * Vendor specific report #4 has a size of 48 bit, | 28 | * Vendor specific report #4 has a size of 48 bit, |
29 | * and therefore is not accepted when inspecting the descriptors. | 29 | * and therefore is not accepted when inspecting the descriptors. |
30 | * As a workaround we reinterpret the report as: | 30 | * As a workaround we reinterpret the report as: |
31 | * Variable type, count 6, size 8 bit, log. maximum 255 | 31 | * Variable type, count 6, size 8 bit, log. maximum 255 |
32 | * The burden to reconstruct the data is moved into user space. | 32 | * The burden to reconstruct the data is moved into user space. |
33 | */ | 33 | */ |
34 | static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 34 | static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
35 | unsigned int rsize) | 35 | unsigned int rsize) |
36 | { | 36 | { |
37 | if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && | 37 | if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && |
38 | rdesc[177] == 0x75 && rdesc[178] == 0x30 && | 38 | rdesc[177] == 0x75 && rdesc[178] == 0x30 && |
39 | rdesc[179] == 0x95 && rdesc[180] == 0x01 && | 39 | rdesc[179] == 0x95 && rdesc[180] == 0x01 && |
40 | rdesc[182] == 0x40) { | 40 | rdesc[182] == 0x40) { |
41 | dev_info(&hdev->dev, "fixing up Samsung IrDA report " | 41 | dev_info(&hdev->dev, "fixing up Samsung IrDA report " |
42 | "descriptor\n"); | 42 | "descriptor\n"); |
43 | rdesc[176] = 0xff; | 43 | rdesc[176] = 0xff; |
44 | rdesc[178] = 0x08; | 44 | rdesc[178] = 0x08; |
45 | rdesc[180] = 0x06; | 45 | rdesc[180] = 0x06; |
46 | rdesc[182] = 0x42; | 46 | rdesc[182] = 0x42; |
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
50 | static int samsung_probe(struct hid_device *hdev, | 50 | static int samsung_probe(struct hid_device *hdev, |
51 | const struct hid_device_id *id) | 51 | const struct hid_device_id *id) |
52 | { | 52 | { |
53 | int ret; | 53 | int ret; |
54 | 54 | ||
55 | ret = hid_parse(hdev); | 55 | ret = hid_parse(hdev); |
56 | if (ret) { | 56 | if (ret) { |
57 | dev_err(&hdev->dev, "parse failed\n"); | 57 | dev_err(&hdev->dev, "parse failed\n"); |
58 | goto err_free; | 58 | goto err_free; |
59 | } | 59 | } |
60 | 60 | ||
61 | ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) | | 61 | ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) | |
62 | HID_CONNECT_HIDDEV_FORCE); | 62 | HID_CONNECT_HIDDEV_FORCE); |
63 | if (ret) { | 63 | if (ret) { |
64 | dev_err(&hdev->dev, "hw start failed\n"); | 64 | dev_err(&hdev->dev, "hw start failed\n"); |
65 | goto err_free; | 65 | goto err_free; |
66 | } | 66 | } |
67 | 67 | ||
68 | return 0; | 68 | return 0; |
69 | err_free: | 69 | err_free: |
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
72 | 72 | ||
73 | static const struct hid_device_id samsung_devices[] = { | 73 | static const struct hid_device_id samsung_devices[] = { |
74 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 74 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
75 | { } | 75 | { } |
76 | }; | 76 | }; |
77 | MODULE_DEVICE_TABLE(hid, samsung_devices); | 77 | MODULE_DEVICE_TABLE(hid, samsung_devices); |
78 | 78 | ||
79 | static struct hid_driver samsung_driver = { | 79 | static struct hid_driver samsung_driver = { |
80 | .name = "samsung", | 80 | .name = "samsung", |
81 | .id_table = samsung_devices, | 81 | .id_table = samsung_devices, |
82 | .report_fixup = samsung_report_fixup, | 82 | .report_fixup = samsung_report_fixup, |
83 | .probe = samsung_probe, | 83 | .probe = samsung_probe, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static int samsung_init(void) | 86 | static int samsung_init(void) |
87 | { | 87 | { |
88 | return hid_register_driver(&samsung_driver); | 88 | return hid_register_driver(&samsung_driver); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void samsung_exit(void) | 91 | static void samsung_exit(void) |
92 | { | 92 | { |
93 | hid_unregister_driver(&samsung_driver); | 93 | hid_unregister_driver(&samsung_driver); |
94 | } | 94 | } |
95 | 95 | ||
96 | module_init(samsung_init); | 96 | module_init(samsung_init); |
97 | module_exit(samsung_exit); | 97 | module_exit(samsung_exit); |
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
99 | |||
100 | HID_COMPAT_LOAD_DRIVER(samsung); | ||
101 | 99 |
drivers/hid/hid-sony.c
1 | /* | 1 | /* |
2 | * HID driver for some sony "special" devices | 2 | * HID driver for some sony "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) 2007 Paul Walmsley | 7 | * Copyright (c) 2007 Paul Walmsley |
8 | * Copyright (c) 2008 Jiri Slaby | 8 | * Copyright (c) 2008 Jiri Slaby |
9 | * Copyright (c) 2006-2008 Jiri Kosina | 9 | * Copyright (c) 2006-2008 Jiri Kosina |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
23 | 23 | ||
24 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
25 | 25 | ||
26 | #define VAIO_RDESC_CONSTANT 0x0001 | 26 | #define VAIO_RDESC_CONSTANT 0x0001 |
27 | 27 | ||
28 | struct sony_sc { | 28 | struct sony_sc { |
29 | unsigned long quirks; | 29 | unsigned long quirks; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ | 32 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ |
33 | static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 33 | static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
34 | unsigned int rsize) | 34 | unsigned int rsize) |
35 | { | 35 | { |
36 | struct sony_sc *sc = hid_get_drvdata(hdev); | 36 | struct sony_sc *sc = hid_get_drvdata(hdev); |
37 | 37 | ||
38 | if ((sc->quirks & VAIO_RDESC_CONSTANT) && | 38 | if ((sc->quirks & VAIO_RDESC_CONSTANT) && |
39 | rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { | 39 | rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { |
40 | dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " | 40 | dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " |
41 | "descriptor\n"); | 41 | "descriptor\n"); |
42 | rdesc[55] = 0x06; | 42 | rdesc[55] = 0x06; |
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | 47 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller |
48 | * to "operational". Without this, the ps3 controller will not report any | 48 | * to "operational". Without this, the ps3 controller will not report any |
49 | * events. | 49 | * events. |
50 | */ | 50 | */ |
51 | static int sony_set_operational(struct hid_device *hdev) | 51 | static int sony_set_operational(struct hid_device *hdev) |
52 | { | 52 | { |
53 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 53 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
54 | struct usb_device *dev = interface_to_usbdev(intf); | 54 | struct usb_device *dev = interface_to_usbdev(intf); |
55 | __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 55 | __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; |
56 | int ret; | 56 | int ret; |
57 | char *buf = kmalloc(18, GFP_KERNEL); | 57 | char *buf = kmalloc(18, GFP_KERNEL); |
58 | 58 | ||
59 | if (!buf) | 59 | if (!buf) |
60 | return -ENOMEM; | 60 | return -ENOMEM; |
61 | 61 | ||
62 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 62 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
63 | HID_REQ_GET_REPORT, | 63 | HID_REQ_GET_REPORT, |
64 | USB_DIR_IN | USB_TYPE_CLASS | | 64 | USB_DIR_IN | USB_TYPE_CLASS | |
65 | USB_RECIP_INTERFACE, | 65 | USB_RECIP_INTERFACE, |
66 | (3 << 8) | 0xf2, ifnum, buf, 17, | 66 | (3 << 8) | 0xf2, ifnum, buf, 17, |
67 | USB_CTRL_GET_TIMEOUT); | 67 | USB_CTRL_GET_TIMEOUT); |
68 | if (ret < 0) | 68 | if (ret < 0) |
69 | dev_err(&hdev->dev, "can't set operational mode\n"); | 69 | dev_err(&hdev->dev, "can't set operational mode\n"); |
70 | 70 | ||
71 | kfree(buf); | 71 | kfree(buf); |
72 | 72 | ||
73 | return ret; | 73 | return ret; |
74 | } | 74 | } |
75 | 75 | ||
76 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | 76 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) |
77 | { | 77 | { |
78 | int ret; | 78 | int ret; |
79 | unsigned long quirks = id->driver_data; | 79 | unsigned long quirks = id->driver_data; |
80 | struct sony_sc *sc; | 80 | struct sony_sc *sc; |
81 | 81 | ||
82 | sc = kzalloc(sizeof(*sc), GFP_KERNEL); | 82 | sc = kzalloc(sizeof(*sc), GFP_KERNEL); |
83 | if (sc == NULL) { | 83 | if (sc == NULL) { |
84 | dev_err(&hdev->dev, "can't alloc apple descriptor\n"); | 84 | dev_err(&hdev->dev, "can't alloc apple descriptor\n"); |
85 | return -ENOMEM; | 85 | return -ENOMEM; |
86 | } | 86 | } |
87 | 87 | ||
88 | sc->quirks = quirks; | 88 | sc->quirks = quirks; |
89 | hid_set_drvdata(hdev, sc); | 89 | hid_set_drvdata(hdev, sc); |
90 | 90 | ||
91 | ret = hid_parse(hdev); | 91 | ret = hid_parse(hdev); |
92 | if (ret) { | 92 | if (ret) { |
93 | dev_err(&hdev->dev, "parse failed\n"); | 93 | dev_err(&hdev->dev, "parse failed\n"); |
94 | goto err_free; | 94 | goto err_free; |
95 | } | 95 | } |
96 | 96 | ||
97 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | | 97 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | |
98 | HID_CONNECT_HIDDEV_FORCE); | 98 | HID_CONNECT_HIDDEV_FORCE); |
99 | if (ret) { | 99 | if (ret) { |
100 | dev_err(&hdev->dev, "hw start failed\n"); | 100 | dev_err(&hdev->dev, "hw start failed\n"); |
101 | goto err_free; | 101 | goto err_free; |
102 | } | 102 | } |
103 | 103 | ||
104 | ret = sony_set_operational(hdev); | 104 | ret = sony_set_operational(hdev); |
105 | if (ret < 0) | 105 | if (ret < 0) |
106 | goto err_stop; | 106 | goto err_stop; |
107 | 107 | ||
108 | return 0; | 108 | return 0; |
109 | err_stop: | 109 | err_stop: |
110 | hid_hw_stop(hdev); | 110 | hid_hw_stop(hdev); |
111 | err_free: | 111 | err_free: |
112 | kfree(sc); | 112 | kfree(sc); |
113 | return ret; | 113 | return ret; |
114 | } | 114 | } |
115 | 115 | ||
116 | static void sony_remove(struct hid_device *hdev) | 116 | static void sony_remove(struct hid_device *hdev) |
117 | { | 117 | { |
118 | hid_hw_stop(hdev); | 118 | hid_hw_stop(hdev); |
119 | kfree(hid_get_drvdata(hdev)); | 119 | kfree(hid_get_drvdata(hdev)); |
120 | } | 120 | } |
121 | 121 | ||
122 | static const struct hid_device_id sony_devices[] = { | 122 | static const struct hid_device_id sony_devices[] = { |
123 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 123 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
124 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), | 124 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), |
125 | .driver_data = VAIO_RDESC_CONSTANT }, | 125 | .driver_data = VAIO_RDESC_CONSTANT }, |
126 | { } | 126 | { } |
127 | }; | 127 | }; |
128 | MODULE_DEVICE_TABLE(hid, sony_devices); | 128 | MODULE_DEVICE_TABLE(hid, sony_devices); |
129 | 129 | ||
130 | static struct hid_driver sony_driver = { | 130 | static struct hid_driver sony_driver = { |
131 | .name = "sony", | 131 | .name = "sony", |
132 | .id_table = sony_devices, | 132 | .id_table = sony_devices, |
133 | .probe = sony_probe, | 133 | .probe = sony_probe, |
134 | .remove = sony_remove, | 134 | .remove = sony_remove, |
135 | .report_fixup = sony_report_fixup, | 135 | .report_fixup = sony_report_fixup, |
136 | }; | 136 | }; |
137 | 137 | ||
138 | static int sony_init(void) | 138 | static int sony_init(void) |
139 | { | 139 | { |
140 | return hid_register_driver(&sony_driver); | 140 | return hid_register_driver(&sony_driver); |
141 | } | 141 | } |
142 | 142 | ||
143 | static void sony_exit(void) | 143 | static void sony_exit(void) |
144 | { | 144 | { |
145 | hid_unregister_driver(&sony_driver); | 145 | hid_unregister_driver(&sony_driver); |
146 | } | 146 | } |
147 | 147 | ||
148 | module_init(sony_init); | 148 | module_init(sony_init); |
149 | module_exit(sony_exit); | 149 | module_exit(sony_exit); |
150 | MODULE_LICENSE("GPL"); | 150 | MODULE_LICENSE("GPL"); |
151 | |||
152 | HID_COMPAT_LOAD_DRIVER(sony); | ||
153 | 151 |
drivers/hid/hid-sunplus.c
1 | /* | 1 | /* |
2 | * HID driver for some sunplus "special" devices | 2 | * HID driver for some sunplus "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 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * 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 | 14 | * 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) | 15 | * Software Foundation; either version 2 of the License, or (at your option) |
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
24 | 24 | ||
25 | static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 25 | static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
26 | unsigned int rsize) | 26 | unsigned int rsize) |
27 | { | 27 | { |
28 | if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | 28 | if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && |
29 | rdesc[106] == 0x03) { | 29 | rdesc[106] == 0x03) { |
30 | dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " | 30 | dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " |
31 | "report descriptor\n"); | 31 | "report descriptor\n"); |
32 | rdesc[105] = rdesc[110] = 0x03; | 32 | rdesc[105] = rdesc[110] = 0x03; |
33 | rdesc[106] = rdesc[111] = 0x21; | 33 | rdesc[106] = rdesc[111] = 0x21; |
34 | } | 34 | } |
35 | } | 35 | } |
36 | 36 | ||
37 | #define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 37 | #define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
38 | EV_KEY, (c)) | 38 | EV_KEY, (c)) |
39 | static int sp_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 39 | static int sp_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
40 | struct hid_field *field, struct hid_usage *usage, | 40 | struct hid_field *field, struct hid_usage *usage, |
41 | unsigned long **bit, int *max) | 41 | unsigned long **bit, int *max) |
42 | { | 42 | { |
43 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | 43 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) |
44 | return 0; | 44 | return 0; |
45 | 45 | ||
46 | switch (usage->hid & HID_USAGE) { | 46 | switch (usage->hid & HID_USAGE) { |
47 | case 0x2003: sp_map_key_clear(KEY_ZOOMIN); break; | 47 | case 0x2003: sp_map_key_clear(KEY_ZOOMIN); break; |
48 | case 0x2103: sp_map_key_clear(KEY_ZOOMOUT); break; | 48 | case 0x2103: sp_map_key_clear(KEY_ZOOMOUT); break; |
49 | default: | 49 | default: |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | return 1; | 52 | return 1; |
53 | } | 53 | } |
54 | 54 | ||
55 | static const struct hid_device_id sp_devices[] = { | 55 | static const struct hid_device_id sp_devices[] = { |
56 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 56 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
57 | { } | 57 | { } |
58 | }; | 58 | }; |
59 | MODULE_DEVICE_TABLE(hid, sp_devices); | 59 | MODULE_DEVICE_TABLE(hid, sp_devices); |
60 | 60 | ||
61 | static struct hid_driver sp_driver = { | 61 | static struct hid_driver sp_driver = { |
62 | .name = "sunplus", | 62 | .name = "sunplus", |
63 | .id_table = sp_devices, | 63 | .id_table = sp_devices, |
64 | .report_fixup = sp_report_fixup, | 64 | .report_fixup = sp_report_fixup, |
65 | .input_mapping = sp_input_mapping, | 65 | .input_mapping = sp_input_mapping, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static int sp_init(void) | 68 | static int sp_init(void) |
69 | { | 69 | { |
70 | return hid_register_driver(&sp_driver); | 70 | return hid_register_driver(&sp_driver); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void sp_exit(void) | 73 | static void sp_exit(void) |
74 | { | 74 | { |
75 | hid_unregister_driver(&sp_driver); | 75 | hid_unregister_driver(&sp_driver); |
76 | } | 76 | } |
77 | 77 | ||
78 | module_init(sp_init); | 78 | module_init(sp_init); |
79 | module_exit(sp_exit); | 79 | module_exit(sp_exit); |
80 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
81 | |||
82 | HID_COMPAT_LOAD_DRIVER(sunplus); | ||
83 | 81 |
drivers/hid/hid-tmff.c
1 | /* | 1 | /* |
2 | * Force feedback support for various HID compliant devices by ThrustMaster: | 2 | * Force feedback support for various HID compliant devices by ThrustMaster: |
3 | * ThrustMaster FireStorm Dual Power 2 | 3 | * ThrustMaster FireStorm Dual Power 2 |
4 | * and possibly others whose device ids haven't been added. | 4 | * and possibly others whose device ids haven't been added. |
5 | * | 5 | * |
6 | * Modified to support ThrustMaster devices by Zinx Verituse | 6 | * Modified to support ThrustMaster devices by Zinx Verituse |
7 | * on 2003-01-25 from the Logitech force feedback driver, | 7 | * on 2003-01-25 from the Logitech force feedback driver, |
8 | * which is by Johann Deneux. | 8 | * which is by Johann Deneux. |
9 | * | 9 | * |
10 | * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org> | 10 | * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org> |
11 | * Copyright (c) 2002 Johann Deneux | 11 | * Copyright (c) 2002 Johann Deneux |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
17 | * the Free Software Foundation; either version 2 of the License, or | 17 | * the Free Software Foundation; either version 2 of the License, or |
18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
19 | * | 19 | * |
20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
24 | * | 24 | * |
25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
26 | * along with this program; if not, write to the Free Software | 26 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/hid.h> | 30 | #include <linux/hid.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
33 | 33 | ||
34 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
35 | 35 | ||
36 | #include "usbhid/usbhid.h" | 36 | #include "usbhid/usbhid.h" |
37 | 37 | ||
38 | /* Usages for thrustmaster devices I know about */ | 38 | /* Usages for thrustmaster devices I know about */ |
39 | #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) | 39 | #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) |
40 | 40 | ||
41 | static const signed short ff_rumble[] = { | 41 | static const signed short ff_rumble[] = { |
42 | FF_RUMBLE, | 42 | FF_RUMBLE, |
43 | -1 | 43 | -1 |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static const signed short ff_joystick[] = { | 46 | static const signed short ff_joystick[] = { |
47 | FF_CONSTANT, | 47 | FF_CONSTANT, |
48 | -1 | 48 | -1 |
49 | }; | 49 | }; |
50 | 50 | ||
51 | struct tmff_device { | 51 | struct tmff_device { |
52 | struct hid_report *report; | 52 | struct hid_report *report; |
53 | struct hid_field *ff_field; | 53 | struct hid_field *ff_field; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | /* Changes values from 0 to 0xffff into values from minimum to maximum */ | 56 | /* Changes values from 0 to 0xffff into values from minimum to maximum */ |
57 | static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) | 57 | static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) |
58 | { | 58 | { |
59 | int ret; | 59 | int ret; |
60 | 60 | ||
61 | ret = (in * (maximum - minimum) / 0xffff) + minimum; | 61 | ret = (in * (maximum - minimum) / 0xffff) + minimum; |
62 | if (ret < minimum) | 62 | if (ret < minimum) |
63 | return minimum; | 63 | return minimum; |
64 | if (ret > maximum) | 64 | if (ret > maximum) |
65 | return maximum; | 65 | return maximum; |
66 | return ret; | 66 | return ret; |
67 | } | 67 | } |
68 | 68 | ||
69 | /* Changes values from -0x80 to 0x7f into values from minimum to maximum */ | 69 | /* Changes values from -0x80 to 0x7f into values from minimum to maximum */ |
70 | static inline int tmff_scale_s8(int in, int minimum, int maximum) | 70 | static inline int tmff_scale_s8(int in, int minimum, int maximum) |
71 | { | 71 | { |
72 | int ret; | 72 | int ret; |
73 | 73 | ||
74 | ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum; | 74 | ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum; |
75 | if (ret < minimum) | 75 | if (ret < minimum) |
76 | return minimum; | 76 | return minimum; |
77 | if (ret > maximum) | 77 | if (ret > maximum) |
78 | return maximum; | 78 | return maximum; |
79 | return ret; | 79 | return ret; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int tmff_play(struct input_dev *dev, void *data, | 82 | static int tmff_play(struct input_dev *dev, void *data, |
83 | struct ff_effect *effect) | 83 | struct ff_effect *effect) |
84 | { | 84 | { |
85 | struct hid_device *hid = input_get_drvdata(dev); | 85 | struct hid_device *hid = input_get_drvdata(dev); |
86 | struct tmff_device *tmff = data; | 86 | struct tmff_device *tmff = data; |
87 | struct hid_field *ff_field = tmff->ff_field; | 87 | struct hid_field *ff_field = tmff->ff_field; |
88 | int x, y; | 88 | int x, y; |
89 | int left, right; /* Rumbling */ | 89 | int left, right; /* Rumbling */ |
90 | 90 | ||
91 | switch (effect->type) { | 91 | switch (effect->type) { |
92 | case FF_CONSTANT: | 92 | case FF_CONSTANT: |
93 | x = tmff_scale_s8(effect->u.ramp.start_level, | 93 | x = tmff_scale_s8(effect->u.ramp.start_level, |
94 | ff_field->logical_minimum, | 94 | ff_field->logical_minimum, |
95 | ff_field->logical_maximum); | 95 | ff_field->logical_maximum); |
96 | y = tmff_scale_s8(effect->u.ramp.end_level, | 96 | y = tmff_scale_s8(effect->u.ramp.end_level, |
97 | ff_field->logical_minimum, | 97 | ff_field->logical_minimum, |
98 | ff_field->logical_maximum); | 98 | ff_field->logical_maximum); |
99 | 99 | ||
100 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); | 100 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); |
101 | ff_field->value[0] = x; | 101 | ff_field->value[0] = x; |
102 | ff_field->value[1] = y; | 102 | ff_field->value[1] = y; |
103 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); | 103 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); |
104 | break; | 104 | break; |
105 | 105 | ||
106 | case FF_RUMBLE: | 106 | case FF_RUMBLE: |
107 | left = tmff_scale_u16(effect->u.rumble.weak_magnitude, | 107 | left = tmff_scale_u16(effect->u.rumble.weak_magnitude, |
108 | ff_field->logical_minimum, | 108 | ff_field->logical_minimum, |
109 | ff_field->logical_maximum); | 109 | ff_field->logical_maximum); |
110 | right = tmff_scale_u16(effect->u.rumble.strong_magnitude, | 110 | right = tmff_scale_u16(effect->u.rumble.strong_magnitude, |
111 | ff_field->logical_minimum, | 111 | ff_field->logical_minimum, |
112 | ff_field->logical_maximum); | 112 | ff_field->logical_maximum); |
113 | 113 | ||
114 | dbg_hid("(left,right)=(%08x, %08x)\n", left, right); | 114 | dbg_hid("(left,right)=(%08x, %08x)\n", left, right); |
115 | ff_field->value[0] = left; | 115 | ff_field->value[0] = left; |
116 | ff_field->value[1] = right; | 116 | ff_field->value[1] = right; |
117 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); | 117 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); |
118 | break; | 118 | break; |
119 | } | 119 | } |
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static int tmff_init(struct hid_device *hid, const signed short *ff_bits) | 123 | static int tmff_init(struct hid_device *hid, const signed short *ff_bits) |
124 | { | 124 | { |
125 | struct tmff_device *tmff; | 125 | struct tmff_device *tmff; |
126 | struct hid_report *report; | 126 | struct hid_report *report; |
127 | struct list_head *report_list; | 127 | struct list_head *report_list; |
128 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 128 | struct hid_input *hidinput = list_entry(hid->inputs.next, |
129 | struct hid_input, list); | 129 | struct hid_input, list); |
130 | struct input_dev *input_dev = hidinput->input; | 130 | struct input_dev *input_dev = hidinput->input; |
131 | int error; | 131 | int error; |
132 | int i; | 132 | int i; |
133 | 133 | ||
134 | tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); | 134 | tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); |
135 | if (!tmff) | 135 | if (!tmff) |
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | /* Find the report to use */ | 138 | /* Find the report to use */ |
139 | report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 139 | report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
140 | list_for_each_entry(report, report_list, list) { | 140 | list_for_each_entry(report, report_list, list) { |
141 | int fieldnum; | 141 | int fieldnum; |
142 | 142 | ||
143 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { | 143 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { |
144 | struct hid_field *field = report->field[fieldnum]; | 144 | struct hid_field *field = report->field[fieldnum]; |
145 | 145 | ||
146 | if (field->maxusage <= 0) | 146 | if (field->maxusage <= 0) |
147 | continue; | 147 | continue; |
148 | 148 | ||
149 | switch (field->usage[0].hid) { | 149 | switch (field->usage[0].hid) { |
150 | case THRUSTMASTER_USAGE_FF: | 150 | case THRUSTMASTER_USAGE_FF: |
151 | if (field->report_count < 2) { | 151 | if (field->report_count < 2) { |
152 | dev_warn(&hid->dev, "ignoring FF field " | 152 | dev_warn(&hid->dev, "ignoring FF field " |
153 | "with report_count < 2\n"); | 153 | "with report_count < 2\n"); |
154 | continue; | 154 | continue; |
155 | } | 155 | } |
156 | 156 | ||
157 | if (field->logical_maximum == | 157 | if (field->logical_maximum == |
158 | field->logical_minimum) { | 158 | field->logical_minimum) { |
159 | dev_warn(&hid->dev, "ignoring FF field " | 159 | dev_warn(&hid->dev, "ignoring FF field " |
160 | "with logical_maximum " | 160 | "with logical_maximum " |
161 | "== logical_minimum\n"); | 161 | "== logical_minimum\n"); |
162 | continue; | 162 | continue; |
163 | } | 163 | } |
164 | 164 | ||
165 | if (tmff->report && tmff->report != report) { | 165 | if (tmff->report && tmff->report != report) { |
166 | dev_warn(&hid->dev, "ignoring FF field " | 166 | dev_warn(&hid->dev, "ignoring FF field " |
167 | "in other report\n"); | 167 | "in other report\n"); |
168 | continue; | 168 | continue; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (tmff->ff_field && tmff->ff_field != field) { | 171 | if (tmff->ff_field && tmff->ff_field != field) { |
172 | dev_warn(&hid->dev, "ignoring " | 172 | dev_warn(&hid->dev, "ignoring " |
173 | "duplicate FF field\n"); | 173 | "duplicate FF field\n"); |
174 | continue; | 174 | continue; |
175 | } | 175 | } |
176 | 176 | ||
177 | tmff->report = report; | 177 | tmff->report = report; |
178 | tmff->ff_field = field; | 178 | tmff->ff_field = field; |
179 | 179 | ||
180 | for (i = 0; ff_bits[i] >= 0; i++) | 180 | for (i = 0; ff_bits[i] >= 0; i++) |
181 | set_bit(ff_bits[i], input_dev->ffbit); | 181 | set_bit(ff_bits[i], input_dev->ffbit); |
182 | 182 | ||
183 | break; | 183 | break; |
184 | 184 | ||
185 | default: | 185 | default: |
186 | dev_warn(&hid->dev, "ignoring unknown output " | 186 | dev_warn(&hid->dev, "ignoring unknown output " |
187 | "usage %08x\n", | 187 | "usage %08x\n", |
188 | field->usage[0].hid); | 188 | field->usage[0].hid); |
189 | continue; | 189 | continue; |
190 | } | 190 | } |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | if (!tmff->report) { | 194 | if (!tmff->report) { |
195 | dev_err(&hid->dev, "can't find FF field in output reports\n"); | 195 | dev_err(&hid->dev, "can't find FF field in output reports\n"); |
196 | error = -ENODEV; | 196 | error = -ENODEV; |
197 | goto fail; | 197 | goto fail; |
198 | } | 198 | } |
199 | 199 | ||
200 | error = input_ff_create_memless(input_dev, tmff, tmff_play); | 200 | error = input_ff_create_memless(input_dev, tmff, tmff_play); |
201 | if (error) | 201 | if (error) |
202 | goto fail; | 202 | goto fail; |
203 | 203 | ||
204 | dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx " | 204 | dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx " |
205 | "Verituse <zinx@epicsol.org>"); | 205 | "Verituse <zinx@epicsol.org>"); |
206 | return 0; | 206 | return 0; |
207 | 207 | ||
208 | fail: | 208 | fail: |
209 | kfree(tmff); | 209 | kfree(tmff); |
210 | return error; | 210 | return error; |
211 | } | 211 | } |
212 | 212 | ||
213 | static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) | 213 | static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) |
214 | { | 214 | { |
215 | int ret; | 215 | int ret; |
216 | 216 | ||
217 | ret = hid_parse(hdev); | 217 | ret = hid_parse(hdev); |
218 | if (ret) { | 218 | if (ret) { |
219 | dev_err(&hdev->dev, "parse failed\n"); | 219 | dev_err(&hdev->dev, "parse failed\n"); |
220 | goto err; | 220 | goto err; |
221 | } | 221 | } |
222 | 222 | ||
223 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 223 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
224 | if (ret) { | 224 | if (ret) { |
225 | dev_err(&hdev->dev, "hw start failed\n"); | 225 | dev_err(&hdev->dev, "hw start failed\n"); |
226 | goto err; | 226 | goto err; |
227 | } | 227 | } |
228 | 228 | ||
229 | tmff_init(hdev, (void *)id->driver_data); | 229 | tmff_init(hdev, (void *)id->driver_data); |
230 | 230 | ||
231 | return 0; | 231 | return 0; |
232 | err: | 232 | err: |
233 | return ret; | 233 | return ret; |
234 | } | 234 | } |
235 | 235 | ||
236 | static const struct hid_device_id tm_devices[] = { | 236 | static const struct hid_device_id tm_devices[] = { |
237 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300), | 237 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300), |
238 | .driver_data = (unsigned long)ff_rumble }, | 238 | .driver_data = (unsigned long)ff_rumble }, |
239 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), | 239 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), |
240 | .driver_data = (unsigned long)ff_rumble }, | 240 | .driver_data = (unsigned long)ff_rumble }, |
241 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ | 241 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ |
242 | .driver_data = (unsigned long)ff_rumble }, | 242 | .driver_data = (unsigned long)ff_rumble }, |
243 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ | 243 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ |
244 | .driver_data = (unsigned long)ff_joystick }, | 244 | .driver_data = (unsigned long)ff_joystick }, |
245 | { } | 245 | { } |
246 | }; | 246 | }; |
247 | MODULE_DEVICE_TABLE(hid, tm_devices); | 247 | MODULE_DEVICE_TABLE(hid, tm_devices); |
248 | 248 | ||
249 | static struct hid_driver tm_driver = { | 249 | static struct hid_driver tm_driver = { |
250 | .name = "thrustmaster", | 250 | .name = "thrustmaster", |
251 | .id_table = tm_devices, | 251 | .id_table = tm_devices, |
252 | .probe = tm_probe, | 252 | .probe = tm_probe, |
253 | }; | 253 | }; |
254 | 254 | ||
255 | static int tm_init(void) | 255 | static int tm_init(void) |
256 | { | 256 | { |
257 | return hid_register_driver(&tm_driver); | 257 | return hid_register_driver(&tm_driver); |
258 | } | 258 | } |
259 | 259 | ||
260 | static void tm_exit(void) | 260 | static void tm_exit(void) |
261 | { | 261 | { |
262 | hid_unregister_driver(&tm_driver); | 262 | hid_unregister_driver(&tm_driver); |
263 | } | 263 | } |
264 | 264 | ||
265 | module_init(tm_init); | 265 | module_init(tm_init); |
266 | module_exit(tm_exit); | 266 | module_exit(tm_exit); |
267 | MODULE_LICENSE("GPL"); | 267 | MODULE_LICENSE("GPL"); |
268 | |||
269 | HID_COMPAT_LOAD_DRIVER(thrustmaster); | ||
270 | 268 |
drivers/hid/hid-topseed.c
1 | /* | 1 | /* |
2 | * HID driver for TopSeed Cyberlink remote | 2 | * HID driver for TopSeed Cyberlink remote |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Lev Babiev | 4 | * Copyright (c) 2008 Lev Babiev |
5 | * based on hid-cherry driver | 5 | * based on hid-cherry driver |
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 | 18 | ||
19 | #include "hid-ids.h" | 19 | #include "hid-ids.h" |
20 | 20 | ||
21 | #define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 21 | #define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
22 | EV_KEY, (c)) | 22 | EV_KEY, (c)) |
23 | static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 23 | static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
24 | struct hid_field *field, struct hid_usage *usage, | 24 | struct hid_field *field, struct hid_usage *usage, |
25 | unsigned long **bit, int *max) | 25 | unsigned long **bit, int *max) |
26 | { | 26 | { |
27 | if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000) | 27 | if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000) |
28 | return 0; | 28 | return 0; |
29 | 29 | ||
30 | switch (usage->hid & HID_USAGE) { | 30 | switch (usage->hid & HID_USAGE) { |
31 | case 0x00d: ts_map_key_clear(KEY_HOME); break; | 31 | case 0x00d: ts_map_key_clear(KEY_HOME); break; |
32 | case 0x024: ts_map_key_clear(KEY_MENU); break; | 32 | case 0x024: ts_map_key_clear(KEY_MENU); break; |
33 | case 0x025: ts_map_key_clear(KEY_TV); break; | 33 | case 0x025: ts_map_key_clear(KEY_TV); break; |
34 | case 0x048: ts_map_key_clear(KEY_RED); break; | 34 | case 0x048: ts_map_key_clear(KEY_RED); break; |
35 | case 0x047: ts_map_key_clear(KEY_GREEN); break; | 35 | case 0x047: ts_map_key_clear(KEY_GREEN); break; |
36 | case 0x049: ts_map_key_clear(KEY_YELLOW); break; | 36 | case 0x049: ts_map_key_clear(KEY_YELLOW); break; |
37 | case 0x04a: ts_map_key_clear(KEY_BLUE); break; | 37 | case 0x04a: ts_map_key_clear(KEY_BLUE); break; |
38 | case 0x04b: ts_map_key_clear(KEY_ANGLE); break; | 38 | case 0x04b: ts_map_key_clear(KEY_ANGLE); break; |
39 | case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break; | 39 | case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break; |
40 | case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break; | 40 | case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break; |
41 | case 0x031: ts_map_key_clear(KEY_AUDIO); break; | 41 | case 0x031: ts_map_key_clear(KEY_AUDIO); break; |
42 | case 0x032: ts_map_key_clear(KEY_TEXT); break; | 42 | case 0x032: ts_map_key_clear(KEY_TEXT); break; |
43 | case 0x033: ts_map_key_clear(KEY_CHANNEL); break; | 43 | case 0x033: ts_map_key_clear(KEY_CHANNEL); break; |
44 | default: | 44 | default: |
45 | return 0; | 45 | return 0; |
46 | } | 46 | } |
47 | 47 | ||
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | 50 | ||
51 | static const struct hid_device_id ts_devices[] = { | 51 | static const struct hid_device_id ts_devices[] = { |
52 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 52 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
53 | { } | 53 | { } |
54 | }; | 54 | }; |
55 | MODULE_DEVICE_TABLE(hid, ts_devices); | 55 | MODULE_DEVICE_TABLE(hid, ts_devices); |
56 | 56 | ||
57 | static struct hid_driver ts_driver = { | 57 | static struct hid_driver ts_driver = { |
58 | .name = "topseed", | 58 | .name = "topseed", |
59 | .id_table = ts_devices, | 59 | .id_table = ts_devices, |
60 | .input_mapping = ts_input_mapping, | 60 | .input_mapping = ts_input_mapping, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static int ts_init(void) | 63 | static int ts_init(void) |
64 | { | 64 | { |
65 | return hid_register_driver(&ts_driver); | 65 | return hid_register_driver(&ts_driver); |
66 | } | 66 | } |
67 | 67 | ||
68 | static void ts_exit(void) | 68 | static void ts_exit(void) |
69 | { | 69 | { |
70 | hid_unregister_driver(&ts_driver); | 70 | hid_unregister_driver(&ts_driver); |
71 | } | 71 | } |
72 | 72 | ||
73 | module_init(ts_init); | 73 | module_init(ts_init); |
74 | module_exit(ts_exit); | 74 | module_exit(ts_exit); |
75 | MODULE_LICENSE("GPL"); | 75 | MODULE_LICENSE("GPL"); |
76 | |||
77 | HID_COMPAT_LOAD_DRIVER(topseed); | ||
78 | 76 |
drivers/hid/hid-zpff.c
1 | /* | 1 | /* |
2 | * Force feedback support for Zeroplus based devices | 2 | * Force feedback support for Zeroplus based devices |
3 | * | 3 | * |
4 | * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com> | 4 | * Copyright (c) 2005, 2006 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/hid.h> | 24 | #include <linux/hid.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | 27 | ||
28 | #include "hid-ids.h" | 28 | #include "hid-ids.h" |
29 | 29 | ||
30 | #include "usbhid/usbhid.h" | 30 | #include "usbhid/usbhid.h" |
31 | 31 | ||
32 | struct zpff_device { | 32 | struct zpff_device { |
33 | struct hid_report *report; | 33 | struct hid_report *report; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static int zpff_play(struct input_dev *dev, void *data, | 36 | static int zpff_play(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 zpff_device *zpff = data; | 40 | struct zpff_device *zpff = data; |
41 | int left, right; | 41 | int left, right; |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * The following is specified the other way around in the Zeroplus | 44 | * The following is specified the other way around in the Zeroplus |
45 | * datasheet but the order below is correct for the XFX Executioner; | 45 | * datasheet but the order below is correct for the XFX Executioner; |
46 | * however it is possible that the XFX Executioner is an exception | 46 | * however it is possible that the XFX Executioner is an exception |
47 | */ | 47 | */ |
48 | 48 | ||
49 | left = effect->u.rumble.strong_magnitude; | 49 | left = effect->u.rumble.strong_magnitude; |
50 | right = effect->u.rumble.weak_magnitude; | 50 | right = effect->u.rumble.weak_magnitude; |
51 | dbg_hid("called with 0x%04x 0x%04x\n", left, right); | 51 | dbg_hid("called with 0x%04x 0x%04x\n", left, right); |
52 | 52 | ||
53 | left = left * 0x7f / 0xffff; | 53 | left = left * 0x7f / 0xffff; |
54 | right = right * 0x7f / 0xffff; | 54 | right = right * 0x7f / 0xffff; |
55 | 55 | ||
56 | zpff->report->field[2]->value[0] = left; | 56 | zpff->report->field[2]->value[0] = left; |
57 | zpff->report->field[3]->value[0] = right; | 57 | zpff->report->field[3]->value[0] = right; |
58 | dbg_hid("running with 0x%02x 0x%02x\n", left, right); | 58 | dbg_hid("running with 0x%02x 0x%02x\n", left, right); |
59 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); | 59 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
60 | 60 | ||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | static int zpff_init(struct hid_device *hid) | 64 | static int zpff_init(struct hid_device *hid) |
65 | { | 65 | { |
66 | struct zpff_device *zpff; | 66 | struct zpff_device *zpff; |
67 | struct hid_report *report; | 67 | struct hid_report *report; |
68 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 68 | struct hid_input *hidinput = list_entry(hid->inputs.next, |
69 | struct hid_input, list); | 69 | struct hid_input, list); |
70 | struct list_head *report_list = | 70 | struct list_head *report_list = |
71 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 71 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
72 | struct input_dev *dev = hidinput->input; | 72 | struct input_dev *dev = hidinput->input; |
73 | int error; | 73 | int error; |
74 | 74 | ||
75 | if (list_empty(report_list)) { | 75 | if (list_empty(report_list)) { |
76 | dev_err(&hid->dev, "no output report found\n"); | 76 | dev_err(&hid->dev, "no output report found\n"); |
77 | return -ENODEV; | 77 | return -ENODEV; |
78 | } | 78 | } |
79 | 79 | ||
80 | report = list_entry(report_list->next, struct hid_report, list); | 80 | report = list_entry(report_list->next, struct hid_report, list); |
81 | 81 | ||
82 | if (report->maxfield < 4) { | 82 | if (report->maxfield < 4) { |
83 | dev_err(&hid->dev, "not enough fields in report\n"); | 83 | dev_err(&hid->dev, "not enough fields in report\n"); |
84 | return -ENODEV; | 84 | return -ENODEV; |
85 | } | 85 | } |
86 | 86 | ||
87 | zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); | 87 | zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); |
88 | if (!zpff) | 88 | if (!zpff) |
89 | return -ENOMEM; | 89 | return -ENOMEM; |
90 | 90 | ||
91 | set_bit(FF_RUMBLE, dev->ffbit); | 91 | set_bit(FF_RUMBLE, dev->ffbit); |
92 | 92 | ||
93 | error = input_ff_create_memless(dev, zpff, zpff_play); | 93 | error = input_ff_create_memless(dev, zpff, zpff_play); |
94 | if (error) { | 94 | if (error) { |
95 | kfree(zpff); | 95 | kfree(zpff); |
96 | return error; | 96 | return error; |
97 | } | 97 | } |
98 | 98 | ||
99 | zpff->report = report; | 99 | zpff->report = report; |
100 | zpff->report->field[0]->value[0] = 0x00; | 100 | zpff->report->field[0]->value[0] = 0x00; |
101 | zpff->report->field[1]->value[0] = 0x02; | 101 | zpff->report->field[1]->value[0] = 0x02; |
102 | zpff->report->field[2]->value[0] = 0x00; | 102 | zpff->report->field[2]->value[0] = 0x00; |
103 | zpff->report->field[3]->value[0] = 0x00; | 103 | zpff->report->field[3]->value[0] = 0x00; |
104 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); | 104 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
105 | 105 | ||
106 | dev_info(&hid->dev, "force feedback for Zeroplus based devices by " | 106 | dev_info(&hid->dev, "force feedback for Zeroplus based devices by " |
107 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); | 107 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); |
108 | 108 | ||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) | 112 | static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) |
113 | { | 113 | { |
114 | int ret; | 114 | int ret; |
115 | 115 | ||
116 | ret = hid_parse(hdev); | 116 | ret = hid_parse(hdev); |
117 | if (ret) { | 117 | if (ret) { |
118 | dev_err(&hdev->dev, "parse failed\n"); | 118 | dev_err(&hdev->dev, "parse failed\n"); |
119 | goto err; | 119 | goto err; |
120 | } | 120 | } |
121 | 121 | ||
122 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 122 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
123 | if (ret) { | 123 | if (ret) { |
124 | dev_err(&hdev->dev, "hw start failed\n"); | 124 | dev_err(&hdev->dev, "hw start failed\n"); |
125 | goto err; | 125 | goto err; |
126 | } | 126 | } |
127 | 127 | ||
128 | zpff_init(hdev); | 128 | zpff_init(hdev); |
129 | 129 | ||
130 | return 0; | 130 | return 0; |
131 | err: | 131 | err: |
132 | return ret; | 132 | return ret; |
133 | } | 133 | } |
134 | 134 | ||
135 | static const struct hid_device_id zp_devices[] = { | 135 | static const struct hid_device_id zp_devices[] = { |
136 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, | 136 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, |
137 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, | 137 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, |
138 | { } | 138 | { } |
139 | }; | 139 | }; |
140 | MODULE_DEVICE_TABLE(hid, zp_devices); | 140 | MODULE_DEVICE_TABLE(hid, zp_devices); |
141 | 141 | ||
142 | static struct hid_driver zp_driver = { | 142 | static struct hid_driver zp_driver = { |
143 | .name = "zeroplus", | 143 | .name = "zeroplus", |
144 | .id_table = zp_devices, | 144 | .id_table = zp_devices, |
145 | .probe = zp_probe, | 145 | .probe = zp_probe, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static int zp_init(void) | 148 | static int zp_init(void) |
149 | { | 149 | { |
150 | return hid_register_driver(&zp_driver); | 150 | return hid_register_driver(&zp_driver); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void zp_exit(void) | 153 | static void zp_exit(void) |
154 | { | 154 | { |
155 | hid_unregister_driver(&zp_driver); | 155 | hid_unregister_driver(&zp_driver); |
156 | } | 156 | } |
157 | 157 | ||
158 | module_init(zp_init); | 158 | module_init(zp_init); |
159 | module_exit(zp_exit); | 159 | module_exit(zp_exit); |
160 | MODULE_LICENSE("GPL"); | 160 | MODULE_LICENSE("GPL"); |
161 | |||
162 | HID_COMPAT_LOAD_DRIVER(zeroplus); | ||
163 | 161 |
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 | /* | 241 | /* |
242 | * HID report types --- Ouch! HID spec says 1 2 3! | 242 | * HID report types --- Ouch! HID spec says 1 2 3! |
243 | */ | 243 | */ |
244 | 244 | ||
245 | #define HID_INPUT_REPORT 0 | 245 | #define HID_INPUT_REPORT 0 |
246 | #define HID_OUTPUT_REPORT 1 | 246 | #define HID_OUTPUT_REPORT 1 |
247 | #define HID_FEATURE_REPORT 2 | 247 | #define HID_FEATURE_REPORT 2 |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * HID connect requests | 250 | * HID connect requests |
251 | */ | 251 | */ |
252 | 252 | ||
253 | #define HID_CONNECT_HIDINPUT 0x01 | 253 | #define HID_CONNECT_HIDINPUT 0x01 |
254 | #define HID_CONNECT_HIDINPUT_FORCE 0x02 | 254 | #define HID_CONNECT_HIDINPUT_FORCE 0x02 |
255 | #define HID_CONNECT_HIDRAW 0x04 | 255 | #define HID_CONNECT_HIDRAW 0x04 |
256 | #define HID_CONNECT_HIDDEV 0x08 | 256 | #define HID_CONNECT_HIDDEV 0x08 |
257 | #define HID_CONNECT_HIDDEV_FORCE 0x10 | 257 | #define HID_CONNECT_HIDDEV_FORCE 0x10 |
258 | #define HID_CONNECT_FF 0x20 | 258 | #define HID_CONNECT_FF 0x20 |
259 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ | 259 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ |
260 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) | 260 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) |
261 | 261 | ||
262 | /* | 262 | /* |
263 | * HID device quirks. | 263 | * HID device quirks. |
264 | */ | 264 | */ |
265 | 265 | ||
266 | /* | 266 | /* |
267 | * Increase this if you need to configure more HID quirks at module load time | 267 | * Increase this if you need to configure more HID quirks at module load time |
268 | */ | 268 | */ |
269 | #define MAX_USBHID_BOOT_QUIRKS 4 | 269 | #define MAX_USBHID_BOOT_QUIRKS 4 |
270 | 270 | ||
271 | #define HID_QUIRK_INVERT 0x00000001 | 271 | #define HID_QUIRK_INVERT 0x00000001 |
272 | #define HID_QUIRK_NOTOUCH 0x00000002 | 272 | #define HID_QUIRK_NOTOUCH 0x00000002 |
273 | #define HID_QUIRK_IGNORE 0x00000004 | 273 | #define HID_QUIRK_IGNORE 0x00000004 |
274 | #define HID_QUIRK_NOGET 0x00000008 | 274 | #define HID_QUIRK_NOGET 0x00000008 |
275 | #define HID_QUIRK_BADPAD 0x00000020 | 275 | #define HID_QUIRK_BADPAD 0x00000020 |
276 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 276 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
277 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 277 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
278 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 278 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
279 | 279 | ||
280 | /* | 280 | /* |
281 | * This is the global environment of the parser. This information is | 281 | * This is the global environment of the parser. This information is |
282 | * persistent for main-items. The global environment can be saved and | 282 | * persistent for main-items. The global environment can be saved and |
283 | * restored with PUSH/POP statements. | 283 | * restored with PUSH/POP statements. |
284 | */ | 284 | */ |
285 | 285 | ||
286 | struct hid_global { | 286 | struct hid_global { |
287 | unsigned usage_page; | 287 | unsigned usage_page; |
288 | __s32 logical_minimum; | 288 | __s32 logical_minimum; |
289 | __s32 logical_maximum; | 289 | __s32 logical_maximum; |
290 | __s32 physical_minimum; | 290 | __s32 physical_minimum; |
291 | __s32 physical_maximum; | 291 | __s32 physical_maximum; |
292 | __s32 unit_exponent; | 292 | __s32 unit_exponent; |
293 | unsigned unit; | 293 | unsigned unit; |
294 | unsigned report_id; | 294 | unsigned report_id; |
295 | unsigned report_size; | 295 | unsigned report_size; |
296 | unsigned report_count; | 296 | unsigned report_count; |
297 | }; | 297 | }; |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * This is the local environment. It is persistent up the next main-item. | 300 | * This is the local environment. It is persistent up the next main-item. |
301 | */ | 301 | */ |
302 | 302 | ||
303 | #define HID_MAX_USAGES 12288 | 303 | #define HID_MAX_USAGES 12288 |
304 | #define HID_DEFAULT_NUM_COLLECTIONS 16 | 304 | #define HID_DEFAULT_NUM_COLLECTIONS 16 |
305 | 305 | ||
306 | struct hid_local { | 306 | struct hid_local { |
307 | unsigned usage[HID_MAX_USAGES]; /* usage array */ | 307 | unsigned usage[HID_MAX_USAGES]; /* usage array */ |
308 | unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ | 308 | unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ |
309 | unsigned usage_index; | 309 | unsigned usage_index; |
310 | unsigned usage_minimum; | 310 | unsigned usage_minimum; |
311 | unsigned delimiter_depth; | 311 | unsigned delimiter_depth; |
312 | unsigned delimiter_branch; | 312 | unsigned delimiter_branch; |
313 | }; | 313 | }; |
314 | 314 | ||
315 | /* | 315 | /* |
316 | * This is the collection stack. We climb up the stack to determine | 316 | * This is the collection stack. We climb up the stack to determine |
317 | * application and function of each field. | 317 | * application and function of each field. |
318 | */ | 318 | */ |
319 | 319 | ||
320 | struct hid_collection { | 320 | struct hid_collection { |
321 | unsigned type; | 321 | unsigned type; |
322 | unsigned usage; | 322 | unsigned usage; |
323 | unsigned level; | 323 | unsigned level; |
324 | }; | 324 | }; |
325 | 325 | ||
326 | struct hid_usage { | 326 | struct hid_usage { |
327 | unsigned hid; /* hid usage code */ | 327 | unsigned hid; /* hid usage code */ |
328 | unsigned collection_index; /* index into collection array */ | 328 | unsigned collection_index; /* index into collection array */ |
329 | /* hidinput data */ | 329 | /* hidinput data */ |
330 | __u16 code; /* input driver code */ | 330 | __u16 code; /* input driver code */ |
331 | __u8 type; /* input driver type */ | 331 | __u8 type; /* input driver type */ |
332 | __s8 hat_min; /* hat switch fun */ | 332 | __s8 hat_min; /* hat switch fun */ |
333 | __s8 hat_max; /* ditto */ | 333 | __s8 hat_max; /* ditto */ |
334 | __s8 hat_dir; /* ditto */ | 334 | __s8 hat_dir; /* ditto */ |
335 | }; | 335 | }; |
336 | 336 | ||
337 | struct hid_input; | 337 | struct hid_input; |
338 | 338 | ||
339 | struct hid_field { | 339 | struct hid_field { |
340 | unsigned physical; /* physical usage for this field */ | 340 | unsigned physical; /* physical usage for this field */ |
341 | unsigned logical; /* logical usage for this field */ | 341 | unsigned logical; /* logical usage for this field */ |
342 | unsigned application; /* application usage for this field */ | 342 | unsigned application; /* application usage for this field */ |
343 | struct hid_usage *usage; /* usage table for this function */ | 343 | struct hid_usage *usage; /* usage table for this function */ |
344 | unsigned maxusage; /* maximum usage index */ | 344 | unsigned maxusage; /* maximum usage index */ |
345 | unsigned flags; /* main-item flags (i.e. volatile,array,constant) */ | 345 | unsigned flags; /* main-item flags (i.e. volatile,array,constant) */ |
346 | unsigned report_offset; /* bit offset in the report */ | 346 | unsigned report_offset; /* bit offset in the report */ |
347 | unsigned report_size; /* size of this field in the report */ | 347 | unsigned report_size; /* size of this field in the report */ |
348 | unsigned report_count; /* number of this field in the report */ | 348 | unsigned report_count; /* number of this field in the report */ |
349 | unsigned report_type; /* (input,output,feature) */ | 349 | unsigned report_type; /* (input,output,feature) */ |
350 | __s32 *value; /* last known value(s) */ | 350 | __s32 *value; /* last known value(s) */ |
351 | __s32 logical_minimum; | 351 | __s32 logical_minimum; |
352 | __s32 logical_maximum; | 352 | __s32 logical_maximum; |
353 | __s32 physical_minimum; | 353 | __s32 physical_minimum; |
354 | __s32 physical_maximum; | 354 | __s32 physical_maximum; |
355 | __s32 unit_exponent; | 355 | __s32 unit_exponent; |
356 | unsigned unit; | 356 | unsigned unit; |
357 | struct hid_report *report; /* associated report */ | 357 | struct hid_report *report; /* associated report */ |
358 | unsigned index; /* index into report->field[] */ | 358 | unsigned index; /* index into report->field[] */ |
359 | /* hidinput data */ | 359 | /* hidinput data */ |
360 | struct hid_input *hidinput; /* associated input structure */ | 360 | struct hid_input *hidinput; /* associated input structure */ |
361 | __u16 dpad; /* dpad input code */ | 361 | __u16 dpad; /* dpad input code */ |
362 | }; | 362 | }; |
363 | 363 | ||
364 | #define HID_MAX_FIELDS 64 | 364 | #define HID_MAX_FIELDS 64 |
365 | 365 | ||
366 | struct hid_report { | 366 | struct hid_report { |
367 | struct list_head list; | 367 | struct list_head list; |
368 | unsigned id; /* id of this report */ | 368 | unsigned id; /* id of this report */ |
369 | unsigned type; /* report type */ | 369 | unsigned type; /* report type */ |
370 | struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ | 370 | struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ |
371 | unsigned maxfield; /* maximum valid field index */ | 371 | unsigned maxfield; /* maximum valid field index */ |
372 | unsigned size; /* size of the report (bits) */ | 372 | unsigned size; /* size of the report (bits) */ |
373 | struct hid_device *device; /* associated device */ | 373 | struct hid_device *device; /* associated device */ |
374 | }; | 374 | }; |
375 | 375 | ||
376 | struct hid_report_enum { | 376 | struct hid_report_enum { |
377 | unsigned numbered; | 377 | unsigned numbered; |
378 | struct list_head report_list; | 378 | struct list_head report_list; |
379 | struct hid_report *report_id_hash[256]; | 379 | struct hid_report *report_id_hash[256]; |
380 | }; | 380 | }; |
381 | 381 | ||
382 | #define HID_REPORT_TYPES 3 | 382 | #define HID_REPORT_TYPES 3 |
383 | 383 | ||
384 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ | 384 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ |
385 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ | 385 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ |
386 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ | 386 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ |
387 | #define HID_OUTPUT_FIFO_SIZE 64 | 387 | #define HID_OUTPUT_FIFO_SIZE 64 |
388 | 388 | ||
389 | struct hid_control_fifo { | 389 | struct hid_control_fifo { |
390 | unsigned char dir; | 390 | unsigned char dir; |
391 | struct hid_report *report; | 391 | struct hid_report *report; |
392 | char *raw_report; | 392 | char *raw_report; |
393 | }; | 393 | }; |
394 | 394 | ||
395 | struct hid_output_fifo { | 395 | struct hid_output_fifo { |
396 | struct hid_report *report; | 396 | struct hid_report *report; |
397 | char *raw_report; | 397 | char *raw_report; |
398 | }; | 398 | }; |
399 | 399 | ||
400 | #define HID_CLAIMED_INPUT 1 | 400 | #define HID_CLAIMED_INPUT 1 |
401 | #define HID_CLAIMED_HIDDEV 2 | 401 | #define HID_CLAIMED_HIDDEV 2 |
402 | #define HID_CLAIMED_HIDRAW 4 | 402 | #define HID_CLAIMED_HIDRAW 4 |
403 | 403 | ||
404 | #define HID_STAT_ADDED 1 | 404 | #define HID_STAT_ADDED 1 |
405 | #define HID_STAT_PARSED 2 | 405 | #define HID_STAT_PARSED 2 |
406 | 406 | ||
407 | struct hid_input { | 407 | struct hid_input { |
408 | struct list_head list; | 408 | struct list_head list; |
409 | struct hid_report *report; | 409 | struct hid_report *report; |
410 | struct input_dev *input; | 410 | struct input_dev *input; |
411 | }; | 411 | }; |
412 | 412 | ||
413 | enum hid_type { | 413 | enum hid_type { |
414 | HID_TYPE_OTHER = 0, | 414 | HID_TYPE_OTHER = 0, |
415 | HID_TYPE_USBMOUSE | 415 | HID_TYPE_USBMOUSE |
416 | }; | 416 | }; |
417 | 417 | ||
418 | struct hid_driver; | 418 | struct hid_driver; |
419 | struct hid_ll_driver; | 419 | struct hid_ll_driver; |
420 | 420 | ||
421 | struct hid_device { /* device report descriptor */ | 421 | struct hid_device { /* device report descriptor */ |
422 | __u8 *rdesc; | 422 | __u8 *rdesc; |
423 | unsigned rsize; | 423 | unsigned rsize; |
424 | struct hid_collection *collection; /* List of HID collections */ | 424 | struct hid_collection *collection; /* List of HID collections */ |
425 | unsigned collection_size; /* Number of allocated hid_collections */ | 425 | unsigned collection_size; /* Number of allocated hid_collections */ |
426 | unsigned maxcollection; /* Number of parsed collections */ | 426 | unsigned maxcollection; /* Number of parsed collections */ |
427 | unsigned maxapplication; /* Number of applications */ | 427 | unsigned maxapplication; /* Number of applications */ |
428 | __u16 bus; /* BUS ID */ | 428 | __u16 bus; /* BUS ID */ |
429 | __u32 vendor; /* Vendor ID */ | 429 | __u32 vendor; /* Vendor ID */ |
430 | __u32 product; /* Product ID */ | 430 | __u32 product; /* Product ID */ |
431 | __u32 version; /* HID version */ | 431 | __u32 version; /* HID version */ |
432 | enum hid_type type; /* device type (mouse, kbd, ...) */ | 432 | enum hid_type type; /* device type (mouse, kbd, ...) */ |
433 | unsigned country; /* HID country */ | 433 | unsigned country; /* HID country */ |
434 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | 434 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; |
435 | 435 | ||
436 | struct device dev; /* device */ | 436 | struct device dev; /* device */ |
437 | struct hid_driver *driver; | 437 | struct hid_driver *driver; |
438 | struct hid_ll_driver *ll_driver; | 438 | struct hid_ll_driver *ll_driver; |
439 | 439 | ||
440 | unsigned int status; /* see STAT flags above */ | 440 | unsigned int status; /* see STAT flags above */ |
441 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 441 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
442 | unsigned quirks; /* Various quirks the device can pull on us */ | 442 | unsigned quirks; /* Various quirks the device can pull on us */ |
443 | 443 | ||
444 | struct list_head inputs; /* The list of inputs */ | 444 | struct list_head inputs; /* The list of inputs */ |
445 | void *hiddev; /* The hiddev structure */ | 445 | void *hiddev; /* The hiddev structure */ |
446 | void *hidraw; | 446 | void *hidraw; |
447 | int minor; /* Hiddev minor number */ | 447 | int minor; /* Hiddev minor number */ |
448 | 448 | ||
449 | int open; /* is the device open by anyone? */ | 449 | int open; /* is the device open by anyone? */ |
450 | char name[128]; /* Device name */ | 450 | char name[128]; /* Device name */ |
451 | char phys[64]; /* Device physical location */ | 451 | char phys[64]; /* Device physical location */ |
452 | char uniq[64]; /* Device unique identifier (serial #) */ | 452 | char uniq[64]; /* Device unique identifier (serial #) */ |
453 | 453 | ||
454 | void *driver_data; | 454 | void *driver_data; |
455 | 455 | ||
456 | /* temporary hid_ff handling (until moved to the drivers) */ | 456 | /* temporary hid_ff handling (until moved to the drivers) */ |
457 | int (*ff_init)(struct hid_device *); | 457 | int (*ff_init)(struct hid_device *); |
458 | 458 | ||
459 | /* hiddev event handler */ | 459 | /* hiddev event handler */ |
460 | int (*hiddev_connect)(struct hid_device *, unsigned int); | 460 | int (*hiddev_connect)(struct hid_device *, unsigned int); |
461 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, | 461 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, |
462 | struct hid_usage *, __s32); | 462 | struct hid_usage *, __s32); |
463 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); | 463 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); |
464 | 464 | ||
465 | /* handler for raw output data, used by hidraw */ | 465 | /* handler for raw output data, used by hidraw */ |
466 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); | 466 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); |
467 | }; | 467 | }; |
468 | 468 | ||
469 | static inline void *hid_get_drvdata(struct hid_device *hdev) | 469 | static inline void *hid_get_drvdata(struct hid_device *hdev) |
470 | { | 470 | { |
471 | return dev_get_drvdata(&hdev->dev); | 471 | return dev_get_drvdata(&hdev->dev); |
472 | } | 472 | } |
473 | 473 | ||
474 | static inline void hid_set_drvdata(struct hid_device *hdev, void *data) | 474 | static inline void hid_set_drvdata(struct hid_device *hdev, void *data) |
475 | { | 475 | { |
476 | dev_set_drvdata(&hdev->dev, data); | 476 | dev_set_drvdata(&hdev->dev, data); |
477 | } | 477 | } |
478 | 478 | ||
479 | #define HID_GLOBAL_STACK_SIZE 4 | 479 | #define HID_GLOBAL_STACK_SIZE 4 |
480 | #define HID_COLLECTION_STACK_SIZE 4 | 480 | #define HID_COLLECTION_STACK_SIZE 4 |
481 | 481 | ||
482 | struct hid_parser { | 482 | struct hid_parser { |
483 | struct hid_global global; | 483 | struct hid_global global; |
484 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; | 484 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; |
485 | unsigned global_stack_ptr; | 485 | unsigned global_stack_ptr; |
486 | struct hid_local local; | 486 | struct hid_local local; |
487 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; | 487 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; |
488 | unsigned collection_stack_ptr; | 488 | unsigned collection_stack_ptr; |
489 | struct hid_device *device; | 489 | struct hid_device *device; |
490 | }; | 490 | }; |
491 | 491 | ||
492 | struct hid_class_descriptor { | 492 | struct hid_class_descriptor { |
493 | __u8 bDescriptorType; | 493 | __u8 bDescriptorType; |
494 | __le16 wDescriptorLength; | 494 | __le16 wDescriptorLength; |
495 | } __attribute__ ((packed)); | 495 | } __attribute__ ((packed)); |
496 | 496 | ||
497 | struct hid_descriptor { | 497 | struct hid_descriptor { |
498 | __u8 bLength; | 498 | __u8 bLength; |
499 | __u8 bDescriptorType; | 499 | __u8 bDescriptorType; |
500 | __le16 bcdHID; | 500 | __le16 bcdHID; |
501 | __u8 bCountryCode; | 501 | __u8 bCountryCode; |
502 | __u8 bNumDescriptors; | 502 | __u8 bNumDescriptors; |
503 | 503 | ||
504 | struct hid_class_descriptor desc[1]; | 504 | struct hid_class_descriptor desc[1]; |
505 | } __attribute__ ((packed)); | 505 | } __attribute__ ((packed)); |
506 | 506 | ||
507 | #define HID_DEVICE(b, ven, prod) \ | 507 | #define HID_DEVICE(b, ven, prod) \ |
508 | .bus = (b), \ | 508 | .bus = (b), \ |
509 | .vendor = (ven), .product = (prod) | 509 | .vendor = (ven), .product = (prod) |
510 | 510 | ||
511 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) | 511 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) |
512 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) | 512 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) |
513 | 513 | ||
514 | #define HID_REPORT_ID(rep) \ | 514 | #define HID_REPORT_ID(rep) \ |
515 | .report_type = (rep) | 515 | .report_type = (rep) |
516 | #define HID_USAGE_ID(uhid, utype, ucode) \ | 516 | #define HID_USAGE_ID(uhid, utype, ucode) \ |
517 | .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) | 517 | .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) |
518 | /* we don't want to catch types and codes equal to 0 */ | 518 | /* we don't want to catch types and codes equal to 0 */ |
519 | #define HID_TERMINATOR (HID_ANY_ID - 1) | 519 | #define HID_TERMINATOR (HID_ANY_ID - 1) |
520 | 520 | ||
521 | struct hid_report_id { | 521 | struct hid_report_id { |
522 | __u32 report_type; | 522 | __u32 report_type; |
523 | }; | 523 | }; |
524 | struct hid_usage_id { | 524 | struct hid_usage_id { |
525 | __u32 usage_hid; | 525 | __u32 usage_hid; |
526 | __u32 usage_type; | 526 | __u32 usage_type; |
527 | __u32 usage_code; | 527 | __u32 usage_code; |
528 | }; | 528 | }; |
529 | 529 | ||
530 | /** | 530 | /** |
531 | * struct hid_driver | 531 | * struct hid_driver |
532 | * @name: driver name (e.g. "Footech_bar-wheel") | 532 | * @name: driver name (e.g. "Footech_bar-wheel") |
533 | * @id_table: which devices is this driver for (must be non-NULL for probe | 533 | * @id_table: which devices is this driver for (must be non-NULL for probe |
534 | * to be called) | 534 | * to be called) |
535 | * @dyn_list: list of dynamically added device ids | 535 | * @dyn_list: list of dynamically added device ids |
536 | * @dyn_lock: lock protecting @dyn_list | 536 | * @dyn_lock: lock protecting @dyn_list |
537 | * @probe: new device inserted | 537 | * @probe: new device inserted |
538 | * @remove: device removed (NULL if not a hot-plug capable driver) | 538 | * @remove: device removed (NULL if not a hot-plug capable driver) |
539 | * @report_table: on which reports to call raw_event (NULL means all) | 539 | * @report_table: on which reports to call raw_event (NULL means all) |
540 | * @raw_event: if report in report_table, this hook is called (NULL means nop) | 540 | * @raw_event: if report in report_table, this hook is called (NULL means nop) |
541 | * @usage_table: on which events to call event (NULL means all) | 541 | * @usage_table: on which events to call event (NULL means all) |
542 | * @event: if usage in usage_table, this hook is called (NULL means nop) | 542 | * @event: if usage in usage_table, this hook is called (NULL means nop) |
543 | * @report_fixup: called before report descriptor parsing (NULL means nop) | 543 | * @report_fixup: called before report descriptor parsing (NULL means nop) |
544 | * @input_mapping: invoked on input registering before mapping an usage | 544 | * @input_mapping: invoked on input registering before mapping an usage |
545 | * @input_mapped: invoked on input registering after mapping an usage | 545 | * @input_mapped: invoked on input registering after mapping an usage |
546 | * | 546 | * |
547 | * raw_event and event should return 0 on no action performed, 1 when no | 547 | * raw_event and event should return 0 on no action performed, 1 when no |
548 | * further processing should be done and negative on error | 548 | * further processing should be done and negative on error |
549 | * | 549 | * |
550 | * input_mapping shall return a negative value to completely ignore this usage | 550 | * input_mapping shall return a negative value to completely ignore this usage |
551 | * (e.g. doubled or invalid usage), zero to continue with parsing of this | 551 | * (e.g. doubled or invalid usage), zero to continue with parsing of this |
552 | * usage by generic code (no special handling needed) or positive to skip | 552 | * usage by generic code (no special handling needed) or positive to skip |
553 | * generic parsing (needed special handling which was done in the hook already) | 553 | * generic parsing (needed special handling which was done in the hook already) |
554 | * input_mapped shall return negative to inform the layer that this usage | 554 | * input_mapped shall return negative to inform the layer that this usage |
555 | * should not be considered for further processing or zero to notify that | 555 | * should not be considered for further processing or zero to notify that |
556 | * no processing was performed and should be done in a generic manner | 556 | * no processing was performed and should be done in a generic manner |
557 | * Both these functions may be NULL which means the same behavior as returning | 557 | * Both these functions may be NULL which means the same behavior as returning |
558 | * zero from them. | 558 | * zero from them. |
559 | */ | 559 | */ |
560 | struct hid_driver { | 560 | struct hid_driver { |
561 | char *name; | 561 | char *name; |
562 | const struct hid_device_id *id_table; | 562 | const struct hid_device_id *id_table; |
563 | 563 | ||
564 | struct list_head dyn_list; | 564 | struct list_head dyn_list; |
565 | spinlock_t dyn_lock; | 565 | spinlock_t dyn_lock; |
566 | 566 | ||
567 | int (*probe)(struct hid_device *dev, const struct hid_device_id *id); | 567 | int (*probe)(struct hid_device *dev, const struct hid_device_id *id); |
568 | void (*remove)(struct hid_device *dev); | 568 | void (*remove)(struct hid_device *dev); |
569 | 569 | ||
570 | const struct hid_report_id *report_table; | 570 | const struct hid_report_id *report_table; |
571 | int (*raw_event)(struct hid_device *hdev, struct hid_report *report, | 571 | int (*raw_event)(struct hid_device *hdev, struct hid_report *report, |
572 | u8 *data, int size); | 572 | u8 *data, int size); |
573 | const struct hid_usage_id *usage_table; | 573 | const struct hid_usage_id *usage_table; |
574 | int (*event)(struct hid_device *hdev, struct hid_field *field, | 574 | int (*event)(struct hid_device *hdev, struct hid_field *field, |
575 | struct hid_usage *usage, __s32 value); | 575 | struct hid_usage *usage, __s32 value); |
576 | 576 | ||
577 | void (*report_fixup)(struct hid_device *hdev, __u8 *buf, | 577 | void (*report_fixup)(struct hid_device *hdev, __u8 *buf, |
578 | unsigned int size); | 578 | unsigned int size); |
579 | 579 | ||
580 | int (*input_mapping)(struct hid_device *hdev, | 580 | int (*input_mapping)(struct hid_device *hdev, |
581 | struct hid_input *hidinput, struct hid_field *field, | 581 | struct hid_input *hidinput, struct hid_field *field, |
582 | struct hid_usage *usage, unsigned long **bit, int *max); | 582 | struct hid_usage *usage, unsigned long **bit, int *max); |
583 | int (*input_mapped)(struct hid_device *hdev, | 583 | int (*input_mapped)(struct hid_device *hdev, |
584 | struct hid_input *hidinput, struct hid_field *field, | 584 | struct hid_input *hidinput, struct hid_field *field, |
585 | struct hid_usage *usage, unsigned long **bit, int *max); | 585 | struct hid_usage *usage, unsigned long **bit, int *max); |
586 | /* private: */ | 586 | /* private: */ |
587 | struct device_driver driver; | 587 | struct device_driver driver; |
588 | }; | 588 | }; |
589 | 589 | ||
590 | /** | 590 | /** |
591 | * hid_ll_driver - low level driver callbacks | 591 | * hid_ll_driver - low level driver callbacks |
592 | * @start: called on probe to start the device | 592 | * @start: called on probe to start the device |
593 | * @stop: called on remove | 593 | * @stop: called on remove |
594 | * @open: called by input layer on open | 594 | * @open: called by input layer on open |
595 | * @close: called by input layer on close | 595 | * @close: called by input layer on close |
596 | * @hidinput_input_event: event input event (e.g. ff or leds) | 596 | * @hidinput_input_event: event input event (e.g. ff or leds) |
597 | * @parse: this method is called only once to parse the device data, | 597 | * @parse: this method is called only once to parse the device data, |
598 | * shouldn't allocate anything to not leak memory | 598 | * shouldn't allocate anything to not leak memory |
599 | */ | 599 | */ |
600 | struct hid_ll_driver { | 600 | struct hid_ll_driver { |
601 | int (*start)(struct hid_device *hdev); | 601 | int (*start)(struct hid_device *hdev); |
602 | void (*stop)(struct hid_device *hdev); | 602 | void (*stop)(struct hid_device *hdev); |
603 | 603 | ||
604 | int (*open)(struct hid_device *hdev); | 604 | int (*open)(struct hid_device *hdev); |
605 | void (*close)(struct hid_device *hdev); | 605 | void (*close)(struct hid_device *hdev); |
606 | 606 | ||
607 | int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, | 607 | int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, |
608 | unsigned int code, int value); | 608 | unsigned int code, int value); |
609 | 609 | ||
610 | int (*parse)(struct hid_device *hdev); | 610 | int (*parse)(struct hid_device *hdev); |
611 | }; | 611 | }; |
612 | 612 | ||
613 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ | 613 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ |
614 | /* We ignore a few input applications that are not widely used */ | 614 | /* We ignore a few input applications that are not widely used */ |
615 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) | 615 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) |
616 | 616 | ||
617 | /* HID core API */ | 617 | /* HID core API */ |
618 | 618 | ||
619 | #ifdef CONFIG_HID_DEBUG | 619 | #ifdef CONFIG_HID_DEBUG |
620 | extern int hid_debug; | 620 | extern int hid_debug; |
621 | #endif | 621 | #endif |
622 | 622 | ||
623 | extern int hid_add_device(struct hid_device *); | 623 | extern int hid_add_device(struct hid_device *); |
624 | extern void hid_destroy_device(struct hid_device *); | 624 | extern void hid_destroy_device(struct hid_device *); |
625 | 625 | ||
626 | extern int __must_check __hid_register_driver(struct hid_driver *, | 626 | extern int __must_check __hid_register_driver(struct hid_driver *, |
627 | struct module *, const char *mod_name); | 627 | struct module *, const char *mod_name); |
628 | static inline int __must_check hid_register_driver(struct hid_driver *driver) | 628 | static inline int __must_check hid_register_driver(struct hid_driver *driver) |
629 | { | 629 | { |
630 | return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); | 630 | return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); |
631 | } | 631 | } |
632 | extern void hid_unregister_driver(struct hid_driver *); | 632 | extern void hid_unregister_driver(struct hid_driver *); |
633 | 633 | ||
634 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 634 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
635 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | 635 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); |
636 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); | 636 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); |
637 | extern void hidinput_disconnect(struct hid_device *); | 637 | extern void hidinput_disconnect(struct hid_device *); |
638 | 638 | ||
639 | int hid_set_field(struct hid_field *, unsigned, __s32); | 639 | int hid_set_field(struct hid_field *, unsigned, __s32); |
640 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); | 640 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); |
641 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); | 641 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
642 | void hid_output_report(struct hid_report *report, __u8 *data); | 642 | void hid_output_report(struct hid_report *report, __u8 *data); |
643 | struct hid_device *hid_allocate_device(void); | 643 | struct hid_device *hid_allocate_device(void); |
644 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | 644 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
645 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | 645 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); |
646 | 646 | ||
647 | /** | 647 | /** |
648 | * hid_map_usage - map usage input bits | 648 | * hid_map_usage - map usage input bits |
649 | * | 649 | * |
650 | * @hidinput: hidinput which we are interested in | 650 | * @hidinput: hidinput which we are interested in |
651 | * @usage: usage to fill in | 651 | * @usage: usage to fill in |
652 | * @bit: pointer to input->{}bit (out parameter) | 652 | * @bit: pointer to input->{}bit (out parameter) |
653 | * @max: maximal valid usage->code to consider later (out parameter) | 653 | * @max: maximal valid usage->code to consider later (out parameter) |
654 | * @type: input event type (EV_KEY, EV_REL, ...) | 654 | * @type: input event type (EV_KEY, EV_REL, ...) |
655 | * @c: code which corresponds to this usage and type | 655 | * @c: code which corresponds to this usage and type |
656 | */ | 656 | */ |
657 | static inline void hid_map_usage(struct hid_input *hidinput, | 657 | static inline void hid_map_usage(struct hid_input *hidinput, |
658 | struct hid_usage *usage, unsigned long **bit, int *max, | 658 | struct hid_usage *usage, unsigned long **bit, int *max, |
659 | __u8 type, __u16 c) | 659 | __u8 type, __u16 c) |
660 | { | 660 | { |
661 | struct input_dev *input = hidinput->input; | 661 | struct input_dev *input = hidinput->input; |
662 | 662 | ||
663 | usage->type = type; | 663 | usage->type = type; |
664 | usage->code = c; | 664 | usage->code = c; |
665 | 665 | ||
666 | switch (type) { | 666 | switch (type) { |
667 | case EV_ABS: | 667 | case EV_ABS: |
668 | *bit = input->absbit; | 668 | *bit = input->absbit; |
669 | *max = ABS_MAX; | 669 | *max = ABS_MAX; |
670 | break; | 670 | break; |
671 | case EV_REL: | 671 | case EV_REL: |
672 | *bit = input->relbit; | 672 | *bit = input->relbit; |
673 | *max = REL_MAX; | 673 | *max = REL_MAX; |
674 | break; | 674 | break; |
675 | case EV_KEY: | 675 | case EV_KEY: |
676 | *bit = input->keybit; | 676 | *bit = input->keybit; |
677 | *max = KEY_MAX; | 677 | *max = KEY_MAX; |
678 | break; | 678 | break; |
679 | case EV_LED: | 679 | case EV_LED: |
680 | *bit = input->ledbit; | 680 | *bit = input->ledbit; |
681 | *max = LED_MAX; | 681 | *max = LED_MAX; |
682 | break; | 682 | break; |
683 | } | 683 | } |
684 | } | 684 | } |
685 | 685 | ||
686 | /** | 686 | /** |
687 | * hid_map_usage_clear - map usage input bits and clear the input bit | 687 | * hid_map_usage_clear - map usage input bits and clear the input bit |
688 | * | 688 | * |
689 | * The same as hid_map_usage, except the @c bit is also cleared in supported | 689 | * The same as hid_map_usage, except the @c bit is also cleared in supported |
690 | * bits (@bit). | 690 | * bits (@bit). |
691 | */ | 691 | */ |
692 | static inline void hid_map_usage_clear(struct hid_input *hidinput, | 692 | static inline void hid_map_usage_clear(struct hid_input *hidinput, |
693 | struct hid_usage *usage, unsigned long **bit, int *max, | 693 | struct hid_usage *usage, unsigned long **bit, int *max, |
694 | __u8 type, __u16 c) | 694 | __u8 type, __u16 c) |
695 | { | 695 | { |
696 | hid_map_usage(hidinput, usage, bit, max, type, c); | 696 | hid_map_usage(hidinput, usage, bit, max, type, c); |
697 | clear_bit(c, *bit); | 697 | clear_bit(c, *bit); |
698 | } | 698 | } |
699 | 699 | ||
700 | /** | 700 | /** |
701 | * hid_parse - parse HW reports | 701 | * hid_parse - parse HW reports |
702 | * | 702 | * |
703 | * @hdev: hid device | 703 | * @hdev: hid device |
704 | * | 704 | * |
705 | * Call this from probe after you set up the device (if needed). Your | 705 | * Call this from probe after you set up the device (if needed). Your |
706 | * report_fixup will be called (if non-NULL) after reading raw report from | 706 | * report_fixup will be called (if non-NULL) after reading raw report from |
707 | * device before passing it to hid layer for real parsing. | 707 | * device before passing it to hid layer for real parsing. |
708 | */ | 708 | */ |
709 | static inline int __must_check hid_parse(struct hid_device *hdev) | 709 | static inline int __must_check hid_parse(struct hid_device *hdev) |
710 | { | 710 | { |
711 | int ret; | 711 | int ret; |
712 | 712 | ||
713 | if (hdev->status & HID_STAT_PARSED) | 713 | if (hdev->status & HID_STAT_PARSED) |
714 | return 0; | 714 | return 0; |
715 | 715 | ||
716 | ret = hdev->ll_driver->parse(hdev); | 716 | ret = hdev->ll_driver->parse(hdev); |
717 | if (!ret) | 717 | if (!ret) |
718 | hdev->status |= HID_STAT_PARSED; | 718 | hdev->status |= HID_STAT_PARSED; |
719 | 719 | ||
720 | return ret; | 720 | return ret; |
721 | } | 721 | } |
722 | 722 | ||
723 | /** | 723 | /** |
724 | * hid_hw_start - start underlaying HW | 724 | * hid_hw_start - start underlaying HW |
725 | * | 725 | * |
726 | * @hdev: hid device | 726 | * @hdev: hid device |
727 | * @connect_mask: which outputs to connect, see HID_CONNECT_* | 727 | * @connect_mask: which outputs to connect, see HID_CONNECT_* |
728 | * | 728 | * |
729 | * Call this in probe function *after* hid_parse. This will setup HW buffers | 729 | * Call this in probe function *after* hid_parse. This will setup HW buffers |
730 | * and start the device (if not deffered to device open). hid_hw_stop must be | 730 | * and start the device (if not deffered to device open). hid_hw_stop must be |
731 | * called if this was successfull. | 731 | * called if this was successfull. |
732 | */ | 732 | */ |
733 | static inline int __must_check hid_hw_start(struct hid_device *hdev, | 733 | static inline int __must_check hid_hw_start(struct hid_device *hdev, |
734 | unsigned int connect_mask) | 734 | unsigned int connect_mask) |
735 | { | 735 | { |
736 | int ret = hdev->ll_driver->start(hdev); | 736 | int ret = hdev->ll_driver->start(hdev); |
737 | if (ret || !connect_mask) | 737 | if (ret || !connect_mask) |
738 | return ret; | 738 | return ret; |
739 | ret = hid_connect(hdev, connect_mask); | 739 | ret = hid_connect(hdev, connect_mask); |
740 | if (ret) | 740 | if (ret) |
741 | hdev->ll_driver->stop(hdev); | 741 | hdev->ll_driver->stop(hdev); |
742 | return ret; | 742 | return ret; |
743 | } | 743 | } |
744 | 744 | ||
745 | /** | 745 | /** |
746 | * hid_hw_stop - stop underlaying HW | 746 | * hid_hw_stop - stop underlaying HW |
747 | * | 747 | * |
748 | * @hdev: hid device | 748 | * @hdev: hid device |
749 | * | 749 | * |
750 | * This is usually called from remove function or from probe when something | 750 | * This is usually called from remove function or from probe when something |
751 | * failed and hid_hw_start was called already. | 751 | * failed and hid_hw_start was called already. |
752 | */ | 752 | */ |
753 | static inline void hid_hw_stop(struct hid_device *hdev) | 753 | static inline void hid_hw_stop(struct hid_device *hdev) |
754 | { | 754 | { |
755 | hdev->ll_driver->stop(hdev); | 755 | hdev->ll_driver->stop(hdev); |
756 | } | 756 | } |
757 | 757 | ||
758 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 758 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
759 | int interrupt); | 759 | int interrupt); |
760 | 760 | ||
761 | extern int hid_generic_init(void); | 761 | extern int hid_generic_init(void); |
762 | extern void hid_generic_exit(void); | 762 | extern void hid_generic_exit(void); |
763 | 763 | ||
764 | /* HID quirks API */ | 764 | /* HID quirks API */ |
765 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); | 765 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); |
766 | int usbhid_quirks_init(char **quirks_param); | 766 | int usbhid_quirks_init(char **quirks_param); |
767 | void usbhid_quirks_exit(void); | 767 | void usbhid_quirks_exit(void); |
768 | void usbhid_set_leds(struct hid_device *hid); | 768 | void usbhid_set_leds(struct hid_device *hid); |
769 | 769 | ||
770 | #ifdef CONFIG_HID_PID | 770 | #ifdef CONFIG_HID_PID |
771 | int hid_pidff_init(struct hid_device *hid); | 771 | int hid_pidff_init(struct hid_device *hid); |
772 | #else | 772 | #else |
773 | #define hid_pidff_init NULL | 773 | #define hid_pidff_init NULL |
774 | #endif | 774 | #endif |
775 | 775 | ||
776 | #ifdef CONFIG_HID_DEBUG | 776 | #ifdef CONFIG_HID_DEBUG |
777 | #define dbg_hid(format, arg...) if (hid_debug) \ | 777 | #define dbg_hid(format, arg...) if (hid_debug) \ |
778 | printk(KERN_DEBUG "%s: " format ,\ | 778 | printk(KERN_DEBUG "%s: " format ,\ |
779 | __FILE__ , ## arg) | 779 | __FILE__ , ## arg) |
780 | #define dbg_hid_line(format, arg...) if (hid_debug) \ | 780 | #define dbg_hid_line(format, arg...) if (hid_debug) \ |
781 | printk(format, ## arg) | 781 | printk(format, ## arg) |
782 | #else | 782 | #else |
783 | static inline int __attribute__((format(printf, 1, 2))) | 783 | static inline int __attribute__((format(printf, 1, 2))) |
784 | dbg_hid(const char *fmt, ...) | 784 | dbg_hid(const char *fmt, ...) |
785 | { | 785 | { |
786 | return 0; | 786 | return 0; |
787 | } | 787 | } |
788 | #define dbg_hid_line dbg_hid | 788 | #define dbg_hid_line dbg_hid |
789 | #endif /* HID_DEBUG */ | 789 | #endif /* HID_DEBUG */ |
790 | 790 | ||
791 | #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ | 791 | #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ |
792 | __FILE__ , ## arg) | 792 | __FILE__ , ## arg) |
793 | #endif /* HID_FF */ | 793 | #endif /* HID_FF */ |
794 | 794 | ||
795 | #ifdef __KERNEL__ | ||
796 | #ifdef CONFIG_HID_COMPAT | ||
797 | #define HID_COMPAT_LOAD_DRIVER(name) \ | ||
798 | /* prototype to avoid sparse warning */ \ | ||
799 | extern void hid_compat_##name(void); \ | ||
800 | void hid_compat_##name(void) { } \ | ||
801 | EXPORT_SYMBOL(hid_compat_##name) | ||
802 | #else | ||
803 | #define HID_COMPAT_LOAD_DRIVER(name) | ||
804 | #endif /* HID_COMPAT */ | ||
805 | #define HID_COMPAT_CALL_DRIVER(name) do { \ | ||
806 | extern void hid_compat_##name(void); \ | ||
807 | hid_compat_##name(); \ | ||
808 | } while (0) | ||
809 | #endif /* __KERNEL__ */ | ||
810 | |||
811 | #endif | 795 | #endif |
812 | 796 | ||
813 | 797 |