aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig19
-rw-r--r--drivers/hid/Makefile4
-rw-r--r--drivers/hid/hid-3m-pct.c127
-rw-r--r--drivers/hid/hid-core.c4
-rw-r--r--drivers/hid/hid-egalax.c16
-rw-r--r--drivers/hid/hid-ids.h5
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/hid/hid-lg.c41
-rw-r--r--drivers/hid/hid-lg.h6
-rw-r--r--drivers/hid/hid-lg2ff.c4
-rw-r--r--drivers/hid/hid-lg4ff.c136
-rw-r--r--drivers/hid/hid-magicmouse.c325
-rw-r--r--drivers/hid/hid-ntrig.c69
-rw-r--r--drivers/hid/hid-roccat-pyra.c968
-rw-r--r--drivers/hid/hid-roccat-pyra.h186
-rw-r--r--drivers/hid/usbhid/hid-core.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
17 files changed, 1703 insertions, 213 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 2072e0138e9f..68a7e862068e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -220,12 +220,12 @@ config LOGITECH_FF
220 force feedback. 220 force feedback.
221 221
222config LOGIRUMBLEPAD2_FF 222config LOGIRUMBLEPAD2_FF
223 bool "Logitech Rumblepad 2 force feedback support" 223 bool "Logitech RumblePad/Rumblepad 2 force feedback support"
224 depends on HID_LOGITECH 224 depends on HID_LOGITECH
225 select INPUT_FF_MEMLESS 225 select INPUT_FF_MEMLESS
226 help 226 help
227 Say Y here if you want to enable force feedback support for Logitech 227 Say Y here if you want to enable force feedback support for Logitech
228 Rumblepad 2 devices. 228 RumblePad and Rumblepad 2 devices.
229 229
230config LOGIG940_FF 230config LOGIG940_FF
231 bool "Logitech Flight System G940 force feedback support" 231 bool "Logitech Flight System G940 force feedback support"
@@ -235,6 +235,14 @@ config LOGIG940_FF
235 Say Y here if you want to enable force feedback support for Logitech 235 Say Y here if you want to enable force feedback support for Logitech
236 Flight System G940 devices. 236 Flight System G940 devices.
237 237
238config 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
238config HID_MAGICMOUSE 246config HID_MAGICMOUSE
239 tristate "Apple MagicMouse multi-touch support" 247 tristate "Apple MagicMouse multi-touch support"
240 depends on BT_HIDP 248 depends on BT_HIDP
@@ -376,6 +384,13 @@ config HID_ROCCAT_KONE
376 ---help--- 384 ---help---
377 Support for Roccat Kone mouse. 385 Support for Roccat Kone mouse.
378 386
387config 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.
393
379config HID_SAMSUNG 394config HID_SAMSUNG
380 tristate "Samsung InfraRed remote control or keyboards" 395 tristate "Samsung InfraRed remote control or keyboards"
381 depends on USB_HID 396 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 46f037f3df80..ad74abcc73d5 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -21,6 +21,9 @@ endif
21ifdef CONFIG_LOGIG940_FF 21ifdef CONFIG_LOGIG940_FF
22 hid-logitech-objs += hid-lg3ff.o 22 hid-logitech-objs += hid-lg3ff.o
23endif 23endif
24ifdef CONFIG_LOGIWII_FF
25 hid-logitech-objs += hid-lg4ff.o
26endif
24 27
25obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o 28obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
26obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 29obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
@@ -52,6 +55,7 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
52obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 55obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
53obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 56obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
54obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 57obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
58obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
55obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 59obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
56obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 60obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
57obj-$(CONFIG_HID_SONY) += hid-sony.o 61obj-$(CONFIG_HID_SONY) += hid-sony.o
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 2a0d56b7a02b..02d8cd3b1b1b 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -2,6 +2,8 @@
2 * HID driver for 3M PCT multitouch panels 2 * HID driver for 3M PCT multitouch panels
3 * 3 *
4 * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> 4 * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
5 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
6 * Copyright (c) 2010 Canonical, Ltd.
5 * 7 *
6 */ 8 */
7 9
@@ -24,15 +26,26 @@ MODULE_LICENSE("GPL");
24 26
25#include "hid-ids.h" 27#include "hid-ids.h"
26 28
29#define MAX_SLOTS 60
30#define MAX_TRKID USHRT_MAX
31#define MAX_EVENTS 360
32
33/* estimated signal-to-noise ratios */
34#define SN_MOVE 2048
35#define SN_WIDTH 128
36
27struct mmm_finger { 37struct mmm_finger {
28 __s32 x, y, w, h; 38 __s32 x, y, w, h;
29 __u8 rank; 39 __u16 id;
40 bool prev_touch;
30 bool touch, valid; 41 bool touch, valid;
31}; 42};
32 43
33struct mmm_data { 44struct mmm_data {
34 struct mmm_finger f[10]; 45 struct mmm_finger f[MAX_SLOTS];
35 __u8 curid, num; 46 __u16 id;
47 __u8 curid;
48 __u8 nexp, nreal;
36 bool touch, valid; 49 bool touch, valid;
37}; 50};
38 51
@@ -40,6 +53,10 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
40 struct hid_field *field, struct hid_usage *usage, 53 struct hid_field *field, struct hid_usage *usage,
41 unsigned long **bit, int *max) 54 unsigned long **bit, int *max)
42{ 55{
56 int f1 = field->logical_minimum;
57 int f2 = field->logical_maximum;
58 int df = f2 - f1;
59
43 switch (usage->hid & HID_USAGE_PAGE) { 60 switch (usage->hid & HID_USAGE_PAGE) {
44 61
45 case HID_UP_BUTTON: 62 case HID_UP_BUTTON:
@@ -50,18 +67,20 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
50 case HID_GD_X: 67 case HID_GD_X:
51 hid_map_usage(hi, usage, bit, max, 68 hid_map_usage(hi, usage, bit, max,
52 EV_ABS, ABS_MT_POSITION_X); 69 EV_ABS, ABS_MT_POSITION_X);
70 input_set_abs_params(hi->input, ABS_MT_POSITION_X,
71 f1, f2, df / SN_MOVE, 0);
53 /* touchscreen emulation */ 72 /* touchscreen emulation */
54 input_set_abs_params(hi->input, ABS_X, 73 input_set_abs_params(hi->input, ABS_X,
55 field->logical_minimum, 74 f1, f2, df / SN_MOVE, 0);
56 field->logical_maximum, 0, 0);
57 return 1; 75 return 1;
58 case HID_GD_Y: 76 case HID_GD_Y:
59 hid_map_usage(hi, usage, bit, max, 77 hid_map_usage(hi, usage, bit, max,
60 EV_ABS, ABS_MT_POSITION_Y); 78 EV_ABS, ABS_MT_POSITION_Y);
79 input_set_abs_params(hi->input, ABS_MT_POSITION_Y,
80 f1, f2, df / SN_MOVE, 0);
61 /* touchscreen emulation */ 81 /* touchscreen emulation */
62 input_set_abs_params(hi->input, ABS_Y, 82 input_set_abs_params(hi->input, ABS_Y,
63 field->logical_minimum, 83 f1, f2, df / SN_MOVE, 0);
64 field->logical_maximum, 0, 0);
65 return 1; 84 return 1;
66 } 85 }
67 return 0; 86 return 0;
@@ -81,21 +100,31 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
81 case HID_DG_TIPSWITCH: 100 case HID_DG_TIPSWITCH:
82 /* touchscreen emulation */ 101 /* touchscreen emulation */
83 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 102 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
103 input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
84 return 1; 104 return 1;
85 case HID_DG_WIDTH: 105 case HID_DG_WIDTH:
86 hid_map_usage(hi, usage, bit, max, 106 hid_map_usage(hi, usage, bit, max,
87 EV_ABS, ABS_MT_TOUCH_MAJOR); 107 EV_ABS, ABS_MT_TOUCH_MAJOR);
108 input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR,
109 f1, f2, df / SN_WIDTH, 0);
88 return 1; 110 return 1;
89 case HID_DG_HEIGHT: 111 case HID_DG_HEIGHT:
90 hid_map_usage(hi, usage, bit, max, 112 hid_map_usage(hi, usage, bit, max,
91 EV_ABS, ABS_MT_TOUCH_MINOR); 113 EV_ABS, ABS_MT_TOUCH_MINOR);
114 input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR,
115 f1, f2, df / SN_WIDTH, 0);
92 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 116 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
93 1, 1, 0, 0); 117 0, 1, 0, 0);
94 return 1; 118 return 1;
95 case HID_DG_CONTACTID: 119 case HID_DG_CONTACTID:
96 field->logical_maximum = 59; 120 field->logical_maximum = MAX_TRKID;
97 hid_map_usage(hi, usage, bit, max, 121 hid_map_usage(hi, usage, bit, max,
98 EV_ABS, ABS_MT_TRACKING_ID); 122 EV_ABS, ABS_MT_TRACKING_ID);
123 input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
124 0, MAX_TRKID, 0, 0);
125 if (!hi->input->mt)
126 input_mt_create_slots(hi->input, MAX_SLOTS);
127 input_set_events_per_packet(hi->input, MAX_EVENTS);
99 return 1; 128 return 1;
100 } 129 }
101 /* let hid-input decide for the others */ 130 /* let hid-input decide for the others */
@@ -113,10 +142,10 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
113 struct hid_field *field, struct hid_usage *usage, 142 struct hid_field *field, struct hid_usage *usage,
114 unsigned long **bit, int *max) 143 unsigned long **bit, int *max)
115{ 144{
145 /* tell hid-input to skip setup of these event types */
116 if (usage->type == EV_KEY || usage->type == EV_ABS) 146 if (usage->type == EV_KEY || usage->type == EV_ABS)
117 clear_bit(usage->code, *bit); 147 set_bit(usage->type, hi->input->evbit);
118 148 return -1;
119 return 0;
120} 149}
121 150
122/* 151/*
@@ -126,70 +155,49 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
126static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 155static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
127{ 156{
128 struct mmm_finger *oldest = 0; 157 struct mmm_finger *oldest = 0;
129 bool pressed = false, released = false;
130 int i; 158 int i;
131 159 for (i = 0; i < MAX_SLOTS; ++i) {
132 /*
133 * we need to iterate on all fingers to decide if we have a press
134 * or a release event in our touchscreen emulation.
135 */
136 for (i = 0; i < 10; ++i) {
137 struct mmm_finger *f = &md->f[i]; 160 struct mmm_finger *f = &md->f[i];
138 if (!f->valid) { 161 if (!f->valid) {
139 /* this finger is just placeholder data, ignore */ 162 /* this finger is just placeholder data, ignore */
140 } else if (f->touch) { 163 continue;
164 }
165 input_mt_slot(input, i);
166 if (f->touch) {
141 /* this finger is on the screen */ 167 /* this finger is on the screen */
142 int wide = (f->w > f->h); 168 int wide = (f->w > f->h);
143 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i); 169 /* divided by two to match visual scale of touch */
170 int major = max(f->w, f->h) >> 1;
171 int minor = min(f->w, f->h) >> 1;
172
173 if (!f->prev_touch)
174 f->id = md->id++;
175 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
144 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 176 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
145 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 177 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
146 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 178 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
147 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, 179 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
148 wide ? f->w : f->h); 180 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
149 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, 181 /* touchscreen emulation: pick the oldest contact */
150 wide ? f->h : f->w); 182 if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
151 input_mt_sync(input);
152 /*
153 * touchscreen emulation: maintain the age rank
154 * of this finger, decide if we have a press
155 */
156 if (f->rank == 0) {
157 f->rank = ++(md->num);
158 if (f->rank == 1)
159 pressed = true;
160 }
161 if (f->rank == 1)
162 oldest = f; 183 oldest = f;
163 } else { 184 } else {
164 /* this finger took off the screen */ 185 /* this finger took off the screen */
165 /* touchscreen emulation: maintain age rank of others */ 186 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
166 int j;
167
168 for (j = 0; j < 10; ++j) {
169 struct mmm_finger *g = &md->f[j];
170 if (g->rank > f->rank) {
171 g->rank--;
172 if (g->rank == 1)
173 oldest = g;
174 }
175 }
176 f->rank = 0;
177 --(md->num);
178 if (md->num == 0)
179 released = true;
180 } 187 }
188 f->prev_touch = f->touch;
181 f->valid = 0; 189 f->valid = 0;
182 } 190 }
183 191
184 /* touchscreen emulation */ 192 /* touchscreen emulation */
185 if (oldest) { 193 if (oldest) {
186 if (pressed) 194 input_event(input, EV_KEY, BTN_TOUCH, 1);
187 input_event(input, EV_KEY, BTN_TOUCH, 1);
188 input_event(input, EV_ABS, ABS_X, oldest->x); 195 input_event(input, EV_ABS, ABS_X, oldest->x);
189 input_event(input, EV_ABS, ABS_Y, oldest->y); 196 input_event(input, EV_ABS, ABS_Y, oldest->y);
190 } else if (released) { 197 } else {
191 input_event(input, EV_KEY, BTN_TOUCH, 0); 198 input_event(input, EV_KEY, BTN_TOUCH, 0);
192 } 199 }
200 input_sync(input);
193} 201}
194 202
195/* 203/*
@@ -223,10 +231,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
223 md->f[md->curid].h = value; 231 md->f[md->curid].h = value;
224 break; 232 break;
225 case HID_DG_CONTACTID: 233 case HID_DG_CONTACTID:
234 value = clamp_val(value, 0, MAX_SLOTS - 1);
226 if (md->valid) { 235 if (md->valid) {
227 md->curid = value; 236 md->curid = value;
228 md->f[value].touch = md->touch; 237 md->f[value].touch = md->touch;
229 md->f[value].valid = 1; 238 md->f[value].valid = 1;
239 md->nreal++;
230 } 240 }
231 break; 241 break;
232 case HID_GD_X: 242 case HID_GD_X:
@@ -238,7 +248,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
238 md->f[md->curid].y = value; 248 md->f[md->curid].y = value;
239 break; 249 break;
240 case HID_DG_CONTACTCOUNT: 250 case HID_DG_CONTACTCOUNT:
241 mmm_filter_event(md, input); 251 if (value)
252 md->nexp = value;
253 if (md->nreal >= md->nexp) {
254 mmm_filter_event(md, input);
255 md->nreal = 0;
256 }
242 break; 257 break;
243 } 258 }
244 } 259 }
@@ -255,6 +270,8 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
255 int ret; 270 int ret;
256 struct mmm_data *md; 271 struct mmm_data *md;
257 272
273 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
274
258 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); 275 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
259 if (!md) { 276 if (!md) {
260 dev_err(&hdev->dev, "cannot allocate 3M data\n"); 277 dev_err(&hdev->dev, "cannot allocate 3M data\n");
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5ac2be978c92..cb7dc99d8b29 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1249,6 +1249,7 @@ static const struct hid_device_id hid_blacklist[] = {
1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1250 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, 1250 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
1251 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, 1251 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
1252 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
1252 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, 1253 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
1253 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, 1254 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
1254 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, 1255 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
@@ -1328,6 +1329,7 @@ static const struct hid_device_id hid_blacklist[] = {
1328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, 1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1330 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
1330 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, 1331 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
1332 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
1331 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, 1333 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
1332 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, 1334 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
1333 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, 1335 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
@@ -1337,6 +1339,7 @@ static const struct hid_device_id hid_blacklist[] = {
1337 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, 1339 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
1338 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, 1340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
1339 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, 1341 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
1342 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
1340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1343 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1341 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, 1344 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1342 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, 1345 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
@@ -1372,6 +1375,7 @@ static const struct hid_device_id hid_blacklist[] = {
1372 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1375 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1373 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1376 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1374 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1377 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1378 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1375 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1379 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1376 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1380 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1377 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1381 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index 8ca7f65cf2f8..54b017ad258d 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -31,7 +31,7 @@ struct egalax_data {
31 bool first; /* is this the first finger in the frame? */ 31 bool first; /* is this the first finger in the frame? */
32 bool valid; /* valid finger data, or just placeholder? */ 32 bool valid; /* valid finger data, or just placeholder? */
33 bool activity; /* at least one active finger previously? */ 33 bool activity; /* at least one active finger previously? */
34 __u16 lastx, lasty; /* latest valid (x, y) in the frame */ 34 __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
35}; 35};
36 36
37static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, 37static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -79,6 +79,10 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
79 case HID_DG_TIPPRESSURE: 79 case HID_DG_TIPPRESSURE:
80 hid_map_usage(hi, usage, bit, max, 80 hid_map_usage(hi, usage, bit, max,
81 EV_ABS, ABS_MT_PRESSURE); 81 EV_ABS, ABS_MT_PRESSURE);
82 /* touchscreen emulation */
83 input_set_abs_params(hi->input, ABS_PRESSURE,
84 field->logical_minimum,
85 field->logical_maximum, 0, 0);
82 return 1; 86 return 1;
83 } 87 }
84 return 0; 88 return 0;
@@ -109,8 +113,8 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
109 if (td->valid) { 113 if (td->valid) {
110 /* emit multitouch events */ 114 /* emit multitouch events */
111 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); 115 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
112 input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); 116 input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
113 input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); 117 input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
114 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); 118 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
115 119
116 input_mt_sync(input); 120 input_mt_sync(input);
@@ -121,6 +125,7 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
121 */ 125 */
122 td->lastx = td->x; 126 td->lastx = td->x;
123 td->lasty = td->y; 127 td->lasty = td->y;
128 td->lastz = td->z;
124 } 129 }
125 130
126 /* 131 /*
@@ -129,8 +134,9 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
129 * the oldest on the panel, the one we want for single touch 134 * the oldest on the panel, the one we want for single touch
130 */ 135 */
131 if (!td->first && td->activity) { 136 if (!td->first && td->activity) {
132 input_event(input, EV_ABS, ABS_X, td->lastx); 137 input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
133 input_event(input, EV_ABS, ABS_Y, td->lasty); 138 input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
139 input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
134 } 140 }
135 141
136 if (!td->valid) { 142 if (!td->valid) {
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 5247f5bdb49b..ae8f74431d92 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -64,6 +64,7 @@
64#define USB_VENDOR_ID_APPLE 0x05ac 64#define USB_VENDOR_ID_APPLE 0x05ac
65#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 65#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
66#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d 66#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
67#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
67#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e 68#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
68#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f 69#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
69#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 70#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
@@ -345,6 +346,7 @@
345#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 346#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
346#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 347#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
347#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f 348#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
349#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
348#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 350#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
349#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 351#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
350#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 352#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
@@ -356,6 +358,7 @@
356#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 358#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
357#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 359#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
358#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 360#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
361#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
359#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a 362#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
360#define USB_DEVICE_ID_S510_RECEIVER 0xc50c 363#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
361#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 364#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
@@ -468,6 +471,8 @@
468 471
469#define USB_VENDOR_ID_ROCCAT 0x1e7d 472#define USB_VENDOR_ID_ROCCAT 0x1e7d
470#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 473#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
474#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
475#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
471 476
472#define USB_VENDOR_ID_SAITEK 0x06a3 477#define USB_VENDOR_ID_SAITEK 0x06a3
473#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 478#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 8e733b6eae27..b9877a86eca7 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -739,6 +739,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
739{ 739{
740 struct hid_input *hidinput; 740 struct hid_input *hidinput;
741 741
742 if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC)
743 return;
744
742 list_for_each_entry(hidinput, &hid->inputs, list) 745 list_for_each_entry(hidinput, &hid->inputs, list)
743 input_sync(hidinput->input); 746 input_sync(hidinput->input);
744} 747}
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index f6433d8050a9..9e92c27002ca 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -7,6 +7,7 @@
7 * Copyright (c) 2006-2007 Jiri Kosina 7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley 8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby 9 * Copyright (c) 2008 Jiri Slaby
10 * Copyright (c) 2010 Hendrik Iben
10 */ 11 */
11 12
12/* 13/*
@@ -19,6 +20,9 @@
19#include <linux/device.h> 20#include <linux/device.h>
20#include <linux/hid.h> 21#include <linux/hid.h>
21#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/random.h>
24#include <linux/sched.h>
25#include <linux/wait.h>
22 26
23#include "hid-ids.h" 27#include "hid-ids.h"
24#include "hid-lg.h" 28#include "hid-lg.h"
@@ -35,6 +39,7 @@
35#define LG_FF2 0x400 39#define LG_FF2 0x400
36#define LG_RDESC_REL_ABS 0x800 40#define LG_RDESC_REL_ABS 0x800
37#define LG_FF3 0x1000 41#define LG_FF3 0x1000
42#define LG_FF4 0x2000
38 43
39/* 44/*
40 * Certain Logitech keyboards send in report #3 keys which are far 45 * Certain Logitech keyboards send in report #3 keys which are far
@@ -60,6 +65,17 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
60 "report descriptor\n"); 65 "report descriptor\n");
61 rdesc[33] = rdesc[50] = 0x02; 66 rdesc[33] = rdesc[50] = 0x02;
62 } 67 }
68
69 if ((quirks & LG_FF4) && rsize >= 101 &&
70 rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
71 rdesc[47] == 0x05 && rdesc[48] == 0x09) {
72 dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless "
73 "button descriptor\n");
74 rdesc[41] = 0x05;
75 rdesc[42] = 0x09;
76 rdesc[47] = 0x95;
77 rdesc[48] = 0x0B;
78 }
63} 79}
64 80
65#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 81#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
@@ -285,12 +301,33 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
285 goto err_free; 301 goto err_free;
286 } 302 }
287 303
304 if (quirks & LG_FF4) {
305 unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
306
307 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
308
309 if (ret >= 0) {
310 /* insert a little delay of 10 jiffies ~ 40ms */
311 wait_queue_head_t wait;
312 init_waitqueue_head (&wait);
313 wait_event_interruptible_timeout(wait, 0, 10);
314
315 /* Select random Address */
316 buf[1] = 0xB2;
317 get_random_bytes(&buf[2], 2);
318
319 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
320 }
321 }
322
288 if (quirks & LG_FF) 323 if (quirks & LG_FF)
289 lgff_init(hdev); 324 lgff_init(hdev);
290 if (quirks & LG_FF2) 325 if (quirks & LG_FF2)
291 lg2ff_init(hdev); 326 lg2ff_init(hdev);
292 if (quirks & LG_FF3) 327 if (quirks & LG_FF3)
293 lg3ff_init(hdev); 328 lg3ff_init(hdev);
329 if (quirks & LG_FF4)
330 lg4ff_init(hdev);
294 331
295 return 0; 332 return 0;
296err_free: 333err_free:
@@ -325,6 +362,8 @@ static const struct hid_device_id lg_devices[] = {
325 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), 362 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
326 .driver_data = LG_NOGET | LG_FF }, 363 .driver_data = LG_NOGET | LG_FF },
327 364
365 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
366 .driver_data = LG_FF2 },
328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), 367 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
329 .driver_data = LG_FF }, 368 .driver_data = LG_FF },
330 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), 369 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
@@ -339,6 +378,8 @@ static const struct hid_device_id lg_devices[] = {
339 .driver_data = LG_FF }, 378 .driver_data = LG_FF },
340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), 379 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
341 .driver_data = LG_FF }, 380 .driver_data = LG_FF },
381 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
382 .driver_data = LG_FF4 },
342 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), 383 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
343 .driver_data = LG_FF }, 384 .driver_data = LG_FF },
344 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), 385 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h
index ce2ac8672624..b0100ba2ae0b 100644
--- a/drivers/hid/hid-lg.h
+++ b/drivers/hid/hid-lg.h
@@ -19,4 +19,10 @@ int lg3ff_init(struct hid_device *hdev);
19static inline int lg3ff_init(struct hid_device *hdev) { return -1; } 19static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
20#endif 20#endif
21 21
22#ifdef CONFIG_LOGIWII_FF
23int lg4ff_init(struct hid_device *hdev);
24#else
25static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
26#endif
27
22#endif 28#endif
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
index d888f1e6794f..4258253c36b3 100644
--- a/drivers/hid/hid-lg2ff.c
+++ b/drivers/hid/hid-lg2ff.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Force feedback support for Logitech Rumblepad 2 2 * Force feedback support for Logitech RumblePad and Rumblepad 2
3 * 3 *
4 * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com> 4 * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
5 */ 5 */
@@ -110,7 +110,7 @@ int lg2ff_init(struct hid_device *hid)
110 110
111 usbhid_submit_report(hid, report, USB_DIR_OUT); 111 usbhid_submit_report(hid, report, USB_DIR_OUT);
112 112
113 dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by " 113 dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by "
114 "Anssi Hannula <anssi.hannula@gmail.com>\n"); 114 "Anssi Hannula <anssi.hannula@gmail.com>\n");
115 115
116 return 0; 116 return 0;
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
new file mode 100644
index 000000000000..7eef5a2ce948
--- /dev/null
+++ b/drivers/hid/hid-lg4ff.c
@@ -0,0 +1,136 @@
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
33struct lg4ff_device {
34 struct hid_report *report;
35};
36
37static const signed short ff4_wheel_ac[] = {
38 FF_CONSTANT,
39 FF_AUTOCENTER,
40 -1
41};
42
43static 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
72static 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
91int lg4ff_init(struct hid_device *hid)
92{
93 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
94 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
95 struct input_dev *dev = hidinput->input;
96 struct hid_report *report;
97 struct hid_field *field;
98 const signed short *ff_bits = ff4_wheel_ac;
99 int error;
100 int i;
101
102 /* Find the report to use */
103 if (list_empty(report_list)) {
104 err_hid("No output report found");
105 return -1;
106 }
107
108 /* Check that the report looks ok */
109 report = list_entry(report_list->next, struct hid_report, list);
110 if (!report) {
111 err_hid("NULL output report");
112 return -1;
113 }
114
115 field = report->field[0];
116 if (!field) {
117 err_hid("NULL field");
118 return -1;
119 }
120
121 for (i = 0; ff_bits[i] >= 0; i++)
122 set_bit(ff_bits[i], dev->ffbit);
123
124 error = input_ff_create_memless(dev, NULL, hid_lg4ff_play);
125
126 if (error)
127 return error;
128
129 if (test_bit(FF_AUTOCENTER, dev->ffbit))
130 dev->ff->set_autocenter = hid_lg4ff_set_autocenter;
131
132 dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by "
133 "Simon Wood <simon@mungewell.org>\n");
134 return 0;
135}
136
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 319b0e57ee41..e6dc15171664 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -2,6 +2,7 @@
2 * Apple "Magic" Wireless Mouse driver 2 * Apple "Magic" Wireless Mouse driver
3 * 3 *
4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> 4 * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
5 * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
5 */ 6 */
6 7
7/* 8/*
@@ -53,7 +54,9 @@ static bool report_undeciphered;
53module_param(report_undeciphered, bool, 0644); 54module_param(report_undeciphered, bool, 0644);
54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 55MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
55 56
56#define TOUCH_REPORT_ID 0x29 57#define TRACKPAD_REPORT_ID 0x28
58#define MOUSE_REPORT_ID 0x29
59#define DOUBLE_REPORT_ID 0xf7
57/* These definitions are not precise, but they're close enough. (Bits 60/* These definitions are not precise, but they're close enough. (Bits
58 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem 61 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
59 * to be some kind of bit mask -- 0x20 may be a near-field reading, 62 * to be some kind of bit mask -- 0x20 may be a near-field reading,
@@ -67,15 +70,19 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
67 70
68#define SCROLL_ACCEL_DEFAULT 7 71#define SCROLL_ACCEL_DEFAULT 7
69 72
73/* Single touch emulation should only begin when no touches are currently down.
74 * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
75 * are down and the touch providing for single touch emulation is lifted,
76 * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
77 * occuring, single_touch_id corresponds with the tracking id of the touch used.
78 */
79#define NO_TOUCHES -1
80#define SINGLE_TOUCH_UP -2
81
70/** 82/**
71 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 83 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
72 * @input: Input device through which we report events. 84 * @input: Input device through which we report events.
73 * @quirks: Currently unused. 85 * @quirks: Currently unused.
74 * @last_timestamp: Timestamp from most recent (18-bit) touch report
75 * (units of milliseconds over short windows, but seems to
76 * increase faster when there are no touches).
77 * @delta_time: 18-bit difference between the two most recent touch
78 * reports from the mouse.
79 * @ntouches: Number of touches in most recent touch report. 86 * @ntouches: Number of touches in most recent touch report.
80 * @scroll_accel: Number of consecutive scroll motions. 87 * @scroll_accel: Number of consecutive scroll motions.
81 * @scroll_jiffies: Time of last scroll motion. 88 * @scroll_jiffies: Time of last scroll motion.
@@ -86,8 +93,6 @@ struct magicmouse_sc {
86 struct input_dev *input; 93 struct input_dev *input;
87 unsigned long quirks; 94 unsigned long quirks;
88 95
89 int last_timestamp;
90 int delta_time;
91 int ntouches; 96 int ntouches;
92 int scroll_accel; 97 int scroll_accel;
93 unsigned long scroll_jiffies; 98 unsigned long scroll_jiffies;
@@ -98,9 +103,9 @@ struct magicmouse_sc {
98 short scroll_x; 103 short scroll_x;
99 short scroll_y; 104 short scroll_y;
100 u8 size; 105 u8 size;
101 u8 down;
102 } touches[16]; 106 } touches[16];
103 int tracking_ids[16]; 107 int tracking_ids[16];
108 int single_touch_id;
104}; 109};
105 110
106static int magicmouse_firm_touch(struct magicmouse_sc *msc) 111static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -166,18 +171,35 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
166static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 171static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
167{ 172{
168 struct input_dev *input = msc->input; 173 struct input_dev *input = msc->input;
169 __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; 174 int id, x, y, size, orientation, touch_major, touch_minor, state, down;
170 int misc = tdata[5] | tdata[6] << 8; 175
171 int id = (misc >> 6) & 15; 176 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
172 int x = x_y << 12 >> 20; 177 id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
173 int y = -(x_y >> 20); 178 x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
174 int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; 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 }
175 197
176 /* Store tracking ID and other fields. */ 198 /* Store tracking ID and other fields. */
177 msc->tracking_ids[raw_id] = id; 199 msc->tracking_ids[raw_id] = id;
178 msc->touches[id].x = x; 200 msc->touches[id].x = x;
179 msc->touches[id].y = y; 201 msc->touches[id].y = y;
180 msc->touches[id].size = misc & 63; 202 msc->touches[id].size = size;
181 203
182 /* If requested, emulate a scroll wheel by detecting small 204 /* If requested, emulate a scroll wheel by detecting small
183 * vertical touch motions. 205 * vertical touch motions.
@@ -188,7 +210,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
188 int step_y = msc->touches[id].scroll_y - y; 210 int step_y = msc->touches[id].scroll_y - y;
189 211
190 /* Calculate and apply the scroll motion. */ 212 /* Calculate and apply the scroll motion. */
191 switch (tdata[7] & TOUCH_STATE_MASK) { 213 switch (state) {
192 case TOUCH_STATE_START: 214 case TOUCH_STATE_START:
193 msc->touches[id].scroll_x = x; 215 msc->touches[id].scroll_x = x;
194 msc->touches[id].scroll_y = y; 216 msc->touches[id].scroll_y = y;
@@ -222,21 +244,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
222 } 244 }
223 } 245 }
224 246
247 if (down) {
248 msc->ntouches++;
249 if (msc->single_touch_id == NO_TOUCHES)
250 msc->single_touch_id = id;
251 } else if (msc->single_touch_id == id)
252 msc->single_touch_id = SINGLE_TOUCH_UP;
253
225 /* Generate the input events for this touch. */ 254 /* Generate the input events for this touch. */
226 if (report_touches && down) { 255 if (report_touches && down) {
227 int orientation = (misc >> 10) - 32;
228
229 msc->touches[id].down = 1;
230
231 input_report_abs(input, ABS_MT_TRACKING_ID, id); 256 input_report_abs(input, ABS_MT_TRACKING_ID, id);
232 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); 257 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
233 input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); 258 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
234 input_report_abs(input, ABS_MT_ORIENTATION, orientation); 259 input_report_abs(input, ABS_MT_ORIENTATION, orientation);
235 input_report_abs(input, ABS_MT_POSITION_X, x); 260 input_report_abs(input, ABS_MT_POSITION_X, x);
236 input_report_abs(input, ABS_MT_POSITION_Y, y); 261 input_report_abs(input, ABS_MT_POSITION_Y, y);
237 262
238 if (report_undeciphered) 263 if (report_undeciphered) {
239 input_event(input, EV_MSC, MSC_RAW, tdata[7]); 264 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
265 input_event(input, EV_MSC, MSC_RAW, tdata[7]);
266 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
267 input_event(input, EV_MSC, MSC_RAW, tdata[8]);
268 }
240 269
241 input_mt_sync(input); 270 input_mt_sync(input);
242 } 271 }
@@ -247,39 +276,43 @@ static int magicmouse_raw_event(struct hid_device *hdev,
247{ 276{
248 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 277 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
249 struct input_dev *input = msc->input; 278 struct input_dev *input = msc->input;
250 int x, y, ts, ii, clicks, last_up; 279 int x = 0, y = 0, ii, clicks = 0, npoints;
251 280
252 switch (data[0]) { 281 switch (data[0]) {
253 case 0x10: 282 case TRACKPAD_REPORT_ID:
254 if (size != 6) 283 /* Expect four bytes of prefix, and N*9 bytes of touch data. */
284 if (size < 4 || ((size - 4) % 9) != 0)
255 return 0; 285 return 0;
256 x = (__s16)(data[2] | data[3] << 8); 286 npoints = (size - 4) / 9;
257 y = (__s16)(data[4] | data[5] << 8); 287 msc->ntouches = 0;
288 for (ii = 0; ii < npoints; ii++)
289 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
290
291 /* We don't need an MT sync here because trackpad emits a
292 * BTN_TOUCH event in a new frame when all touches are released.
293 */
294 if (msc->ntouches == 0)
295 msc->single_touch_id = NO_TOUCHES;
296
258 clicks = data[1]; 297 clicks = data[1];
298
299 /* The following bits provide a device specific timestamp. They
300 * are unused here.
301 *
302 * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
303 */
259 break; 304 break;
260 case TOUCH_REPORT_ID: 305 case MOUSE_REPORT_ID:
261 /* Expect six bytes of prefix, and N*8 bytes of touch data. */ 306 /* Expect six bytes of prefix, and N*8 bytes of touch data. */
262 if (size < 6 || ((size - 6) % 8) != 0) 307 if (size < 6 || ((size - 6) % 8) != 0)
263 return 0; 308 return 0;
264 ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; 309 npoints = (size - 6) / 8;
265 msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; 310 msc->ntouches = 0;
266 msc->last_timestamp = ts; 311 for (ii = 0; ii < npoints; ii++)
267 msc->ntouches = (size - 6) / 8;
268 for (ii = 0; ii < msc->ntouches; ii++)
269 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 312 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
270 313
271 if (report_touches) { 314 if (report_touches && msc->ntouches == 0)
272 last_up = 1; 315 input_mt_sync(input);
273 for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) {
274 if (msc->touches[ii].down) {
275 last_up = 0;
276 msc->touches[ii].down = 0;
277 }
278 }
279 if (last_up) {
280 input_mt_sync(input);
281 }
282 }
283 316
284 /* When emulating three-button mode, it is important 317 /* When emulating three-button mode, it is important
285 * to have the current touch information before 318 * to have the current touch information before
@@ -288,68 +321,72 @@ static int magicmouse_raw_event(struct hid_device *hdev,
288 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; 321 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
289 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; 322 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
290 clicks = data[3]; 323 clicks = data[3];
324
325 /* The following bits provide a device specific timestamp. They
326 * are unused here.
327 *
328 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
329 */
330 break;
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]);
291 break; 338 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 */
299 default: 339 default:
300 return 0; 340 return 0;
301 } 341 }
302 342
303 magicmouse_emit_buttons(msc, clicks & 3); 343 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
304 input_report_rel(input, REL_X, x); 344 magicmouse_emit_buttons(msc, clicks & 3);
305 input_report_rel(input, REL_Y, y); 345 input_report_rel(input, REL_X, x);
346 input_report_rel(input, REL_Y, y);
347 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
348 input_report_key(input, BTN_MOUSE, clicks & 1);
349 input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
350 input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
351 input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
352 input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
353 input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
354 if (msc->single_touch_id >= 0) {
355 input_report_abs(input, ABS_X,
356 msc->touches[msc->single_touch_id].x);
357 input_report_abs(input, ABS_Y,
358 msc->touches[msc->single_touch_id].y);
359 }
360 }
361
306 input_sync(input); 362 input_sync(input);
307 return 1; 363 return 1;
308} 364}
309 365
310static 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
317static 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
324static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 366static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
325{ 367{
326 input_set_drvdata(input, hdev);
327 input->event = hdev->ll_driver->hidinput_input_event;
328 input->open = magicmouse_input_open;
329 input->close = magicmouse_input_close;
330
331 input->name = hdev->name;
332 input->phys = hdev->phys;
333 input->uniq = hdev->uniq;
334 input->id.bustype = hdev->bus;
335 input->id.vendor = hdev->vendor;
336 input->id.product = hdev->product;
337 input->id.version = hdev->version;
338 input->dev.parent = hdev->dev.parent;
339
340 __set_bit(EV_KEY, input->evbit); 368 __set_bit(EV_KEY, input->evbit);
341 __set_bit(BTN_LEFT, input->keybit); 369
342 __set_bit(BTN_RIGHT, input->keybit); 370 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
343 if (emulate_3button) 371 __set_bit(BTN_LEFT, input->keybit);
344 __set_bit(BTN_MIDDLE, input->keybit); 372 __set_bit(BTN_RIGHT, input->keybit);
345 __set_bit(BTN_TOOL_FINGER, input->keybit); 373 if (emulate_3button)
346 374 __set_bit(BTN_MIDDLE, input->keybit);
347 __set_bit(EV_REL, input->evbit); 375
348 __set_bit(REL_X, input->relbit); 376 __set_bit(EV_REL, input->evbit);
349 __set_bit(REL_Y, input->relbit); 377 __set_bit(REL_X, input->relbit);
350 if (emulate_scroll_wheel) { 378 __set_bit(REL_Y, input->relbit);
351 __set_bit(REL_WHEEL, input->relbit); 379 if (emulate_scroll_wheel) {
352 __set_bit(REL_HWHEEL, input->relbit); 380 __set_bit(REL_WHEEL, input->relbit);
381 __set_bit(REL_HWHEEL, input->relbit);
382 }
383 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
384 __set_bit(BTN_MOUSE, input->keybit);
385 __set_bit(BTN_TOOL_FINGER, input->keybit);
386 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
387 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
388 __set_bit(BTN_TOOL_QUADTAP, input->keybit);
389 __set_bit(BTN_TOUCH, input->keybit);
353 } 390 }
354 391
355 if (report_touches) { 392 if (report_touches) {
@@ -359,16 +396,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
359 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); 396 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
360 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); 397 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
361 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); 398 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
362 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, 399
363 4, 0);
364 /* Note: Touch Y position from the device is inverted relative 400 /* Note: Touch Y position from the device is inverted relative
365 * to how pointer motion is reported (and relative to how USB 401 * to how pointer motion is reported (and relative to how USB
366 * HID recommends the coordinates work). This driver keeps 402 * HID recommends the coordinates work). This driver keeps
367 * the origin at the same position, and just uses the additive 403 * the origin at the same position, and just uses the additive
368 * inverse of the reported Y. 404 * inverse of the reported Y.
369 */ 405 */
370 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, 406 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
371 4, 0); 407 input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
408 1358, 4, 0);
409 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
410 2047, 4, 0);
411 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
412 input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
413 input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
414 input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
415 3167, 4, 0);
416 input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
417 2565, 4, 0);
418 }
372 } 419 }
373 420
374 if (report_undeciphered) { 421 if (report_undeciphered) {
@@ -377,12 +424,22 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
377 } 424 }
378} 425}
379 426
427static 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
380static int magicmouse_probe(struct hid_device *hdev, 439static int magicmouse_probe(struct hid_device *hdev,
381 const struct hid_device_id *id) 440 const struct hid_device_id *id)
382{ 441{
383 __u8 feature_1[] = { 0xd7, 0x01 }; 442 __u8 feature[] = { 0xd7, 0x01 };
384 __u8 feature_2[] = { 0xf8, 0x01, 0x32 };
385 struct input_dev *input;
386 struct magicmouse_sc *msc; 443 struct magicmouse_sc *msc;
387 struct hid_report *report; 444 struct hid_report *report;
388 int ret; 445 int ret;
@@ -398,6 +455,8 @@ static int magicmouse_probe(struct hid_device *hdev,
398 msc->quirks = id->driver_data; 455 msc->quirks = id->driver_data;
399 hid_set_drvdata(hdev, msc); 456 hid_set_drvdata(hdev, msc);
400 457
458 msc->single_touch_id = NO_TOUCHES;
459
401 ret = hid_parse(hdev); 460 ret = hid_parse(hdev);
402 if (ret) { 461 if (ret) {
403 dev_err(&hdev->dev, "magicmouse hid parse failed\n"); 462 dev_err(&hdev->dev, "magicmouse hid parse failed\n");
@@ -410,10 +469,22 @@ static int magicmouse_probe(struct hid_device *hdev,
410 goto err_free; 469 goto err_free;
411 } 470 }
412 471
413 /* we are handling the input ourselves */ 472 /* We do this after hid-input is done parsing reports so that
414 hidinput_disconnect(hdev); 473 * hid-input uses the most natural button and axis IDs.
474 */
475 if (msc->input)
476 magicmouse_setup_input(msc->input, hdev);
477
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 }
415 487
416 report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID);
417 if (!report) { 488 if (!report) {
418 dev_err(&hdev->dev, "unable to register touch report\n"); 489 dev_err(&hdev->dev, "unable to register touch report\n");
419 ret = -ENOMEM; 490 ret = -ENOMEM;
@@ -421,39 +492,15 @@ static int magicmouse_probe(struct hid_device *hdev,
421 } 492 }
422 report->size = 6; 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 HID_FEATURE_REPORT); 496 HID_FEATURE_REPORT);
426 if (ret != sizeof(feature_1)) { 497 if (ret != sizeof(feature)) {
427 dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", 498 dev_err(&hdev->dev, "unable to request touch data (%d)\n",
428 ret);
429 goto err_stop_hw;
430 }
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); 499 ret);
436 goto err_stop_hw; 500 goto err_stop_hw;
437 } 501 }
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 return 0; 503 return 0;
455err_input:
456 input_free_device(input);
457err_stop_hw: 504err_stop_hw:
458 hid_hw_stop(hdev); 505 hid_hw_stop(hdev);
459err_free: 506err_free:
@@ -466,13 +513,14 @@ static void magicmouse_remove(struct hid_device *hdev)
466 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 513 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
467 514
468 hid_hw_stop(hdev); 515 hid_hw_stop(hdev);
469 input_unregister_device(msc->input);
470 kfree(msc); 516 kfree(msc);
471} 517}
472 518
473static const struct hid_device_id magic_mice[] = { 519static const struct hid_device_id magic_mice[] = {
474 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), 520 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
475 .driver_data = 0 }, 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};
478MODULE_DEVICE_TABLE(hid, magic_mice); 526MODULE_DEVICE_TABLE(hid, magic_mice);
@@ -483,6 +531,7 @@ static struct hid_driver magicmouse_driver = {
483 .probe = magicmouse_probe, 531 .probe = magicmouse_probe,
484 .remove = magicmouse_remove, 532 .remove = magicmouse_remove,
485 .raw_event = magicmouse_raw_event, 533 .raw_event = magicmouse_raw_event,
534 .input_mapping = magicmouse_input_mapping,
486}; 535};
487 536
488static int __init magicmouse_init(void) 537static int __init magicmouse_init(void)
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index fb69b8c4953f..69169efa1e16 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -90,6 +90,55 @@ struct ntrig_data {
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 */
97static 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
113static 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
138err_free:
139 kfree(data);
140}
141
93static ssize_t show_phys_width(struct device *dev, 142static ssize_t show_phys_width(struct device *dev,
94 struct device_attribute *attr, 143 struct device_attribute *attr,
95 char *buf) 144 char *buf)
@@ -377,8 +426,8 @@ static struct attribute_group ntrig_attribute_group = {
377 */ 426 */
378 427
379static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, 428static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
380 struct hid_field *field, struct hid_usage *usage, 429 struct hid_field *field, struct hid_usage *usage,
381 unsigned long **bit, int *max) 430 unsigned long **bit, int *max)
382{ 431{
383 struct ntrig_data *nd = hid_get_drvdata(hdev); 432 struct ntrig_data *nd = hid_get_drvdata(hdev);
384 433
@@ -448,13 +497,13 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
448 /* width/height mapped on TouchMajor/TouchMinor/Orientation */ 497 /* width/height mapped on TouchMajor/TouchMinor/Orientation */
449 case HID_DG_WIDTH: 498 case HID_DG_WIDTH:
450 hid_map_usage(hi, usage, bit, max, 499 hid_map_usage(hi, usage, bit, max,
451 EV_ABS, ABS_MT_TOUCH_MAJOR); 500 EV_ABS, ABS_MT_TOUCH_MAJOR);
452 return 1; 501 return 1;
453 case HID_DG_HEIGHT: 502 case HID_DG_HEIGHT:
454 hid_map_usage(hi, usage, bit, max, 503 hid_map_usage(hi, usage, bit, max,
455 EV_ABS, ABS_MT_TOUCH_MINOR); 504 EV_ABS, ABS_MT_TOUCH_MINOR);
456 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 505 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
457 0, 1, 0, 0); 506 0, 1, 0, 0);
458 return 1; 507 return 1;
459 } 508 }
460 return 0; 509 return 0;
@@ -468,8 +517,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
468} 517}
469 518
470static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, 519static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
471 struct hid_field *field, struct hid_usage *usage, 520 struct hid_field *field, struct hid_usage *usage,
472 unsigned long **bit, int *max) 521 unsigned long **bit, int *max)
473{ 522{
474 /* No special mappings needed for the pen and single touch */ 523 /* No special mappings needed for the pen and single touch */
475 if (field->physical) 524 if (field->physical)
@@ -489,7 +538,7 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
489 * and call input_mt_sync after each point if necessary 538 * and call input_mt_sync after each point if necessary
490 */ 539 */
491static int ntrig_event (struct hid_device *hid, struct hid_field *field, 540static int ntrig_event (struct hid_device *hid, struct hid_field *field,
492 struct hid_usage *usage, __s32 value) 541 struct hid_usage *usage, __s32 value)
493{ 542{
494 struct input_dev *input = field->hidinput->input; 543 struct input_dev *input = field->hidinput->input;
495 struct ntrig_data *nd = hid_get_drvdata(hid); 544 struct ntrig_data *nd = hid_get_drvdata(hid);
@@ -848,6 +897,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
848 if (report) 897 if (report)
849 usbhid_submit_report(hdev, report, USB_DIR_OUT); 898 usbhid_submit_report(hdev, report, USB_DIR_OUT);
850 899
900 ntrig_report_version(hdev);
901
851 ret = sysfs_create_group(&hdev->dev.kobj, 902 ret = sysfs_create_group(&hdev->dev.kobj,
852 &ntrig_attribute_group); 903 &ntrig_attribute_group);
853 904
@@ -860,7 +911,7 @@ err_free:
860static void ntrig_remove(struct hid_device *hdev) 911static void ntrig_remove(struct hid_device *hdev)
861{ 912{
862 sysfs_remove_group(&hdev->dev.kobj, 913 sysfs_remove_group(&hdev->dev.kobj,
863 &ntrig_attribute_group); 914 &ntrig_attribute_group);
864 hid_hw_stop(hdev); 915 hid_hw_stop(hdev);
865 kfree(hid_get_drvdata(hdev)); 916 kfree(hid_get_drvdata(hdev));
866} 917}
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
new file mode 100644
index 000000000000..9bf23047892a
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -0,0 +1,968 @@
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
30static 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
37static 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
65static 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
97static 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
121static 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
145static 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
159static 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
172static 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
189static 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
206static 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
222static 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
243static 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
251static 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
259static 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
267static 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
275static 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
283static 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
304static 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
312static 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
320static 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
328static 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
336static 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
344static 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
380static 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
416static 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
436static 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
469static 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
476static 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
483static 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
490static 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
497static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
498
499static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
500
501static DEVICE_ATTR(firmware_version, 0440,
502 pyra_sysfs_show_firmware_version, NULL);
503
504static DEVICE_ATTR(startup_profile, 0440,
505 pyra_sysfs_show_startup_profile, NULL);
506
507static 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
515static struct attribute_group pyra_attribute_group = {
516 .attrs = pyra_attributes
517};
518
519static 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
525static 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
531static 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
537static 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
543static 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
549static 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
555static 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
561static 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
567static 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
573static 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
579static 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
585static 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
591static 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
598static 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
673exit_14:
674 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
675exit_13:
676 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
677exit_12:
678 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
679exit_11:
680 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
681exit_10:
682 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
683exit_9:
684 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
685exit_8:
686 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
687exit_7:
688 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
689exit_6:
690 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
691exit_5:
692 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
693exit_4:
694 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
695exit_3:
696 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
697exit_2:
698 sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
699exit_1:
700 return retval;
701}
702
703static 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
721static 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
761static 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;
803exit_free:
804 kfree(pyra);
805 return retval;
806}
807
808static 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
823static 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
846exit_stop:
847 hid_hw_stop(hdev);
848exit:
849 return retval;
850}
851
852static void pyra_remove(struct hid_device *hdev)
853{
854 pyra_remove_specials(hdev);
855 hid_hw_stop(hdev);
856}
857
858static 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
878static 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
918static 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
936static 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
943MODULE_DEVICE_TABLE(hid, pyra_devices);
944
945static 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
953static int __init pyra_init(void)
954{
955 return hid_register_driver(&pyra_driver);
956}
957
958static void __exit pyra_exit(void)
959{
960 hid_unregister_driver(&pyra_driver);
961}
962
963module_init(pyra_init);
964module_exit(pyra_exit);
965
966MODULE_AUTHOR("Stefan Achatz");
967MODULE_DESCRIPTION("USB Roccat Pyra driver");
968MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
new file mode 100644
index 000000000000..22f80a8f26f9
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -0,0 +1,186 @@
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
20struct pyra_b {
21 uint8_t command; /* PYRA_COMMAND_B */
22 uint8_t size; /* always 3 */
23 uint8_t unknown; /* 1 */
24};
25
26struct 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
36enum 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
42struct 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
48struct 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
63struct 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
71struct 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
80enum 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
89enum 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
98enum 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
104struct 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
112struct 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 */
119enum 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
125enum 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
161enum {
162 PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
163 PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
164};
165
166struct pyra_roccat_report {
167 uint8_t type;
168 uint8_t value;
169 uint8_t key;
170};
171
172#pragma pack(pop)
173
174struct 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
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7a778ac4c5cb..5489eab3a6bd 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -807,7 +807,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
807 struct usb_host_interface *interface = intf->cur_altsetting; 807 struct usb_host_interface *interface = intf->cur_altsetting;
808 int ret; 808 int ret;
809 809
810 if (usbhid->urbout) { 810 if (usbhid->urbout && report_type != HID_FEATURE_REPORT) {
811 int actual_length; 811 int actual_length;
812 int skipped_report_id = 0; 812 int skipped_report_id = 0;
813 813
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index f90e937b577f..836a87473c58 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -34,7 +34,6 @@ static const struct hid_blacklist {
34 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, 34 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
35 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, 35 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
36 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, 36 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
37 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
38 { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, 37 { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
39 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, 38 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT },
40 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 39 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },