Commit bbd128b5acae85b2ef346e95cc5a729ac5252f19

Authored by Jiri Kosina

Merge branches '3m', 'egalax', 'logitech', 'magicmouse', 'ntrig' and 'roccat' into for-linus

Showing 20 changed files Side-by-side Diff

Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
  1 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_cpi
  2 +Date: August 2010
  3 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  4 +Description: It is possible to switch the cpi setting of the mouse with the
  5 + press of a button.
  6 + When read, this file returns the raw number of the actual cpi
  7 + setting reported by the mouse. This number has to be further
  8 + processed to receive the real dpi value.
  9 +
  10 + VALUE DPI
  11 + 1 400
  12 + 2 800
  13 + 4 1600
  14 +
  15 + This file is readonly.
  16 +
  17 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
  18 +Date: August 2010
  19 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  20 +Description: When read, this file returns the number of the actual profile in
  21 + range 0-4.
  22 + This file is readonly.
  23 +
  24 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
  25 +Date: August 2010
  26 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  27 +Description: When read, this file returns the raw integer version number of the
  28 + firmware reported by the mouse. Using the integer value eases
  29 + further usage in other programs. To receive the real version
  30 + number the decimal point has to be shifted 2 positions to the
  31 + left. E.g. a returned value of 138 means 1.38
  32 + This file is readonly.
  33 +
  34 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_settings
  35 +Date: August 2010
  36 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  37 +Description: The mouse can store 5 profiles which can be switched by the
  38 + press of a button. A profile is split in settings and buttons.
  39 + profile_settings holds informations like resolution, sensitivity
  40 + and light effects.
  41 + When written, this file lets one write the respective profile
  42 + settings back to the mouse. The data has to be 13 bytes long.
  43 + The mouse will reject invalid data.
  44 + Which profile to write is determined by the profile number
  45 + contained in the data.
  46 + This file is writeonly.
  47 +
  48 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_settings
  49 +Date: August 2010
  50 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  51 +Description: The mouse can store 5 profiles which can be switched by the
  52 + press of a button. A profile is split in settings and buttons.
  53 + profile_settings holds informations like resolution, sensitivity
  54 + and light effects.
  55 + When read, these files return the respective profile settings.
  56 + The returned data is 13 bytes in size.
  57 + This file is readonly.
  58 +
  59 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_buttons
  60 +Date: August 2010
  61 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  62 +Description: The mouse can store 5 profiles which can be switched by the
  63 + press of a button. A profile is split in settings and buttons.
  64 + profile_buttons holds informations about button layout.
  65 + When written, this file lets one write the respective profile
  66 + buttons back to the mouse. The data has to be 19 bytes long.
  67 + The mouse will reject invalid data.
  68 + Which profile to write is determined by the profile number
  69 + contained in the data.
  70 + This file is writeonly.
  71 +
  72 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_buttons
  73 +Date: August 2010
  74 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  75 +Description: The mouse can store 5 profiles which can be switched by the
  76 + press of a button. A profile is split in settings and buttons.
  77 + profile_buttons holds informations about button layout.
  78 + When read, these files return the respective profile buttons.
  79 + The returned data is 19 bytes in size.
  80 + This file is readonly.
  81 +
  82 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
  83 +Date: August 2010
  84 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  85 +Description: The integer value of this attribute ranges from 0-4.
  86 + When read, this attribute returns the number of the profile
  87 + that's active when the mouse is powered on.
  88 + This file is readonly.
  89 +
  90 +What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
  91 +Date: August 2010
  92 +Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
  93 +Description: When read, this file returns the settings stored in the mouse.
  94 + The size of the data is 3 bytes and holds information on the
  95 + startup_profile.
  96 + When written, this file lets write settings back to the mouse.
  97 + The data has to be 3 bytes long. The mouse will reject invalid
  98 + data.
Documentation/input/ntrig.txt
  1 +N-Trig touchscreen Driver
  2 +-------------------------
  3 + Copyright (c) 2008-2010 Rafi Rubin <rafi@seas.upenn.edu>
  4 + Copyright (c) 2009-2010 Stephane Chatty
  5 +
  6 +This driver provides support for N-Trig pen and multi-touch sensors. Single
  7 +and multi-touch events are translated to the appropriate protocols for
  8 +the hid and input systems. Pen events are sufficiently hid compliant and
  9 +are left to the hid core. The driver also provides additional filtering
  10 +and utility functions accessible with sysfs and module parameters.
  11 +
  12 +This driver has been reported to work properly with multiple N-Trig devices
  13 +attached.
  14 +
  15 +
  16 +Parameters
  17 +----------
  18 +
  19 +Note: values set at load time are global and will apply to all applicable
  20 +devices. Adjusting parameters with sysfs will override the load time values,
  21 +but only for that one device.
  22 +
  23 +The following parameters are used to configure filters to reduce noise:
  24 +
  25 +activate_slack number of fingers to ignore before processing events
  26 +
  27 +activation_height size threshold to activate immediately
  28 +activation_width
  29 +
  30 +min_height size threshold bellow which fingers are ignored
  31 +min_width both to decide activation and during activity
  32 +
  33 +deactivate_slack the number of "no contact" frames to ignore before
  34 + propagating the end of activity events
  35 +
  36 +When the last finger is removed from the device, it sends a number of empty
  37 +frames. By holding off on deactivation for a few frames we can tolerate false
  38 +erroneous disconnects, where the sensor may mistakenly not detect a finger that
  39 +is still present. Thus deactivate_slack addresses problems where a users might
  40 +see breaks in lines during drawing, or drop an object during a long drag.
  41 +
  42 +
  43 +Additional sysfs items
  44 +----------------------
  45 +
  46 +These nodes just provide easy access to the ranges reported by the device.
  47 +sensor_logical_height the range for positions reported during activity
  48 +sensor_logical_width
  49 +
  50 +sensor_physical_height internal ranges not used for normal events but
  51 +sensor_physical_width useful for tuning
  52 +
  53 +All N-Trig devices with product id of 1 report events in the ranges of
  54 +X: 0-9600
  55 +Y: 0-7200
  56 +However not all of these devices have the same physical dimensions. Most
  57 +seem to be 12" sensors (Dell Latitude XT and XT2 and the HP TX2), and
  58 +at least one model (Dell Studio 17) has a 17" sensor. The ratio of physical
  59 +to logical sizes is used to adjust the size based filter parameters.
  60 +
  61 +
  62 +Filtering
  63 +---------
  64 +
  65 +With the release of the early multi-touch firmwares it became increasingly
  66 +obvious that these sensors were prone to erroneous events. Users reported
  67 +seeing both inappropriately dropped contact and ghosts, contacts reported
  68 +where no finger was actually touching the screen.
  69 +
  70 +Deactivation slack helps prevent dropped contact for single touch use, but does
  71 +not address the problem of dropping one of more contacts while other contacts
  72 +are still active. Drops in the multi-touch context require additional
  73 +processing and should be handled in tandem with tacking.
  74 +
  75 +As observed ghost contacts are similar to actual use of the sensor, but they
  76 +seem to have different profiles. Ghost activity typically shows up as small
  77 +short lived touches. As such, I assume that the longer the continuous stream
  78 +of events the more likely those events are from a real contact, and that the
  79 +larger the size of each contact the more likely it is real. Balancing the
  80 +goals of preventing ghosts and accepting real events quickly (to minimize
  81 +user observable latency), the filter accumulates confidence for incoming
  82 +events until it hits thresholds and begins propagating. In the interest in
  83 +minimizing stored state as well as the cost of operations to make a decision,
  84 +I've kept that decision simple.
  85 +
  86 +Time is measured in terms of the number of fingers reported, not frames since
  87 +the probability of multiple simultaneous ghosts is expected to drop off
  88 +dramatically with increasing numbers. Rather than accumulate weight as a
  89 +function of size, I just use it as a binary threshold. A sufficiently large
  90 +contact immediately overrides the waiting period and leads to activation.
  91 +
  92 +Setting the activation size thresholds to large values will result in deciding
  93 +primarily on activation slack. If you see longer lived ghosts, turning up the
  94 +activation slack while reducing the size thresholds may suffice to eliminate
  95 +the ghosts while keeping the screen quite responsive to firm taps.
  96 +
  97 +Contacts continue to be filtered with min_height and min_width even after
  98 +the initial activation filter is satisfied. The intent is to provide
  99 +a mechanism for filtering out ghosts in the form of an extra finger while
  100 +you actually are using the screen. In practice this sort of ghost has
  101 +been far less problematic or relatively rare and I've left the defaults
  102 +set to 0 for both parameters, effectively turning off that filter.
  103 +
  104 +I don't know what the optimal values are for these filters. If the defaults
  105 +don't work for you, please play with the parameters. If you do find other
  106 +values more comfortable, I would appreciate feedback.
  107 +
  108 +The calibration of these devices does drift over time. If ghosts or contact
  109 +dropping worsen and interfere with the normal usage of your device, try
  110 +recalibrating it.
  111 +
  112 +
  113 +Calibration
  114 +-----------
  115 +
  116 +The N-Trig windows tools provide calibration and testing routines. Also an
  117 +unofficial unsupported set of user space tools including a calibrator is
  118 +available at:
  119 +http://code.launchpad.net/~rafi-seas/+junk/ntrig_calib
  120 +
  121 +
  122 +Tracking
  123 +--------
  124 +
  125 +As of yet, all tested N-Trig firmwares do not track fingers. When multiple
  126 +contacts are active they seem to be sorted primarily by Y position.
... ... @@ -220,12 +220,12 @@
220 220 force feedback.
221 221  
222 222 config LOGIRUMBLEPAD2_FF
223   - bool "Logitech Rumblepad 2 force feedback support"
  223 + bool "Logitech RumblePad/Rumblepad 2 force feedback support"
224 224 depends on HID_LOGITECH
225 225 select INPUT_FF_MEMLESS
226 226 help
227 227 Say Y here if you want to enable force feedback support for Logitech
228   - Rumblepad 2 devices.
  228 + RumblePad and Rumblepad 2 devices.
229 229  
230 230 config LOGIG940_FF
231 231 bool "Logitech Flight System G940 force feedback support"
... ... @@ -235,6 +235,14 @@
235 235 Say Y here if you want to enable force feedback support for Logitech
236 236 Flight System G940 devices.
237 237  
  238 +config LOGIWII_FF
  239 + bool "Logitech Speed Force Wireless force feedback support"
  240 + depends on HID_LOGITECH
  241 + select INPUT_FF_MEMLESS
  242 + help
  243 + Say Y here if you want to enable force feedback support for Logitech
  244 + Speed Force Wireless (Wii) devices.
  245 +
238 246 config HID_MAGICMOUSE
239 247 tristate "Apple MagicMouse multi-touch support"
240 248 depends on BT_HIDP
... ... @@ -375,6 +383,13 @@
375 383 select HID_ROCCAT
376 384 ---help---
377 385 Support for Roccat Kone mouse.
  386 +
  387 +config HID_ROCCAT_PYRA
  388 + tristate "Roccat Pyra mouse support"
  389 + depends on USB_HID
  390 + select HID_ROCCAT
  391 + ---help---
  392 + Support for Roccat Pyra mouse.
378 393  
379 394 config HID_SAMSUNG
380 395 tristate "Samsung InfraRed remote control or keyboards"
drivers/hid/Makefile
... ... @@ -21,6 +21,9 @@
21 21 ifdef CONFIG_LOGIG940_FF
22 22 hid-logitech-objs += hid-lg3ff.o
23 23 endif
  24 +ifdef CONFIG_LOGIWII_FF
  25 + hid-logitech-objs += hid-lg4ff.o
  26 +endif
24 27  
25 28 obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
26 29 obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
... ... @@ -52,6 +55,7 @@
52 55 obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
53 56 obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
54 57 obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
  58 +obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
55 59 obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
56 60 obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
57 61 obj-$(CONFIG_HID_SONY) += hid-sony.o
drivers/hid/hid-3m-pct.c
... ... @@ -2,6 +2,8 @@
2 2 * HID driver for 3M PCT multitouch panels
3 3 *
4 4 * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
  5 + * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
  6 + * Copyright (c) 2010 Canonical, Ltd.
5 7 *
6 8 */
7 9  
8 10  
9 11  
... ... @@ -24,15 +26,26 @@
24 26  
25 27 #include "hid-ids.h"
26 28  
  29 +#define MAX_SLOTS 60
  30 +#define MAX_TRKID USHRT_MAX
  31 +#define MAX_EVENTS 360
  32 +
  33 +/* estimated signal-to-noise ratios */
  34 +#define SN_MOVE 2048
  35 +#define SN_WIDTH 128
  36 +
27 37 struct mmm_finger {
28 38 __s32 x, y, w, h;
29   - __u8 rank;
  39 + __u16 id;
  40 + bool prev_touch;
30 41 bool touch, valid;
31 42 };
32 43  
33 44 struct mmm_data {
34   - struct mmm_finger f[10];
35   - __u8 curid, num;
  45 + struct mmm_finger f[MAX_SLOTS];
  46 + __u16 id;
  47 + __u8 curid;
  48 + __u8 nexp, nreal;
36 49 bool touch, valid;
37 50 };
38 51  
... ... @@ -40,6 +53,10 @@
40 53 struct hid_field *field, struct hid_usage *usage,
41 54 unsigned long **bit, int *max)
42 55 {
  56 + int f1 = field->logical_minimum;
  57 + int f2 = field->logical_maximum;
  58 + int df = f2 - f1;
  59 +
43 60 switch (usage->hid & HID_USAGE_PAGE) {
44 61  
45 62 case HID_UP_BUTTON:
46 63  
47 64  
48 65  
... ... @@ -50,18 +67,20 @@
50 67 case HID_GD_X:
51 68 hid_map_usage(hi, usage, bit, max,
52 69 EV_ABS, ABS_MT_POSITION_X);
  70 + input_set_abs_params(hi->input, ABS_MT_POSITION_X,
  71 + f1, f2, df / SN_MOVE, 0);
53 72 /* touchscreen emulation */
54 73 input_set_abs_params(hi->input, ABS_X,
55   - field->logical_minimum,
56   - field->logical_maximum, 0, 0);
  74 + f1, f2, df / SN_MOVE, 0);
57 75 return 1;
58 76 case HID_GD_Y:
59 77 hid_map_usage(hi, usage, bit, max,
60 78 EV_ABS, ABS_MT_POSITION_Y);
  79 + input_set_abs_params(hi->input, ABS_MT_POSITION_Y,
  80 + f1, f2, df / SN_MOVE, 0);
61 81 /* touchscreen emulation */
62 82 input_set_abs_params(hi->input, ABS_Y,
63   - field->logical_minimum,
64   - field->logical_maximum, 0, 0);
  83 + f1, f2, df / SN_MOVE, 0);
65 84 return 1;
66 85 }
67 86 return 0;
68 87  
69 88  
70 89  
71 90  
72 91  
... ... @@ -81,21 +100,31 @@
81 100 case HID_DG_TIPSWITCH:
82 101 /* touchscreen emulation */
83 102 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
  103 + input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
84 104 return 1;
85 105 case HID_DG_WIDTH:
86 106 hid_map_usage(hi, usage, bit, max,
87 107 EV_ABS, ABS_MT_TOUCH_MAJOR);
  108 + input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR,
  109 + f1, f2, df / SN_WIDTH, 0);
88 110 return 1;
89 111 case HID_DG_HEIGHT:
90 112 hid_map_usage(hi, usage, bit, max,
91 113 EV_ABS, ABS_MT_TOUCH_MINOR);
  114 + input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR,
  115 + f1, f2, df / SN_WIDTH, 0);
92 116 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
93   - 1, 1, 0, 0);
  117 + 0, 1, 0, 0);
94 118 return 1;
95 119 case HID_DG_CONTACTID:
96   - field->logical_maximum = 59;
  120 + field->logical_maximum = MAX_TRKID;
97 121 hid_map_usage(hi, usage, bit, max,
98 122 EV_ABS, ABS_MT_TRACKING_ID);
  123 + input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
  124 + 0, MAX_TRKID, 0, 0);
  125 + if (!hi->input->mt)
  126 + input_mt_create_slots(hi->input, MAX_SLOTS);
  127 + input_set_events_per_packet(hi->input, MAX_EVENTS);
99 128 return 1;
100 129 }
101 130 /* let hid-input decide for the others */
102 131  
... ... @@ -113,10 +142,10 @@
113 142 struct hid_field *field, struct hid_usage *usage,
114 143 unsigned long **bit, int *max)
115 144 {
  145 + /* tell hid-input to skip setup of these event types */
116 146 if (usage->type == EV_KEY || usage->type == EV_ABS)
117   - clear_bit(usage->code, *bit);
118   -
119   - return 0;
  147 + set_bit(usage->type, hi->input->evbit);
  148 + return -1;
120 149 }
121 150  
122 151 /*
123 152  
124 153  
125 154  
126 155  
127 156  
128 157  
129 158  
130 159  
131 160  
... ... @@ -126,70 +155,49 @@
126 155 static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
127 156 {
128 157 struct mmm_finger *oldest = 0;
129   - bool pressed = false, released = false;
130 158 int i;
131   -
132   - /*
133   - * we need to iterate on all fingers to decide if we have a press
134   - * or a release event in our touchscreen emulation.
135   - */
136   - for (i = 0; i < 10; ++i) {
  159 + for (i = 0; i < MAX_SLOTS; ++i) {
137 160 struct mmm_finger *f = &md->f[i];
138 161 if (!f->valid) {
139 162 /* this finger is just placeholder data, ignore */
140   - } else if (f->touch) {
  163 + continue;
  164 + }
  165 + input_mt_slot(input, i);
  166 + if (f->touch) {
141 167 /* this finger is on the screen */
142 168 int wide = (f->w > f->h);
143   - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i);
  169 + /* divided by two to match visual scale of touch */
  170 + int major = max(f->w, f->h) >> 1;
  171 + int minor = min(f->w, f->h) >> 1;
  172 +
  173 + if (!f->prev_touch)
  174 + f->id = md->id++;
  175 + input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
144 176 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
145 177 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
146 178 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
147   - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR,
148   - wide ? f->w : f->h);
149   - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR,
150   - wide ? f->h : f->w);
151   - input_mt_sync(input);
152   - /*
153   - * touchscreen emulation: maintain the age rank
154   - * of this finger, decide if we have a press
155   - */
156   - if (f->rank == 0) {
157   - f->rank = ++(md->num);
158   - if (f->rank == 1)
159   - pressed = true;
160   - }
161   - if (f->rank == 1)
  179 + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
  180 + input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
  181 + /* touchscreen emulation: pick the oldest contact */
  182 + if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
162 183 oldest = f;
163 184 } else {
164 185 /* this finger took off the screen */
165   - /* touchscreen emulation: maintain age rank of others */
166   - int j;
167   -
168   - for (j = 0; j < 10; ++j) {
169   - struct mmm_finger *g = &md->f[j];
170   - if (g->rank > f->rank) {
171   - g->rank--;
172   - if (g->rank == 1)
173   - oldest = g;
174   - }
175   - }
176   - f->rank = 0;
177   - --(md->num);
178   - if (md->num == 0)
179   - released = true;
  186 + input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
180 187 }
  188 + f->prev_touch = f->touch;
181 189 f->valid = 0;
182 190 }
183 191  
184 192 /* touchscreen emulation */
185 193 if (oldest) {
186   - if (pressed)
187   - input_event(input, EV_KEY, BTN_TOUCH, 1);
  194 + input_event(input, EV_KEY, BTN_TOUCH, 1);
188 195 input_event(input, EV_ABS, ABS_X, oldest->x);
189 196 input_event(input, EV_ABS, ABS_Y, oldest->y);
190   - } else if (released) {
  197 + } else {
191 198 input_event(input, EV_KEY, BTN_TOUCH, 0);
192 199 }
  200 + input_sync(input);
193 201 }
194 202  
195 203 /*
196 204  
... ... @@ -223,10 +231,12 @@
223 231 md->f[md->curid].h = value;
224 232 break;
225 233 case HID_DG_CONTACTID:
  234 + value = clamp_val(value, 0, MAX_SLOTS - 1);
226 235 if (md->valid) {
227 236 md->curid = value;
228 237 md->f[value].touch = md->touch;
229 238 md->f[value].valid = 1;
  239 + md->nreal++;
230 240 }
231 241 break;
232 242 case HID_GD_X:
... ... @@ -238,7 +248,12 @@
238 248 md->f[md->curid].y = value;
239 249 break;
240 250 case HID_DG_CONTACTCOUNT:
241   - mmm_filter_event(md, input);
  251 + if (value)
  252 + md->nexp = value;
  253 + if (md->nreal >= md->nexp) {
  254 + mmm_filter_event(md, input);
  255 + md->nreal = 0;
  256 + }
242 257 break;
243 258 }
244 259 }
... ... @@ -254,6 +269,8 @@
254 269 {
255 270 int ret;
256 271 struct mmm_data *md;
  272 +
  273 + hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
257 274  
258 275 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
259 276 if (!md) {
drivers/hid/hid-core.c
... ... @@ -1249,6 +1249,7 @@
1249 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1250 1250 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
1251 1251 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
  1252 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
1252 1253 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
1253 1254 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
1254 1255 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
... ... @@ -1328,6 +1329,7 @@
1328 1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
1329 1330 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
1330 1331 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
  1332 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
1331 1333 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
1332 1334 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
1333 1335 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
... ... @@ -1337,6 +1339,7 @@
1337 1339 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
1338 1340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
1339 1341 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
  1342 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
1340 1343 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1341 1344 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1342 1345 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
... ... @@ -1372,6 +1375,7 @@
1372 1375 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1373 1376 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1374 1377 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
  1378 + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1375 1379 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1376 1380 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1377 1381 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
drivers/hid/hid-egalax.c
... ... @@ -31,7 +31,7 @@
31 31 bool first; /* is this the first finger in the frame? */
32 32 bool valid; /* valid finger data, or just placeholder? */
33 33 bool activity; /* at least one active finger previously? */
34   - __u16 lastx, lasty; /* latest valid (x, y) in the frame */
  34 + __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
35 35 };
36 36  
37 37 static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
... ... @@ -79,6 +79,10 @@
79 79 case HID_DG_TIPPRESSURE:
80 80 hid_map_usage(hi, usage, bit, max,
81 81 EV_ABS, ABS_MT_PRESSURE);
  82 + /* touchscreen emulation */
  83 + input_set_abs_params(hi->input, ABS_PRESSURE,
  84 + field->logical_minimum,
  85 + field->logical_maximum, 0, 0);
82 86 return 1;
83 87 }
84 88 return 0;
... ... @@ -109,8 +113,8 @@
109 113 if (td->valid) {
110 114 /* emit multitouch events */
111 115 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
112   - input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
113   - input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
  116 + input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
  117 + input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
114 118 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
115 119  
116 120 input_mt_sync(input);
... ... @@ -121,6 +125,7 @@
121 125 */
122 126 td->lastx = td->x;
123 127 td->lasty = td->y;
  128 + td->lastz = td->z;
124 129 }
125 130  
126 131 /*
... ... @@ -129,8 +134,9 @@
129 134 * the oldest on the panel, the one we want for single touch
130 135 */
131 136 if (!td->first && td->activity) {
132   - input_event(input, EV_ABS, ABS_X, td->lastx);
133   - input_event(input, EV_ABS, ABS_Y, td->lasty);
  137 + input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
  138 + input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
  139 + input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
134 140 }
135 141  
136 142 if (!td->valid) {
drivers/hid/hid-ids.h
... ... @@ -64,6 +64,7 @@
64 64 #define USB_VENDOR_ID_APPLE 0x05ac
65 65 #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
66 66 #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
  67 +#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
67 68 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
68 69 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
69 70 #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
... ... @@ -345,6 +346,7 @@
345 346 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
346 347 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
347 348 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
  349 +#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
348 350 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
349 351 #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
350 352 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
... ... @@ -356,6 +358,7 @@
356 358 #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
357 359 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
358 360 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
  361 +#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
359 362 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
360 363 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c
361 364 #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
... ... @@ -468,6 +471,8 @@
468 471  
469 472 #define USB_VENDOR_ID_ROCCAT 0x1e7d
470 473 #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
  474 +#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
  475 +#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
471 476  
472 477 #define USB_VENDOR_ID_SAITEK 0x06a3
473 478 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
drivers/hid/hid-input.c
... ... @@ -739,6 +739,9 @@
739 739 {
740 740 struct hid_input *hidinput;
741 741  
  742 + if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC)
  743 + return;
  744 +
742 745 list_for_each_entry(hidinput, &hid->inputs, list)
743 746 input_sync(hidinput->input);
744 747 }
drivers/hid/hid-lg.c
... ... @@ -7,6 +7,7 @@
7 7 * Copyright (c) 2006-2007 Jiri Kosina
8 8 * Copyright (c) 2007 Paul Walmsley
9 9 * Copyright (c) 2008 Jiri Slaby
  10 + * Copyright (c) 2010 Hendrik Iben
10 11 */
11 12  
12 13 /*
... ... @@ -19,6 +20,9 @@
19 20 #include <linux/device.h>
20 21 #include <linux/hid.h>
21 22 #include <linux/module.h>
  23 +#include <linux/random.h>
  24 +#include <linux/sched.h>
  25 +#include <linux/wait.h>
22 26  
23 27 #include "hid-ids.h"
24 28 #include "hid-lg.h"
... ... @@ -35,6 +39,7 @@
35 39 #define LG_FF2 0x400
36 40 #define LG_RDESC_REL_ABS 0x800
37 41 #define LG_FF3 0x1000
  42 +#define LG_FF4 0x2000
38 43  
39 44 /*
40 45 * Certain Logitech keyboards send in report #3 keys which are far
... ... @@ -60,6 +65,17 @@
60 65 "report descriptor\n");
61 66 rdesc[33] = rdesc[50] = 0x02;
62 67 }
  68 +
  69 + if ((quirks & LG_FF4) && rsize >= 101 &&
  70 + rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
  71 + rdesc[47] == 0x05 && rdesc[48] == 0x09) {
  72 + dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless "
  73 + "button descriptor\n");
  74 + rdesc[41] = 0x05;
  75 + rdesc[42] = 0x09;
  76 + rdesc[47] = 0x95;
  77 + rdesc[48] = 0x0B;
  78 + }
63 79 }
64 80  
65 81 #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
66 82  
... ... @@ -285,12 +301,33 @@
285 301 goto err_free;
286 302 }
287 303  
  304 + if (quirks & LG_FF4) {
  305 + unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  306 +
  307 + ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
  308 +
  309 + if (ret >= 0) {
  310 + /* insert a little delay of 10 jiffies ~ 40ms */
  311 + wait_queue_head_t wait;
  312 + init_waitqueue_head (&wait);
  313 + wait_event_interruptible_timeout(wait, 0, 10);
  314 +
  315 + /* Select random Address */
  316 + buf[1] = 0xB2;
  317 + get_random_bytes(&buf[2], 2);
  318 +
  319 + ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
  320 + }
  321 + }
  322 +
288 323 if (quirks & LG_FF)
289 324 lgff_init(hdev);
290 325 if (quirks & LG_FF2)
291 326 lg2ff_init(hdev);
292 327 if (quirks & LG_FF3)
293 328 lg3ff_init(hdev);
  329 + if (quirks & LG_FF4)
  330 + lg4ff_init(hdev);
294 331  
295 332 return 0;
296 333 err_free:
... ... @@ -325,6 +362,8 @@
325 362 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
326 363 .driver_data = LG_NOGET | LG_FF },
327 364  
  365 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
  366 + .driver_data = LG_FF2 },
328 367 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
329 368 .driver_data = LG_FF },
330 369 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
... ... @@ -339,6 +378,8 @@
339 378 .driver_data = LG_FF },
340 379 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
341 380 .driver_data = LG_FF },
  381 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
  382 + .driver_data = LG_FF4 },
342 383 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
343 384 .driver_data = LG_FF },
344 385 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
drivers/hid/hid-lg.h
... ... @@ -19,5 +19,11 @@
19 19 static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
20 20 #endif
21 21  
  22 +#ifdef CONFIG_LOGIWII_FF
  23 +int lg4ff_init(struct hid_device *hdev);
  24 +#else
  25 +static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
  26 +#endif
  27 +
22 28 #endif
drivers/hid/hid-lg2ff.c
1 1 /*
2   - * Force feedback support for Logitech Rumblepad 2
  2 + * Force feedback support for Logitech RumblePad and Rumblepad 2
3 3 *
4 4 * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
5 5 */
... ... @@ -110,7 +110,7 @@
110 110  
111 111 usbhid_submit_report(hid, report, USB_DIR_OUT);
112 112  
113   - dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by "
  113 + dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by "
114 114 "Anssi Hannula <anssi.hannula@gmail.com>\n");
115 115  
116 116 return 0;
drivers/hid/hid-lg4ff.c
  1 +/*
  2 + * Force feedback support for Logitech Speed Force Wireless
  3 + *
  4 + * http://wiibrew.org/wiki/Logitech_USB_steering_wheel
  5 + *
  6 + * Copyright (c) 2010 Simon Wood <simon@mungewell.org>
  7 + */
  8 +
  9 +/*
  10 + * This program is free software; you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License as published by
  12 + * the Free Software Foundation; either version 2 of the License, or
  13 + * (at your option) any later version.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program; if not, write to the Free Software
  22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23 + */
  24 +
  25 +
  26 +#include <linux/input.h>
  27 +#include <linux/usb.h>
  28 +#include <linux/hid.h>
  29 +
  30 +#include "usbhid/usbhid.h"
  31 +#include "hid-lg.h"
  32 +
  33 +struct lg4ff_device {
  34 + struct hid_report *report;
  35 +};
  36 +
  37 +static const signed short ff4_wheel_ac[] = {
  38 + FF_CONSTANT,
  39 + FF_AUTOCENTER,
  40 + -1
  41 +};
  42 +
  43 +static int hid_lg4ff_play(struct input_dev *dev, void *data,
  44 + struct ff_effect *effect)
  45 +{
  46 + struct hid_device *hid = input_get_drvdata(dev);
  47 + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
  48 + struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
  49 + int x;
  50 +
  51 +#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
  52 +
  53 + switch (effect->type) {
  54 + case FF_CONSTANT:
  55 + x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */
  56 + CLAMP(x);
  57 + report->field[0]->value[0] = 0x11; /* Slot 1 */
  58 + report->field[0]->value[1] = 0x10;
  59 + report->field[0]->value[2] = x;
  60 + report->field[0]->value[3] = 0x00;
  61 + report->field[0]->value[4] = 0x00;
  62 + report->field[0]->value[5] = 0x08;
  63 + report->field[0]->value[6] = 0x00;
  64 + dbg_hid("Autocenter, x=0x%02X\n", x);
  65 +
  66 + usbhid_submit_report(hid, report, USB_DIR_OUT);
  67 + break;
  68 + }
  69 + return 0;
  70 +}
  71 +
  72 +static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude)
  73 +{
  74 + struct hid_device *hid = input_get_drvdata(dev);
  75 + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
  76 + struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
  77 + __s32 *value = report->field[0]->value;
  78 +
  79 + *value++ = 0xfe;
  80 + *value++ = 0x0d;
  81 + *value++ = 0x07;
  82 + *value++ = 0x07;
  83 + *value++ = (magnitude >> 8) & 0xff;
  84 + *value++ = 0x00;
  85 + *value = 0x00;
  86 +
  87 + usbhid_submit_report(hid, report, USB_DIR_OUT);
  88 +}
  89 +
  90 +
  91 +int lg4ff_init(struct hid_device *hid)
  92 +{
  93 + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
  94 + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
  95 + struct input_dev *dev = hidinput->input;
  96 + struct hid_report *report;
  97 + struct hid_field *field;
  98 + const signed short *ff_bits = ff4_wheel_ac;
  99 + int error;
  100 + int i;
  101 +
  102 + /* Find the report to use */
  103 + if (list_empty(report_list)) {
  104 + err_hid("No output report found");
  105 + return -1;
  106 + }
  107 +
  108 + /* Check that the report looks ok */
  109 + report = list_entry(report_list->next, struct hid_report, list);
  110 + if (!report) {
  111 + err_hid("NULL output report");
  112 + return -1;
  113 + }
  114 +
  115 + field = report->field[0];
  116 + if (!field) {
  117 + err_hid("NULL field");
  118 + return -1;
  119 + }
  120 +
  121 + for (i = 0; ff_bits[i] >= 0; i++)
  122 + set_bit(ff_bits[i], dev->ffbit);
  123 +
  124 + error = input_ff_create_memless(dev, NULL, hid_lg4ff_play);
  125 +
  126 + if (error)
  127 + return error;
  128 +
  129 + if (test_bit(FF_AUTOCENTER, dev->ffbit))
  130 + dev->ff->set_autocenter = hid_lg4ff_set_autocenter;
  131 +
  132 + dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by "
  133 + "Simon Wood <simon@mungewell.org>\n");
  134 + return 0;
  135 +}
drivers/hid/hid-magicmouse.c
... ... @@ -2,6 +2,7 @@
2 2 * Apple "Magic" Wireless Mouse driver
3 3 *
4 4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
  5 + * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
5 6 */
6 7  
7 8 /*
... ... @@ -53,7 +54,9 @@
53 54 module_param(report_undeciphered, bool, 0644);
54 55 MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
55 56  
56   -#define TOUCH_REPORT_ID 0x29
  57 +#define TRACKPAD_REPORT_ID 0x28
  58 +#define MOUSE_REPORT_ID 0x29
  59 +#define DOUBLE_REPORT_ID 0xf7
57 60 /* These definitions are not precise, but they're close enough. (Bits
58 61 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
59 62 * to be some kind of bit mask -- 0x20 may be a near-field reading,
60 63  
... ... @@ -67,15 +70,19 @@
67 70  
68 71 #define SCROLL_ACCEL_DEFAULT 7
69 72  
  73 +/* Single touch emulation should only begin when no touches are currently down.
  74 + * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
  75 + * are down and the touch providing for single touch emulation is lifted,
  76 + * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
  77 + * occuring, single_touch_id corresponds with the tracking id of the touch used.
  78 + */
  79 +#define NO_TOUCHES -1
  80 +#define SINGLE_TOUCH_UP -2
  81 +
70 82 /**
71 83 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
72 84 * @input: Input device through which we report events.
73 85 * @quirks: Currently unused.
74   - * @last_timestamp: Timestamp from most recent (18-bit) touch report
75   - * (units of milliseconds over short windows, but seems to
76   - * increase faster when there are no touches).
77   - * @delta_time: 18-bit difference between the two most recent touch
78   - * reports from the mouse.
79 86 * @ntouches: Number of touches in most recent touch report.
80 87 * @scroll_accel: Number of consecutive scroll motions.
81 88 * @scroll_jiffies: Time of last scroll motion.
... ... @@ -86,8 +93,6 @@
86 93 struct input_dev *input;
87 94 unsigned long quirks;
88 95  
89   - int last_timestamp;
90   - int delta_time;
91 96 int ntouches;
92 97 int scroll_accel;
93 98 unsigned long scroll_jiffies;
94 99  
... ... @@ -98,9 +103,9 @@
98 103 short scroll_x;
99 104 short scroll_y;
100 105 u8 size;
101   - u8 down;
102 106 } touches[16];
103 107 int tracking_ids[16];
  108 + int single_touch_id;
104 109 };
105 110  
106 111 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
107 112  
108 113  
... ... @@ -166,18 +171,35 @@
166 171 static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
167 172 {
168 173 struct input_dev *input = msc->input;
169   - __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24;
170   - int misc = tdata[5] | tdata[6] << 8;
171   - int id = (misc >> 6) & 15;
172   - int x = x_y << 12 >> 20;
173   - int y = -(x_y >> 20);
174   - int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE;
  174 + int id, x, y, size, orientation, touch_major, touch_minor, state, down;
175 175  
  176 + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  177 + id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
  178 + x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
  179 + y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
  180 + size = tdata[5] & 0x3f;
  181 + orientation = (tdata[6] >> 2) - 32;
  182 + touch_major = tdata[3];
  183 + touch_minor = tdata[4];
  184 + state = tdata[7] & TOUCH_STATE_MASK;
  185 + down = state != TOUCH_STATE_NONE;
  186 + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  187 + id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
  188 + x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
  189 + y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
  190 + size = tdata[6] & 0x3f;
  191 + orientation = (tdata[7] >> 2) - 32;
  192 + touch_major = tdata[4];
  193 + touch_minor = tdata[5];
  194 + state = tdata[8] & TOUCH_STATE_MASK;
  195 + down = state != TOUCH_STATE_NONE;
  196 + }
  197 +
176 198 /* Store tracking ID and other fields. */
177 199 msc->tracking_ids[raw_id] = id;
178 200 msc->touches[id].x = x;
179 201 msc->touches[id].y = y;
180   - msc->touches[id].size = misc & 63;
  202 + msc->touches[id].size = size;
181 203  
182 204 /* If requested, emulate a scroll wheel by detecting small
183 205 * vertical touch motions.
... ... @@ -188,7 +210,7 @@
188 210 int step_y = msc->touches[id].scroll_y - y;
189 211  
190 212 /* Calculate and apply the scroll motion. */
191   - switch (tdata[7] & TOUCH_STATE_MASK) {
  213 + switch (state) {
192 214 case TOUCH_STATE_START:
193 215 msc->touches[id].scroll_x = x;
194 216 msc->touches[id].scroll_y = y;
195 217  
196 218  
197 219  
... ... @@ -222,21 +244,28 @@
222 244 }
223 245 }
224 246  
  247 + if (down) {
  248 + msc->ntouches++;
  249 + if (msc->single_touch_id == NO_TOUCHES)
  250 + msc->single_touch_id = id;
  251 + } else if (msc->single_touch_id == id)
  252 + msc->single_touch_id = SINGLE_TOUCH_UP;
  253 +
225 254 /* Generate the input events for this touch. */
226 255 if (report_touches && down) {
227   - int orientation = (misc >> 10) - 32;
228   -
229   - msc->touches[id].down = 1;
230   -
231 256 input_report_abs(input, ABS_MT_TRACKING_ID, id);
232   - input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
233   - input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
  257 + input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
  258 + input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
234 259 input_report_abs(input, ABS_MT_ORIENTATION, orientation);
235 260 input_report_abs(input, ABS_MT_POSITION_X, x);
236 261 input_report_abs(input, ABS_MT_POSITION_Y, y);
237 262  
238   - if (report_undeciphered)
239   - input_event(input, EV_MSC, MSC_RAW, tdata[7]);
  263 + if (report_undeciphered) {
  264 + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
  265 + input_event(input, EV_MSC, MSC_RAW, tdata[7]);
  266 + else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  267 + input_event(input, EV_MSC, MSC_RAW, tdata[8]);
  268 + }
240 269  
241 270 input_mt_sync(input);
242 271 }
243 272  
244 273  
245 274  
246 275  
247 276  
248 277  
... ... @@ -247,39 +276,43 @@
247 276 {
248 277 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
249 278 struct input_dev *input = msc->input;
250   - int x, y, ts, ii, clicks, last_up;
  279 + int x = 0, y = 0, ii, clicks = 0, npoints;
251 280  
252 281 switch (data[0]) {
253   - case 0x10:
254   - if (size != 6)
  282 + case TRACKPAD_REPORT_ID:
  283 + /* Expect four bytes of prefix, and N*9 bytes of touch data. */
  284 + if (size < 4 || ((size - 4) % 9) != 0)
255 285 return 0;
256   - x = (__s16)(data[2] | data[3] << 8);
257   - y = (__s16)(data[4] | data[5] << 8);
  286 + npoints = (size - 4) / 9;
  287 + msc->ntouches = 0;
  288 + for (ii = 0; ii < npoints; ii++)
  289 + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
  290 +
  291 + /* We don't need an MT sync here because trackpad emits a
  292 + * BTN_TOUCH event in a new frame when all touches are released.
  293 + */
  294 + if (msc->ntouches == 0)
  295 + msc->single_touch_id = NO_TOUCHES;
  296 +
258 297 clicks = data[1];
  298 +
  299 + /* The following bits provide a device specific timestamp. They
  300 + * are unused here.
  301 + *
  302 + * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
  303 + */
259 304 break;
260   - case TOUCH_REPORT_ID:
  305 + case MOUSE_REPORT_ID:
261 306 /* Expect six bytes of prefix, and N*8 bytes of touch data. */
262 307 if (size < 6 || ((size - 6) % 8) != 0)
263 308 return 0;
264   - ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
265   - msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff;
266   - msc->last_timestamp = ts;
267   - msc->ntouches = (size - 6) / 8;
268   - for (ii = 0; ii < msc->ntouches; ii++)
  309 + npoints = (size - 6) / 8;
  310 + msc->ntouches = 0;
  311 + for (ii = 0; ii < npoints; ii++)
269 312 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
270 313  
271   - if (report_touches) {
272   - last_up = 1;
273   - for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) {
274   - if (msc->touches[ii].down) {
275   - last_up = 0;
276   - msc->touches[ii].down = 0;
277   - }
278   - }
279   - if (last_up) {
280   - input_mt_sync(input);
281   - }
282   - }
  314 + if (report_touches && msc->ntouches == 0)
  315 + input_mt_sync(input);
283 316  
284 317 /* When emulating three-button mode, it is important
285 318 * to have the current touch information before
286 319  
287 320  
288 321  
289 322  
290 323  
291 324  
... ... @@ -288,68 +321,72 @@
288 321 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
289 322 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
290 323 clicks = data[3];
  324 +
  325 + /* The following bits provide a device specific timestamp. They
  326 + * are unused here.
  327 + *
  328 + * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
  329 + */
291 330 break;
292   - case 0x20: /* Theoretically battery status (0-100), but I have
293   - * never seen it -- maybe it is only upon request.
294   - */
295   - case 0x60: /* Unknown, maybe laser on/off. */
296   - case 0x61: /* Laser reflection status change.
297   - * data[1]: 0 = spotted, 1 = lost
298   - */
  331 + case DOUBLE_REPORT_ID:
  332 + /* Sometimes the trackpad sends two touch reports in one
  333 + * packet.
  334 + */
  335 + magicmouse_raw_event(hdev, report, data + 2, data[1]);
  336 + magicmouse_raw_event(hdev, report, data + 2 + data[1],
  337 + size - 2 - data[1]);
  338 + break;
299 339 default:
300 340 return 0;
301 341 }
302 342  
303   - magicmouse_emit_buttons(msc, clicks & 3);
304   - input_report_rel(input, REL_X, x);
305   - input_report_rel(input, REL_Y, y);
  343 + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  344 + magicmouse_emit_buttons(msc, clicks & 3);
  345 + input_report_rel(input, REL_X, x);
  346 + input_report_rel(input, REL_Y, y);
  347 + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  348 + input_report_key(input, BTN_MOUSE, clicks & 1);
  349 + input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
  350 + input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
  351 + input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
  352 + input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
  353 + input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
  354 + if (msc->single_touch_id >= 0) {
  355 + input_report_abs(input, ABS_X,
  356 + msc->touches[msc->single_touch_id].x);
  357 + input_report_abs(input, ABS_Y,
  358 + msc->touches[msc->single_touch_id].y);
  359 + }
  360 + }
  361 +
306 362 input_sync(input);
307 363 return 1;
308 364 }
309 365  
310   -static int magicmouse_input_open(struct input_dev *dev)
311   -{
312   - struct hid_device *hid = input_get_drvdata(dev);
313   -
314   - return hid->ll_driver->open(hid);
315   -}
316   -
317   -static void magicmouse_input_close(struct input_dev *dev)
318   -{
319   - struct hid_device *hid = input_get_drvdata(dev);
320   -
321   - hid->ll_driver->close(hid);
322   -}
323   -
324 366 static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
325 367 {
326   - input_set_drvdata(input, hdev);
327   - input->event = hdev->ll_driver->hidinput_input_event;
328   - input->open = magicmouse_input_open;
329   - input->close = magicmouse_input_close;
330   -
331   - input->name = hdev->name;
332   - input->phys = hdev->phys;
333   - input->uniq = hdev->uniq;
334   - input->id.bustype = hdev->bus;
335   - input->id.vendor = hdev->vendor;
336   - input->id.product = hdev->product;
337   - input->id.version = hdev->version;
338   - input->dev.parent = hdev->dev.parent;
339   -
340 368 __set_bit(EV_KEY, input->evbit);
341   - __set_bit(BTN_LEFT, input->keybit);
342   - __set_bit(BTN_RIGHT, input->keybit);
343   - if (emulate_3button)
344   - __set_bit(BTN_MIDDLE, input->keybit);
345   - __set_bit(BTN_TOOL_FINGER, input->keybit);
346 369  
347   - __set_bit(EV_REL, input->evbit);
348   - __set_bit(REL_X, input->relbit);
349   - __set_bit(REL_Y, input->relbit);
350   - if (emulate_scroll_wheel) {
351   - __set_bit(REL_WHEEL, input->relbit);
352   - __set_bit(REL_HWHEEL, input->relbit);
  370 + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  371 + __set_bit(BTN_LEFT, input->keybit);
  372 + __set_bit(BTN_RIGHT, input->keybit);
  373 + if (emulate_3button)
  374 + __set_bit(BTN_MIDDLE, input->keybit);
  375 +
  376 + __set_bit(EV_REL, input->evbit);
  377 + __set_bit(REL_X, input->relbit);
  378 + __set_bit(REL_Y, input->relbit);
  379 + if (emulate_scroll_wheel) {
  380 + __set_bit(REL_WHEEL, input->relbit);
  381 + __set_bit(REL_HWHEEL, input->relbit);
  382 + }
  383 + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  384 + __set_bit(BTN_MOUSE, input->keybit);
  385 + __set_bit(BTN_TOOL_FINGER, input->keybit);
  386 + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
  387 + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
  388 + __set_bit(BTN_TOOL_QUADTAP, input->keybit);
  389 + __set_bit(BTN_TOUCH, input->keybit);
353 390 }
354 391  
355 392 if (report_touches) {
356 393  
... ... @@ -359,16 +396,26 @@
359 396 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
360 397 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
361 398 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
362   - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358,
363   - 4, 0);
  399 +
364 400 /* Note: Touch Y position from the device is inverted relative
365 401 * to how pointer motion is reported (and relative to how USB
366 402 * HID recommends the coordinates work). This driver keeps
367 403 * the origin at the same position, and just uses the additive
368 404 * inverse of the reported Y.
369 405 */
370   - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047,
371   - 4, 0);
  406 + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
  407 + input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
  408 + 1358, 4, 0);
  409 + input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
  410 + 2047, 4, 0);
  411 + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  412 + input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
  413 + input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
  414 + input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
  415 + 3167, 4, 0);
  416 + input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
  417 + 2565, 4, 0);
  418 + }
372 419 }
373 420  
374 421 if (report_undeciphered) {
375 422  
... ... @@ -377,12 +424,22 @@
377 424 }
378 425 }
379 426  
  427 +static int magicmouse_input_mapping(struct hid_device *hdev,
  428 + struct hid_input *hi, struct hid_field *field,
  429 + struct hid_usage *usage, unsigned long **bit, int *max)
  430 +{
  431 + struct magicmouse_sc *msc = hid_get_drvdata(hdev);
  432 +
  433 + if (!msc->input)
  434 + msc->input = hi->input;
  435 +
  436 + return 0;
  437 +}
  438 +
380 439 static int magicmouse_probe(struct hid_device *hdev,
381 440 const struct hid_device_id *id)
382 441 {
383   - __u8 feature_1[] = { 0xd7, 0x01 };
384   - __u8 feature_2[] = { 0xf8, 0x01, 0x32 };
385   - struct input_dev *input;
  442 + __u8 feature[] = { 0xd7, 0x01 };
386 443 struct magicmouse_sc *msc;
387 444 struct hid_report *report;
388 445 int ret;
... ... @@ -398,6 +455,8 @@
398 455 msc->quirks = id->driver_data;
399 456 hid_set_drvdata(hdev, msc);
400 457  
  458 + msc->single_touch_id = NO_TOUCHES;
  459 +
401 460 ret = hid_parse(hdev);
402 461 if (ret) {
403 462 dev_err(&hdev->dev, "magicmouse hid parse failed\n");
404 463  
... ... @@ -410,10 +469,22 @@
410 469 goto err_free;
411 470 }
412 471  
413   - /* we are handling the input ourselves */
414   - hidinput_disconnect(hdev);
  472 + /* We do this after hid-input is done parsing reports so that
  473 + * hid-input uses the most natural button and axis IDs.
  474 + */
  475 + if (msc->input)
  476 + magicmouse_setup_input(msc->input, hdev);
415 477  
416   - report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID);
  478 + if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
  479 + report = hid_register_report(hdev, HID_INPUT_REPORT,
  480 + MOUSE_REPORT_ID);
  481 + else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
  482 + report = hid_register_report(hdev, HID_INPUT_REPORT,
  483 + TRACKPAD_REPORT_ID);
  484 + report = hid_register_report(hdev, HID_INPUT_REPORT,
  485 + DOUBLE_REPORT_ID);
  486 + }
  487 +
417 488 if (!report) {
418 489 dev_err(&hdev->dev, "unable to register touch report\n");
419 490 ret = -ENOMEM;
420 491  
421 492  
422 493  
423 494  
... ... @@ -421,39 +492,15 @@
421 492 }
422 493 report->size = 6;
423 494  
424   - ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1),
  495 + ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
425 496 HID_FEATURE_REPORT);
426   - if (ret != sizeof(feature_1)) {
427   - dev_err(&hdev->dev, "unable to request touch data (1:%d)\n",
  497 + if (ret != sizeof(feature)) {
  498 + dev_err(&hdev->dev, "unable to request touch data (%d)\n",
428 499 ret);
429 500 goto err_stop_hw;
430 501 }
431   - ret = hdev->hid_output_raw_report(hdev, feature_2,
432   - sizeof(feature_2), HID_FEATURE_REPORT);
433   - if (ret != sizeof(feature_2)) {
434   - dev_err(&hdev->dev, "unable to request touch data (2:%d)\n",
435   - ret);
436   - goto err_stop_hw;
437   - }
438 502  
439   - input = input_allocate_device();
440   - if (!input) {
441   - dev_err(&hdev->dev, "can't alloc input device\n");
442   - ret = -ENOMEM;
443   - goto err_stop_hw;
444   - }
445   - magicmouse_setup_input(input, hdev);
446   -
447   - ret = input_register_device(input);
448   - if (ret) {
449   - dev_err(&hdev->dev, "input device registration failed\n");
450   - goto err_input;
451   - }
452   - msc->input = input;
453   -
454 503 return 0;
455   -err_input:
456   - input_free_device(input);
457 504 err_stop_hw:
458 505 hid_hw_stop(hdev);
459 506 err_free:
460 507  
... ... @@ -466,13 +513,14 @@
466 513 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
467 514  
468 515 hid_hw_stop(hdev);
469   - input_unregister_device(msc->input);
470 516 kfree(msc);
471 517 }
472 518  
473 519 static const struct hid_device_id magic_mice[] = {
474   - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE),
475   - .driver_data = 0 },
  520 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
  521 + USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
  522 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
  523 + USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
476 524 { }
477 525 };
478 526 MODULE_DEVICE_TABLE(hid, magic_mice);
... ... @@ -483,6 +531,7 @@
483 531 .probe = magicmouse_probe,
484 532 .remove = magicmouse_remove,
485 533 .raw_event = magicmouse_raw_event,
  534 + .input_mapping = magicmouse_input_mapping,
486 535 };
487 536  
488 537 static int __init magicmouse_init(void)
drivers/hid/hid-ntrig.c
... ... @@ -90,6 +90,55 @@
90 90 };
91 91  
92 92  
  93 +/*
  94 + * This function converts the 4 byte raw firmware code into
  95 + * a string containing 5 comma separated numbers.
  96 + */
  97 +static int ntrig_version_string(unsigned char *raw, char *buf)
  98 +{
  99 + __u8 a = (raw[1] & 0x0e) >> 1;
  100 + __u8 b = (raw[0] & 0x3c) >> 2;
  101 + __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5);
  102 + __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5);
  103 + __u8 e = raw[2] & 0x07;
  104 +
  105 + /*
  106 + * As yet unmapped bits:
  107 + * 0b11000000 0b11110001 0b00011000 0b00011000
  108 + */
  109 +
  110 + return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
  111 +}
  112 +
  113 +static void ntrig_report_version(struct hid_device *hdev)
  114 +{
  115 + int ret;
  116 + char buf[20];
  117 + struct usb_device *usb_dev = hid_to_usb_dev(hdev);
  118 + unsigned char *data = kmalloc(8, GFP_KERNEL);
  119 +
  120 + if (!data)
  121 + goto err_free;
  122 +
  123 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  124 + USB_REQ_CLEAR_FEATURE,
  125 + USB_TYPE_CLASS | USB_RECIP_INTERFACE |
  126 + USB_DIR_IN,
  127 + 0x30c, 1, data, 8,
  128 + USB_CTRL_SET_TIMEOUT);
  129 +
  130 + if (ret == 8) {
  131 + ret = ntrig_version_string(&data[2], buf);
  132 +
  133 + dev_info(&hdev->dev,
  134 + "Firmware version: %s (%02x%02x %02x%02x)\n",
  135 + buf, data[2], data[3], data[4], data[5]);
  136 + }
  137 +
  138 +err_free:
  139 + kfree(data);
  140 +}
  141 +
93 142 static ssize_t show_phys_width(struct device *dev,
94 143 struct device_attribute *attr,
95 144 char *buf)
... ... @@ -377,8 +426,8 @@
377 426 */
378 427  
379 428 static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
380   - struct hid_field *field, struct hid_usage *usage,
381   - unsigned long **bit, int *max)
  429 + struct hid_field *field, struct hid_usage *usage,
  430 + unsigned long **bit, int *max)
382 431 {
383 432 struct ntrig_data *nd = hid_get_drvdata(hdev);
384 433  
385 434  
386 435  
... ... @@ -448,13 +497,13 @@
448 497 /* width/height mapped on TouchMajor/TouchMinor/Orientation */
449 498 case HID_DG_WIDTH:
450 499 hid_map_usage(hi, usage, bit, max,
451   - EV_ABS, ABS_MT_TOUCH_MAJOR);
  500 + EV_ABS, ABS_MT_TOUCH_MAJOR);
452 501 return 1;
453 502 case HID_DG_HEIGHT:
454 503 hid_map_usage(hi, usage, bit, max,
455   - EV_ABS, ABS_MT_TOUCH_MINOR);
  504 + EV_ABS, ABS_MT_TOUCH_MINOR);
456 505 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
457   - 0, 1, 0, 0);
  506 + 0, 1, 0, 0);
458 507 return 1;
459 508 }
460 509 return 0;
... ... @@ -468,8 +517,8 @@
468 517 }
469 518  
470 519 static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
471   - struct hid_field *field, struct hid_usage *usage,
472   - unsigned long **bit, int *max)
  520 + struct hid_field *field, struct hid_usage *usage,
  521 + unsigned long **bit, int *max)
473 522 {
474 523 /* No special mappings needed for the pen and single touch */
475 524 if (field->physical)
... ... @@ -489,7 +538,7 @@
489 538 * and call input_mt_sync after each point if necessary
490 539 */
491 540 static int ntrig_event (struct hid_device *hid, struct hid_field *field,
492   - struct hid_usage *usage, __s32 value)
  541 + struct hid_usage *usage, __s32 value)
493 542 {
494 543 struct input_dev *input = field->hidinput->input;
495 544 struct ntrig_data *nd = hid_get_drvdata(hid);
... ... @@ -848,6 +897,8 @@
848 897 if (report)
849 898 usbhid_submit_report(hdev, report, USB_DIR_OUT);
850 899  
  900 + ntrig_report_version(hdev);
  901 +
851 902 ret = sysfs_create_group(&hdev->dev.kobj,
852 903 &ntrig_attribute_group);
853 904  
... ... @@ -860,7 +911,7 @@
860 911 static void ntrig_remove(struct hid_device *hdev)
861 912 {
862 913 sysfs_remove_group(&hdev->dev.kobj,
863   - &ntrig_attribute_group);
  914 + &ntrig_attribute_group);
864 915 hid_hw_stop(hdev);
865 916 kfree(hid_get_drvdata(hdev));
866 917 }
drivers/hid/hid-roccat-pyra.c
  1 +/*
  2 + * Roccat Pyra driver for Linux
  3 + *
  4 + * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
  5 + */
  6 +
  7 +/*
  8 + * This program is free software; you can redistribute it and/or modify it
  9 + * under the terms of the GNU General Public License as published by the Free
  10 + * Software Foundation; either version 2 of the License, or (at your option)
  11 + * any later version.
  12 + */
  13 +
  14 +/*
  15 + * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
  16 + * variant. Wireless variant is not tested.
  17 + * Userland tools can be found at http://sourceforge.net/projects/roccat
  18 + */
  19 +
  20 +#include <linux/device.h>
  21 +#include <linux/input.h>
  22 +#include <linux/hid.h>
  23 +#include <linux/usb.h>
  24 +#include <linux/module.h>
  25 +#include <linux/slab.h>
  26 +#include "hid-ids.h"
  27 +#include "hid-roccat.h"
  28 +#include "hid-roccat-pyra.h"
  29 +
  30 +static void profile_activated(struct pyra_device *pyra,
  31 + unsigned int new_profile)
  32 +{
  33 + pyra->actual_profile = new_profile;
  34 + pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
  35 +}
  36 +
  37 +static int pyra_send_control(struct usb_device *usb_dev, int value,
  38 + enum pyra_control_requests request)
  39 +{
  40 + int len;
  41 + struct pyra_control control;
  42 +
  43 + if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
  44 + request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
  45 + (value < 0 || value > 4))
  46 + return -EINVAL;
  47 +
  48 + control.command = PYRA_COMMAND_CONTROL;
  49 + control.value = value;
  50 + control.request = request;
  51 +
  52 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
  53 + USB_REQ_SET_CONFIGURATION,
  54 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
  55 + PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
  56 + sizeof(struct pyra_control),
  57 + USB_CTRL_SET_TIMEOUT);
  58 +
  59 + if (len != sizeof(struct pyra_control))
  60 + return len;
  61 +
  62 + return 0;
  63 +}
  64 +
  65 +static int pyra_receive_control_status(struct usb_device *usb_dev)
  66 +{
  67 + int len;
  68 + struct pyra_control control;
  69 +
  70 + do {
  71 + msleep(10);
  72 +
  73 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  74 + USB_REQ_CLEAR_FEATURE,
  75 + USB_TYPE_CLASS | USB_RECIP_INTERFACE |
  76 + USB_DIR_IN,
  77 + PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
  78 + sizeof(struct pyra_control),
  79 + USB_CTRL_SET_TIMEOUT);
  80 +
  81 + /* requested too early, try again */
  82 + } while (len == -EPROTO);
  83 +
  84 + if (len == sizeof(struct pyra_control) &&
  85 + control.command == PYRA_COMMAND_CONTROL &&
  86 + control.request == PYRA_CONTROL_REQUEST_STATUS &&
  87 + control.value == 1)
  88 + return 0;
  89 + else {
  90 + dev_err(&usb_dev->dev, "receive control status: "
  91 + "unknown response 0x%x 0x%x\n",
  92 + control.request, control.value);
  93 + return -EINVAL;
  94 + }
  95 +}
  96 +
  97 +static int pyra_get_profile_settings(struct usb_device *usb_dev,
  98 + struct pyra_profile_settings *buf, int number)
  99 +{
  100 + int retval;
  101 +
  102 + retval = pyra_send_control(usb_dev, number,
  103 + PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
  104 +
  105 + if (retval)
  106 + return retval;
  107 +
  108 + retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  109 + USB_REQ_CLEAR_FEATURE,
  110 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
  111 + PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
  112 + sizeof(struct pyra_profile_settings),
  113 + USB_CTRL_SET_TIMEOUT);
  114 +
  115 + if (retval != sizeof(struct pyra_profile_settings))
  116 + return retval;
  117 +
  118 + return 0;
  119 +}
  120 +
  121 +static int pyra_get_profile_buttons(struct usb_device *usb_dev,
  122 + struct pyra_profile_buttons *buf, int number)
  123 +{
  124 + int retval;
  125 +
  126 + retval = pyra_send_control(usb_dev, number,
  127 + PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
  128 +
  129 + if (retval)
  130 + return retval;
  131 +
  132 + retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  133 + USB_REQ_CLEAR_FEATURE,
  134 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
  135 + PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
  136 + sizeof(struct pyra_profile_buttons),
  137 + USB_CTRL_SET_TIMEOUT);
  138 +
  139 + if (retval != sizeof(struct pyra_profile_buttons))
  140 + return retval;
  141 +
  142 + return 0;
  143 +}
  144 +
  145 +static int pyra_get_settings(struct usb_device *usb_dev,
  146 + struct pyra_settings *buf)
  147 +{
  148 + int len;
  149 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  150 + USB_REQ_CLEAR_FEATURE,
  151 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
  152 + PYRA_USB_COMMAND_SETTINGS, 0, buf,
  153 + sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
  154 + if (len != sizeof(struct pyra_settings))
  155 + return -EIO;
  156 + return 0;
  157 +}
  158 +
  159 +static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
  160 +{
  161 + int len;
  162 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  163 + USB_REQ_CLEAR_FEATURE,
  164 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
  165 + PYRA_USB_COMMAND_INFO, 0, buf,
  166 + sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT);
  167 + if (len != sizeof(struct pyra_info))
  168 + return -EIO;
  169 + return 0;
  170 +}
  171 +
  172 +static int pyra_set_profile_settings(struct usb_device *usb_dev,
  173 + struct pyra_profile_settings const *settings)
  174 +{
  175 + int len;
  176 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
  177 + USB_REQ_SET_CONFIGURATION,
  178 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
  179 + PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
  180 + sizeof(struct pyra_profile_settings),
  181 + USB_CTRL_SET_TIMEOUT);
  182 + if (len != sizeof(struct pyra_profile_settings))
  183 + return -EIO;
  184 + if (pyra_receive_control_status(usb_dev))
  185 + return -EIO;
  186 + return 0;
  187 +}
  188 +
  189 +static int pyra_set_profile_buttons(struct usb_device *usb_dev,
  190 + struct pyra_profile_buttons const *buttons)
  191 +{
  192 + int len;
  193 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
  194 + USB_REQ_SET_CONFIGURATION,
  195 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
  196 + PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
  197 + sizeof(struct pyra_profile_buttons),
  198 + USB_CTRL_SET_TIMEOUT);
  199 + if (len != sizeof(struct pyra_profile_buttons))
  200 + return -EIO;
  201 + if (pyra_receive_control_status(usb_dev))
  202 + return -EIO;
  203 + return 0;
  204 +}
  205 +
  206 +static int pyra_set_settings(struct usb_device *usb_dev,
  207 + struct pyra_settings const *settings)
  208 +{
  209 + int len;
  210 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
  211 + USB_REQ_SET_CONFIGURATION,
  212 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
  213 + PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings,
  214 + sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
  215 + if (len != sizeof(struct pyra_settings))
  216 + return -EIO;
  217 + if (pyra_receive_control_status(usb_dev))
  218 + return -EIO;
  219 + return 0;
  220 +}
  221 +
  222 +static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
  223 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  224 + loff_t off, size_t count, int number)
  225 +{
  226 + struct device *dev = container_of(kobj, struct device, kobj);
  227 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  228 +
  229 + if (off >= sizeof(struct pyra_profile_settings))
  230 + return 0;
  231 +
  232 + if (off + count > sizeof(struct pyra_profile_settings))
  233 + count = sizeof(struct pyra_profile_settings) - off;
  234 +
  235 + mutex_lock(&pyra->pyra_lock);
  236 + memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off,
  237 + count);
  238 + mutex_unlock(&pyra->pyra_lock);
  239 +
  240 + return count;
  241 +}
  242 +
  243 +static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp,
  244 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  245 + loff_t off, size_t count)
  246 +{
  247 + return pyra_sysfs_read_profilex_settings(fp, kobj,
  248 + attr, buf, off, count, 0);
  249 +}
  250 +
  251 +static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp,
  252 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  253 + loff_t off, size_t count)
  254 +{
  255 + return pyra_sysfs_read_profilex_settings(fp, kobj,
  256 + attr, buf, off, count, 1);
  257 +}
  258 +
  259 +static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp,
  260 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  261 + loff_t off, size_t count)
  262 +{
  263 + return pyra_sysfs_read_profilex_settings(fp, kobj,
  264 + attr, buf, off, count, 2);
  265 +}
  266 +
  267 +static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp,
  268 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  269 + loff_t off, size_t count)
  270 +{
  271 + return pyra_sysfs_read_profilex_settings(fp, kobj,
  272 + attr, buf, off, count, 3);
  273 +}
  274 +
  275 +static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp,
  276 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  277 + loff_t off, size_t count)
  278 +{
  279 + return pyra_sysfs_read_profilex_settings(fp, kobj,
  280 + attr, buf, off, count, 4);
  281 +}
  282 +
  283 +static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
  284 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  285 + loff_t off, size_t count, int number)
  286 +{
  287 + struct device *dev = container_of(kobj, struct device, kobj);
  288 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  289 +
  290 + if (off >= sizeof(struct pyra_profile_buttons))
  291 + return 0;
  292 +
  293 + if (off + count > sizeof(struct pyra_profile_buttons))
  294 + count = sizeof(struct pyra_profile_buttons) - off;
  295 +
  296 + mutex_lock(&pyra->pyra_lock);
  297 + memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off,
  298 + count);
  299 + mutex_unlock(&pyra->pyra_lock);
  300 +
  301 + return count;
  302 +}
  303 +
  304 +static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp,
  305 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  306 + loff_t off, size_t count)
  307 +{
  308 + return pyra_sysfs_read_profilex_buttons(fp, kobj,
  309 + attr, buf, off, count, 0);
  310 +}
  311 +
  312 +static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp,
  313 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  314 + loff_t off, size_t count)
  315 +{
  316 + return pyra_sysfs_read_profilex_buttons(fp, kobj,
  317 + attr, buf, off, count, 1);
  318 +}
  319 +
  320 +static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp,
  321 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  322 + loff_t off, size_t count)
  323 +{
  324 + return pyra_sysfs_read_profilex_buttons(fp, kobj,
  325 + attr, buf, off, count, 2);
  326 +}
  327 +
  328 +static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp,
  329 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  330 + loff_t off, size_t count)
  331 +{
  332 + return pyra_sysfs_read_profilex_buttons(fp, kobj,
  333 + attr, buf, off, count, 3);
  334 +}
  335 +
  336 +static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp,
  337 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  338 + loff_t off, size_t count)
  339 +{
  340 + return pyra_sysfs_read_profilex_buttons(fp, kobj,
  341 + attr, buf, off, count, 4);
  342 +}
  343 +
  344 +static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
  345 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  346 + loff_t off, size_t count)
  347 +{
  348 + struct device *dev = container_of(kobj, struct device, kobj);
  349 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  350 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
  351 + int retval = 0;
  352 + int difference;
  353 + int profile_number;
  354 + struct pyra_profile_settings *profile_settings;
  355 +
  356 + if (off != 0 || count != sizeof(struct pyra_profile_settings))
  357 + return -EINVAL;
  358 +
  359 + profile_number = ((struct pyra_profile_settings const *)buf)->number;
  360 + profile_settings = &pyra->profile_settings[profile_number];
  361 +
  362 + mutex_lock(&pyra->pyra_lock);
  363 + difference = memcmp(buf, profile_settings,
  364 + sizeof(struct pyra_profile_settings));
  365 + if (difference) {
  366 + retval = pyra_set_profile_settings(usb_dev,
  367 + (struct pyra_profile_settings const *)buf);
  368 + if (!retval)
  369 + memcpy(profile_settings, buf,
  370 + sizeof(struct pyra_profile_settings));
  371 + }
  372 + mutex_unlock(&pyra->pyra_lock);
  373 +
  374 + if (retval)
  375 + return retval;
  376 +
  377 + return sizeof(struct pyra_profile_settings);
  378 +}
  379 +
  380 +static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
  381 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  382 + loff_t off, size_t count)
  383 +{
  384 + struct device *dev = container_of(kobj, struct device, kobj);
  385 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  386 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
  387 + int retval = 0;
  388 + int difference;
  389 + int profile_number;
  390 + struct pyra_profile_buttons *profile_buttons;
  391 +
  392 + if (off != 0 || count != sizeof(struct pyra_profile_buttons))
  393 + return -EINVAL;
  394 +
  395 + profile_number = ((struct pyra_profile_buttons const *)buf)->number;
  396 + profile_buttons = &pyra->profile_buttons[profile_number];
  397 +
  398 + mutex_lock(&pyra->pyra_lock);
  399 + difference = memcmp(buf, profile_buttons,
  400 + sizeof(struct pyra_profile_buttons));
  401 + if (difference) {
  402 + retval = pyra_set_profile_buttons(usb_dev,
  403 + (struct pyra_profile_buttons const *)buf);
  404 + if (!retval)
  405 + memcpy(profile_buttons, buf,
  406 + sizeof(struct pyra_profile_buttons));
  407 + }
  408 + mutex_unlock(&pyra->pyra_lock);
  409 +
  410 + if (retval)
  411 + return retval;
  412 +
  413 + return sizeof(struct pyra_profile_buttons);
  414 +}
  415 +
  416 +static ssize_t pyra_sysfs_read_settings(struct file *fp,
  417 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  418 + loff_t off, size_t count)
  419 +{
  420 + struct device *dev = container_of(kobj, struct device, kobj);
  421 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  422 +
  423 + if (off >= sizeof(struct pyra_settings))
  424 + return 0;
  425 +
  426 + if (off + count > sizeof(struct pyra_settings))
  427 + count = sizeof(struct pyra_settings) - off;
  428 +
  429 + mutex_lock(&pyra->pyra_lock);
  430 + memcpy(buf, ((char const *)&pyra->settings) + off, count);
  431 + mutex_unlock(&pyra->pyra_lock);
  432 +
  433 + return count;
  434 +}
  435 +
  436 +static ssize_t pyra_sysfs_write_settings(struct file *fp,
  437 + struct kobject *kobj, struct bin_attribute *attr, char *buf,
  438 + loff_t off, size_t count)
  439 +{
  440 + struct device *dev = container_of(kobj, struct device, kobj);
  441 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  442 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
  443 + int retval = 0;
  444 + int difference;
  445 +
  446 + if (off != 0 || count != sizeof(struct pyra_settings))
  447 + return -EINVAL;
  448 +
  449 + mutex_lock(&pyra->pyra_lock);
  450 + difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
  451 + if (difference) {
  452 + retval = pyra_set_settings(usb_dev,
  453 + (struct pyra_settings const *)buf);
  454 + if (!retval)
  455 + memcpy(&pyra->settings, buf,
  456 + sizeof(struct pyra_settings));
  457 + }
  458 + mutex_unlock(&pyra->pyra_lock);
  459 +
  460 + if (retval)
  461 + return retval;
  462 +
  463 + profile_activated(pyra, pyra->settings.startup_profile);
  464 +
  465 + return sizeof(struct pyra_settings);
  466 +}
  467 +
  468 +
  469 +static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
  470 + struct device_attribute *attr, char *buf)
  471 +{
  472 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  473 + return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
  474 +}
  475 +
  476 +static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
  477 + struct device_attribute *attr, char *buf)
  478 +{
  479 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  480 + return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
  481 +}
  482 +
  483 +static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
  484 + struct device_attribute *attr, char *buf)
  485 +{
  486 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  487 + return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
  488 +}
  489 +
  490 +static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
  491 + struct device_attribute *attr, char *buf)
  492 +{
  493 + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
  494 + return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
  495 +}
  496 +
  497 +static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
  498 +
  499 +static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
  500 +
  501 +static DEVICE_ATTR(firmware_version, 0440,
  502 + pyra_sysfs_show_firmware_version, NULL);
  503 +
  504 +static DEVICE_ATTR(startup_profile, 0440,
  505 + pyra_sysfs_show_startup_profile, NULL);
  506 +
  507 +static struct attribute *pyra_attributes[] = {
  508 + &dev_attr_actual_cpi.attr,
  509 + &dev_attr_actual_profile.attr,
  510 + &dev_attr_firmware_version.attr,
  511 + &dev_attr_startup_profile.attr,
  512 + NULL
  513 +};
  514 +
  515 +static struct attribute_group pyra_attribute_group = {
  516 + .attrs = pyra_attributes
  517 +};
  518 +
  519 +static struct bin_attribute pyra_profile_settings_attr = {
  520 + .attr = { .name = "profile_settings", .mode = 0220 },
  521 + .size = sizeof(struct pyra_profile_settings),
  522 + .write = pyra_sysfs_write_profile_settings
  523 +};
  524 +
  525 +static struct bin_attribute pyra_profile1_settings_attr = {
  526 + .attr = { .name = "profile1_settings", .mode = 0440 },
  527 + .size = sizeof(struct pyra_profile_settings),
  528 + .read = pyra_sysfs_read_profile1_settings
  529 +};
  530 +
  531 +static struct bin_attribute pyra_profile2_settings_attr = {
  532 + .attr = { .name = "profile2_settings", .mode = 0440 },
  533 + .size = sizeof(struct pyra_profile_settings),
  534 + .read = pyra_sysfs_read_profile2_settings
  535 +};
  536 +
  537 +static struct bin_attribute pyra_profile3_settings_attr = {
  538 + .attr = { .name = "profile3_settings", .mode = 0440 },
  539 + .size = sizeof(struct pyra_profile_settings),
  540 + .read = pyra_sysfs_read_profile3_settings
  541 +};
  542 +
  543 +static struct bin_attribute pyra_profile4_settings_attr = {
  544 + .attr = { .name = "profile4_settings", .mode = 0440 },
  545 + .size = sizeof(struct pyra_profile_settings),
  546 + .read = pyra_sysfs_read_profile4_settings
  547 +};
  548 +
  549 +static struct bin_attribute pyra_profile5_settings_attr = {
  550 + .attr = { .name = "profile5_settings", .mode = 0440 },
  551 + .size = sizeof(struct pyra_profile_settings),
  552 + .read = pyra_sysfs_read_profile5_settings
  553 +};
  554 +
  555 +static struct bin_attribute pyra_profile_buttons_attr = {
  556 + .attr = { .name = "profile_buttons", .mode = 0220 },
  557 + .size = sizeof(struct pyra_profile_buttons),
  558 + .write = pyra_sysfs_write_profile_buttons
  559 +};
  560 +
  561 +static struct bin_attribute pyra_profile1_buttons_attr = {
  562 + .attr = { .name = "profile1_buttons", .mode = 0440 },
  563 + .size = sizeof(struct pyra_profile_buttons),
  564 + .read = pyra_sysfs_read_profile1_buttons
  565 +};
  566 +
  567 +static struct bin_attribute pyra_profile2_buttons_attr = {
  568 + .attr = { .name = "profile2_buttons", .mode = 0440 },
  569 + .size = sizeof(struct pyra_profile_buttons),
  570 + .read = pyra_sysfs_read_profile2_buttons
  571 +};
  572 +
  573 +static struct bin_attribute pyra_profile3_buttons_attr = {
  574 + .attr = { .name = "profile3_buttons", .mode = 0440 },
  575 + .size = sizeof(struct pyra_profile_buttons),
  576 + .read = pyra_sysfs_read_profile3_buttons
  577 +};
  578 +
  579 +static struct bin_attribute pyra_profile4_buttons_attr = {
  580 + .attr = { .name = "profile4_buttons", .mode = 0440 },
  581 + .size = sizeof(struct pyra_profile_buttons),
  582 + .read = pyra_sysfs_read_profile4_buttons
  583 +};
  584 +
  585 +static struct bin_attribute pyra_profile5_buttons_attr = {
  586 + .attr = { .name = "profile5_buttons", .mode = 0440 },
  587 + .size = sizeof(struct pyra_profile_buttons),
  588 + .read = pyra_sysfs_read_profile5_buttons
  589 +};
  590 +
  591 +static struct bin_attribute pyra_settings_attr = {
  592 + .attr = { .name = "settings", .mode = 0660 },
  593 + .size = sizeof(struct pyra_settings),
  594 + .read = pyra_sysfs_read_settings,
  595 + .write = pyra_sysfs_write_settings
  596 +};
  597 +
  598 +static int pyra_create_sysfs_attributes(struct usb_interface *intf)
  599 +{
  600 + int retval;
  601 +
  602 + retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
  603 + if (retval)
  604 + goto exit_1;
  605 +
  606 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  607 + &pyra_profile_settings_attr);
  608 + if (retval)
  609 + goto exit_2;
  610 +
  611 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  612 + &pyra_profile1_settings_attr);
  613 + if (retval)
  614 + goto exit_3;
  615 +
  616 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  617 + &pyra_profile2_settings_attr);
  618 + if (retval)
  619 + goto exit_4;
  620 +
  621 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  622 + &pyra_profile3_settings_attr);
  623 + if (retval)
  624 + goto exit_5;
  625 +
  626 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  627 + &pyra_profile4_settings_attr);
  628 + if (retval)
  629 + goto exit_6;
  630 +
  631 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  632 + &pyra_profile5_settings_attr);
  633 + if (retval)
  634 + goto exit_7;
  635 +
  636 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  637 + &pyra_profile_buttons_attr);
  638 + if (retval)
  639 + goto exit_8;
  640 +
  641 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  642 + &pyra_profile1_buttons_attr);
  643 + if (retval)
  644 + goto exit_9;
  645 +
  646 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  647 + &pyra_profile2_buttons_attr);
  648 + if (retval)
  649 + goto exit_10;
  650 +
  651 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  652 + &pyra_profile3_buttons_attr);
  653 + if (retval)
  654 + goto exit_11;
  655 +
  656 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  657 + &pyra_profile4_buttons_attr);
  658 + if (retval)
  659 + goto exit_12;
  660 +
  661 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  662 + &pyra_profile5_buttons_attr);
  663 + if (retval)
  664 + goto exit_13;
  665 +
  666 + retval = sysfs_create_bin_file(&intf->dev.kobj,
  667 + &pyra_settings_attr);
  668 + if (retval)
  669 + goto exit_14;
  670 +
  671 + return 0;
  672 +
  673 +exit_14:
  674 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
  675 +exit_13:
  676 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
  677 +exit_12:
  678 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
  679 +exit_11:
  680 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
  681 +exit_10:
  682 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
  683 +exit_9:
  684 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
  685 +exit_8:
  686 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
  687 +exit_7:
  688 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
  689 +exit_6:
  690 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
  691 +exit_5:
  692 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
  693 +exit_4:
  694 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
  695 +exit_3:
  696 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
  697 +exit_2:
  698 + sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
  699 +exit_1:
  700 + return retval;
  701 +}
  702 +
  703 +static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
  704 +{
  705 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
  706 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
  707 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
  708 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
  709 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
  710 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
  711 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
  712 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
  713 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
  714 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
  715 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
  716 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
  717 + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
  718 + sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
  719 +}
  720 +
  721 +static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
  722 + struct pyra_device *pyra)
  723 +{
  724 + struct pyra_info *info;
  725 + int retval, i;
  726 +
  727 + mutex_init(&pyra->pyra_lock);
  728 +
  729 + info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL);
  730 + if (!info)
  731 + return -ENOMEM;
  732 + retval = pyra_get_info(usb_dev, info);
  733 + if (retval) {
  734 + kfree(info);
  735 + return retval;
  736 + }
  737 + pyra->firmware_version = info->firmware_version;
  738 + kfree(info);
  739 +
  740 + retval = pyra_get_settings(usb_dev, &pyra->settings);
  741 + if (retval)
  742 + return retval;
  743 +
  744 + for (i = 0; i < 5; ++i) {
  745 + retval = pyra_get_profile_settings(usb_dev,
  746 + &pyra->profile_settings[i], i);
  747 + if (retval)
  748 + return retval;
  749 +
  750 + retval = pyra_get_profile_buttons(usb_dev,
  751 + &pyra->profile_buttons[i], i);
  752 + if (retval)
  753 + return retval;
  754 + }
  755 +
  756 + profile_activated(pyra, pyra->settings.startup_profile);
  757 +
  758 + return 0;
  759 +}
  760 +
  761 +static int pyra_init_specials(struct hid_device *hdev)
  762 +{
  763 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  764 + struct usb_device *usb_dev = interface_to_usbdev(intf);
  765 + struct pyra_device *pyra;
  766 + int retval;
  767 +
  768 + if (intf->cur_altsetting->desc.bInterfaceProtocol
  769 + == USB_INTERFACE_PROTOCOL_MOUSE) {
  770 +
  771 + pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
  772 + if (!pyra) {
  773 + dev_err(&hdev->dev, "can't alloc device descriptor\n");
  774 + return -ENOMEM;
  775 + }
  776 + hid_set_drvdata(hdev, pyra);
  777 +
  778 + retval = pyra_init_pyra_device_struct(usb_dev, pyra);
  779 + if (retval) {
  780 + dev_err(&hdev->dev,
  781 + "couldn't init struct pyra_device\n");
  782 + goto exit_free;
  783 + }
  784 +
  785 + retval = roccat_connect(hdev);
  786 + if (retval < 0) {
  787 + dev_err(&hdev->dev, "couldn't init char dev\n");
  788 + } else {
  789 + pyra->chrdev_minor = retval;
  790 + pyra->roccat_claimed = 1;
  791 + }
  792 +
  793 + retval = pyra_create_sysfs_attributes(intf);
  794 + if (retval) {
  795 + dev_err(&hdev->dev, "cannot create sysfs files\n");
  796 + goto exit_free;
  797 + }
  798 + } else {
  799 + hid_set_drvdata(hdev, NULL);
  800 + }
  801 +
  802 + return 0;
  803 +exit_free:
  804 + kfree(pyra);
  805 + return retval;
  806 +}
  807 +
  808 +static void pyra_remove_specials(struct hid_device *hdev)
  809 +{
  810 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  811 + struct pyra_device *pyra;
  812 +
  813 + if (intf->cur_altsetting->desc.bInterfaceProtocol
  814 + == USB_INTERFACE_PROTOCOL_MOUSE) {
  815 + pyra_remove_sysfs_attributes(intf);
  816 + pyra = hid_get_drvdata(hdev);
  817 + if (pyra->roccat_claimed)
  818 + roccat_disconnect(pyra->chrdev_minor);
  819 + kfree(hid_get_drvdata(hdev));
  820 + }
  821 +}
  822 +
  823 +static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
  824 +{
  825 + int retval;
  826 +
  827 + retval = hid_parse(hdev);
  828 + if (retval) {
  829 + dev_err(&hdev->dev, "parse failed\n");
  830 + goto exit;
  831 + }
  832 +
  833 + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
  834 + if (retval) {
  835 + dev_err(&hdev->dev, "hw start failed\n");
  836 + goto exit;
  837 + }
  838 +
  839 + retval = pyra_init_specials(hdev);
  840 + if (retval) {
  841 + dev_err(&hdev->dev, "couldn't install mouse\n");
  842 + goto exit_stop;
  843 + }
  844 + return 0;
  845 +
  846 +exit_stop:
  847 + hid_hw_stop(hdev);
  848 +exit:
  849 + return retval;
  850 +}
  851 +
  852 +static void pyra_remove(struct hid_device *hdev)
  853 +{
  854 + pyra_remove_specials(hdev);
  855 + hid_hw_stop(hdev);
  856 +}
  857 +
  858 +static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
  859 + u8 const *data)
  860 +{
  861 + struct pyra_mouse_event_button const *button_event;
  862 +
  863 + switch (data[0]) {
  864 + case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
  865 + button_event = (struct pyra_mouse_event_button const *)data;
  866 + switch (button_event->type) {
  867 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
  868 + profile_activated(pyra, button_event->data1 - 1);
  869 + break;
  870 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
  871 + pyra->actual_cpi = button_event->data1;
  872 + break;
  873 + }
  874 + break;
  875 + }
  876 +}
  877 +
  878 +static void pyra_report_to_chrdev(struct pyra_device const *pyra,
  879 + u8 const *data)
  880 +{
  881 + struct pyra_roccat_report roccat_report;
  882 + struct pyra_mouse_event_button const *button_event;
  883 +
  884 + if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
  885 + return;
  886 +
  887 + button_event = (struct pyra_mouse_event_button const *)data;
  888 +
  889 + switch (button_event->type) {
  890 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
  891 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
  892 + roccat_report.type = button_event->type;
  893 + roccat_report.value = button_event->data1;
  894 + roccat_report.key = 0;
  895 + roccat_report_event(pyra->chrdev_minor,
  896 + (uint8_t const *)&roccat_report,
  897 + sizeof(struct pyra_roccat_report));
  898 + break;
  899 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
  900 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
  901 + case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
  902 + if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
  903 + roccat_report.type = button_event->type;
  904 + roccat_report.key = button_event->data1;
  905 + /*
  906 + * pyra reports profile numbers with range 1-5.
  907 + * Keeping this behaviour.
  908 + */
  909 + roccat_report.value = pyra->actual_profile + 1;
  910 + roccat_report_event(pyra->chrdev_minor,
  911 + (uint8_t const *)&roccat_report,
  912 + sizeof(struct pyra_roccat_report));
  913 + }
  914 + break;
  915 + }
  916 +}
  917 +
  918 +static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
  919 + u8 *data, int size)
  920 +{
  921 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  922 + struct pyra_device *pyra = hid_get_drvdata(hdev);
  923 +
  924 + if (intf->cur_altsetting->desc.bInterfaceProtocol
  925 + != USB_INTERFACE_PROTOCOL_MOUSE)
  926 + return 0;
  927 +
  928 + pyra_keep_values_up_to_date(pyra, data);
  929 +
  930 + if (pyra->roccat_claimed)
  931 + pyra_report_to_chrdev(pyra, data);
  932 +
  933 + return 0;
  934 +}
  935 +
  936 +static const struct hid_device_id pyra_devices[] = {
  937 + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
  938 + USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
  939 + /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */
  940 + { }
  941 +};
  942 +
  943 +MODULE_DEVICE_TABLE(hid, pyra_devices);
  944 +
  945 +static struct hid_driver pyra_driver = {
  946 + .name = "pyra",
  947 + .id_table = pyra_devices,
  948 + .probe = pyra_probe,
  949 + .remove = pyra_remove,
  950 + .raw_event = pyra_raw_event
  951 +};
  952 +
  953 +static int __init pyra_init(void)
  954 +{
  955 + return hid_register_driver(&pyra_driver);
  956 +}
  957 +
  958 +static void __exit pyra_exit(void)
  959 +{
  960 + hid_unregister_driver(&pyra_driver);
  961 +}
  962 +
  963 +module_init(pyra_init);
  964 +module_exit(pyra_exit);
  965 +
  966 +MODULE_AUTHOR("Stefan Achatz");
  967 +MODULE_DESCRIPTION("USB Roccat Pyra driver");
  968 +MODULE_LICENSE("GPL v2");
drivers/hid/hid-roccat-pyra.h
  1 +#ifndef __HID_ROCCAT_PYRA_H
  2 +#define __HID_ROCCAT_PYRA_H
  3 +
  4 +/*
  5 + * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
  6 + */
  7 +
  8 +/*
  9 + * This program is free software; you can redistribute it and/or modify it
  10 + * under the terms of the GNU General Public License as published by the Free
  11 + * Software Foundation; either version 2 of the License, or (at your option)
  12 + * any later version.
  13 + */
  14 +
  15 +#include <linux/types.h>
  16 +
  17 +#pragma pack(push)
  18 +#pragma pack(1)
  19 +
  20 +struct pyra_b {
  21 + uint8_t command; /* PYRA_COMMAND_B */
  22 + uint8_t size; /* always 3 */
  23 + uint8_t unknown; /* 1 */
  24 +};
  25 +
  26 +struct pyra_control {
  27 + uint8_t command; /* PYRA_COMMAND_CONTROL */
  28 + /*
  29 + * value is profile number for request_settings and request_buttons
  30 + * 1 if status ok for request_status
  31 + */
  32 + uint8_t value; /* Range 0-4 */
  33 + uint8_t request;
  34 +};
  35 +
  36 +enum pyra_control_requests {
  37 + PYRA_CONTROL_REQUEST_STATUS = 0x00,
  38 + PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
  39 + PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
  40 +};
  41 +
  42 +struct pyra_settings {
  43 + uint8_t command; /* PYRA_COMMAND_SETTINGS */
  44 + uint8_t size; /* always 3 */
  45 + uint8_t startup_profile; /* Range 0-4! */
  46 +};
  47 +
  48 +struct pyra_profile_settings {
  49 + uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
  50 + uint8_t size; /* always 0xd */
  51 + uint8_t number; /* Range 0-4 */
  52 + uint8_t xysync;
  53 + uint8_t x_sensitivity; /* 0x1-0xa */
  54 + uint8_t y_sensitivity;
  55 + uint8_t x_cpi; /* unused */
  56 + uint8_t y_cpi; /* this value is for x and y */
  57 + uint8_t lightswitch; /* 0 = off, 1 = on */
  58 + uint8_t light_effect;
  59 + uint8_t handedness;
  60 + uint16_t checksum; /* byte sum */
  61 +};
  62 +
  63 +struct pyra_profile_buttons {
  64 + uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
  65 + uint8_t size; /* always 0x13 */
  66 + uint8_t number; /* Range 0-4 */
  67 + uint8_t buttons[14];
  68 + uint16_t checksum; /* byte sum */
  69 +};
  70 +
  71 +struct pyra_info {
  72 + uint8_t command; /* PYRA_COMMAND_INFO */
  73 + uint8_t size; /* always 6 */
  74 + uint8_t firmware_version;
  75 + uint8_t unknown1; /* always 0 */
  76 + uint8_t unknown2; /* always 1 */
  77 + uint8_t unknown3; /* always 0 */
  78 +};
  79 +
  80 +enum pyra_commands {
  81 + PYRA_COMMAND_CONTROL = 0x4,
  82 + PYRA_COMMAND_SETTINGS = 0x5,
  83 + PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
  84 + PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
  85 + PYRA_COMMAND_INFO = 0x9,
  86 + PYRA_COMMAND_B = 0xb
  87 +};
  88 +
  89 +enum pyra_usb_commands {
  90 + PYRA_USB_COMMAND_CONTROL = 0x304,
  91 + PYRA_USB_COMMAND_SETTINGS = 0x305,
  92 + PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306,
  93 + PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307,
  94 + PYRA_USB_COMMAND_INFO = 0x309,
  95 + PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */
  96 +};
  97 +
  98 +enum pyra_mouse_report_numbers {
  99 + PYRA_MOUSE_REPORT_NUMBER_HID = 1,
  100 + PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
  101 + PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3,
  102 +};
  103 +
  104 +struct pyra_mouse_event_button {
  105 + uint8_t report_number; /* always 3 */
  106 + uint8_t unknown; /* always 0 */
  107 + uint8_t type;
  108 + uint8_t data1;
  109 + uint8_t data2;
  110 +};
  111 +
  112 +struct pyra_mouse_event_audio {
  113 + uint8_t report_number; /* always 2 */
  114 + uint8_t type;
  115 + uint8_t unused; /* always 0 */
  116 +};
  117 +
  118 +/* hid audio controls */
  119 +enum pyra_mouse_event_audio_types {
  120 + PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2,
  121 + PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9,
  122 + PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea,
  123 +};
  124 +
  125 +enum pyra_mouse_event_button_types {
  126 + /*
  127 + * Mouse sends tilt events on report_number 1 and 3
  128 + * Tilt events are sent repeatedly with 0.94s between first and second
  129 + * event and 0.22s on subsequent
  130 + */
  131 + PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10,
  132 +
  133 + /*
  134 + * These are sent sequentially
  135 + * data1 contains new profile number in range 1-5
  136 + */
  137 + PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20,
  138 + PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30,
  139 +
  140 + /*
  141 + * data1 = button_number (rmp index)
  142 + * data2 = pressed/released
  143 + */
  144 + PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40,
  145 + PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50,
  146 +
  147 + /*
  148 + * data1 = button_number (rmp index)
  149 + */
  150 + PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
  151 +
  152 + /* data1 = new cpi */
  153 + PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0,
  154 +
  155 + /* data1 and data2 = new sensitivity */
  156 + PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0,
  157 +
  158 + PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
  159 +};
  160 +
  161 +enum {
  162 + PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
  163 + PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
  164 +};
  165 +
  166 +struct pyra_roccat_report {
  167 + uint8_t type;
  168 + uint8_t value;
  169 + uint8_t key;
  170 +};
  171 +
  172 +#pragma pack(pop)
  173 +
  174 +struct pyra_device {
  175 + int actual_profile;
  176 + int actual_cpi;
  177 + int firmware_version;
  178 + int roccat_claimed;
  179 + int chrdev_minor;
  180 + struct mutex pyra_lock;
  181 + struct pyra_settings settings;
  182 + struct pyra_profile_settings profile_settings[5];
  183 + struct pyra_profile_buttons profile_buttons[5];
  184 +};
  185 +
  186 +#endif
drivers/hid/usbhid/hid-core.c
... ... @@ -807,7 +807,7 @@
807 807 struct usb_host_interface *interface = intf->cur_altsetting;
808 808 int ret;
809 809  
810   - if (usbhid->urbout) {
  810 + if (usbhid->urbout && report_type != HID_FEATURE_REPORT) {
811 811 int actual_length;
812 812 int skipped_report_id = 0;
813 813  
drivers/hid/usbhid/hid-quirks.c
... ... @@ -34,7 +34,6 @@
34 34 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
35 35 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
36 36 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
37   - { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
38 37 { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
39 38 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT },
40 39 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
... ... @@ -316,6 +316,7 @@
316 316 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
317 317 #define HID_QUIRK_NO_INIT_REPORTS 0x20000000
318 318 #define HID_QUIRK_NO_IGNORE 0x40000000
  319 +#define HID_QUIRK_NO_INPUT_SYNC 0x80000000
319 320  
320 321 /*
321 322 * This is the global environment of the parser. This information is