aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-magicmouse.c100
1 files changed, 40 insertions, 60 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index f94b3e43c5b6..4a3a94f2b10c 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -18,22 +18,22 @@
18 18
19#include "hid-ids.h" 19#include "hid-ids.h"
20 20
21static bool emulate_3button = 1; 21static bool emulate_3button = true;
22module_param(emulate_3button, bool, 0644); 22module_param(emulate_3button, bool, 0644);
23MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); 23MODULE_PARM_DESC(emulate_3button, "Emulate a middle button");
24 24
25static int middle_button_start = -350; 25static int middle_button_start = -350;
26static int middle_button_stop = +350; 26static int middle_button_stop = +350;
27 27
28static bool emulate_scroll_wheel = 1; 28static bool emulate_scroll_wheel = true;
29module_param(emulate_scroll_wheel, bool, 0644); 29module_param(emulate_scroll_wheel, bool, 0644);
30MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); 30MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
31 31
32static bool report_touches = 1; 32static bool report_touches = true;
33module_param(report_touches, bool, 0644); 33module_param(report_touches, bool, 0644);
34MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); 34MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
35 35
36static bool report_undeciphered = 0; 36static bool report_undeciphered;
37module_param(report_undeciphered, bool, 0644); 37module_param(report_undeciphered, bool, 0644);
38MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 38MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
39 39
@@ -108,9 +108,9 @@ static int magicmouse_firm_touch(struct magicmouse_sc *msc)
108 108
109static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) 109static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
110{ 110{
111 int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 | 111 int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 |
112 test_bit(BTN_RIGHT, msc->input->key) << 1 | 112 test_bit(BTN_RIGHT, msc->input->key) << 1 |
113 test_bit(BTN_MIDDLE, msc->input->key) << 2; 113 test_bit(BTN_MIDDLE, msc->input->key) << 2;
114 114
115 if (emulate_3button) { 115 if (emulate_3button) {
116 int id; 116 int id;
@@ -177,7 +177,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
177 switch (tdata[7] & TOUCH_STATE_MASK) { 177 switch (tdata[7] & TOUCH_STATE_MASK) {
178 case TOUCH_STATE_START: 178 case TOUCH_STATE_START:
179 msc->touches[id].scroll_y = y; 179 msc->touches[id].scroll_y = y;
180 msc->scroll_accel = min_t(int, msc->scroll_accel + 1, 180 msc->scroll_accel = min_t(int, msc->scroll_accel + 1,
181 ARRAY_SIZE(accel_profile) - 1); 181 ARRAY_SIZE(accel_profile) - 1);
182 break; 182 break;
183 case TOUCH_STATE_DRAG: 183 case TOUCH_STATE_DRAG:
@@ -193,7 +193,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
193 193
194 /* Generate the input events for this touch. */ 194 /* Generate the input events for this touch. */
195 if (report_touches) { 195 if (report_touches) {
196 int orientation = (misc >> 10) - 32; 196 int orientation = (misc >> 10) - 32;
197 197
198 input_report_abs(input, ABS_MT_TRACKING_ID, id); 198 input_report_abs(input, ABS_MT_TRACKING_ID, id);
199 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); 199 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
@@ -202,9 +202,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
202 input_report_abs(input, ABS_MT_POSITION_X, x); 202 input_report_abs(input, ABS_MT_POSITION_X, x);
203 input_report_abs(input, ABS_MT_POSITION_Y, y); 203 input_report_abs(input, ABS_MT_POSITION_Y, y);
204 204
205 if (report_undeciphered) { 205 if (report_undeciphered)
206 input_event(input, EV_MSC, MSC_RAW, tdata[7]); 206 input_event(input, EV_MSC, MSC_RAW, tdata[7]);
207 }
208 207
209 input_mt_sync(input); 208 input_mt_sync(input);
210 } 209 }
@@ -291,62 +290,41 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
291 input->id.version = hdev->version; 290 input->id.version = hdev->version;
292 input->dev.parent = hdev->dev.parent; 291 input->dev.parent = hdev->dev.parent;
293 292
294 set_bit(EV_KEY, input->evbit); 293 __set_bit(EV_KEY, input->evbit);
295 set_bit(BTN_LEFT, input->keybit); 294 __set_bit(BTN_LEFT, input->keybit);
296 set_bit(BTN_RIGHT, input->keybit); 295 __set_bit(BTN_RIGHT, input->keybit);
297 if (emulate_3button) 296 if (emulate_3button)
298 set_bit(BTN_MIDDLE, input->keybit); 297 __set_bit(BTN_MIDDLE, input->keybit);
299 set_bit(BTN_TOOL_FINGER, input->keybit); 298 __set_bit(BTN_TOOL_FINGER, input->keybit);
300 299
301 set_bit(EV_REL, input->evbit); 300 __set_bit(EV_REL, input->evbit);
302 set_bit(REL_X, input->relbit); 301 __set_bit(REL_X, input->relbit);
303 set_bit(REL_Y, input->relbit); 302 __set_bit(REL_Y, input->relbit);
304 if (emulate_scroll_wheel) 303 if (emulate_scroll_wheel)
305 set_bit(REL_WHEEL, input->relbit); 304 __set_bit(REL_WHEEL, input->relbit);
306 305
307 if (report_touches) { 306 if (report_touches) {
308 set_bit(EV_ABS, input->evbit); 307 __set_bit(EV_ABS, input->evbit);
309 308
310 set_bit(ABS_MT_TRACKING_ID, input->absbit); 309 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0);
311 input->absmin[ABS_MT_TRACKING_ID] = 0; 310 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
312 input->absmax[ABS_MT_TRACKING_ID] = 15; 311 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
313 input->absfuzz[ABS_MT_TRACKING_ID] = 0; 312 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
314 313 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358,
315 set_bit(ABS_MT_TOUCH_MAJOR, input->absbit); 314 4, 0);
316 input->absmin[ABS_MT_TOUCH_MAJOR] = 0;
317 input->absmax[ABS_MT_TOUCH_MAJOR] = 255;
318 input->absfuzz[ABS_MT_TOUCH_MAJOR] = 4;
319
320 set_bit(ABS_MT_TOUCH_MINOR, input->absbit);
321 input->absmin[ABS_MT_TOUCH_MINOR] = 0;
322 input->absmax[ABS_MT_TOUCH_MINOR] = 255;
323 input->absfuzz[ABS_MT_TOUCH_MINOR] = 4;
324
325 set_bit(ABS_MT_ORIENTATION, input->absbit);
326 input->absmin[ABS_MT_ORIENTATION] = -32;
327 input->absmax[ABS_MT_ORIENTATION] = 31;
328 input->absfuzz[ABS_MT_ORIENTATION] = 1;
329
330 set_bit(ABS_MT_POSITION_X, input->absbit);
331 input->absmin[ABS_MT_POSITION_X] = -1100;
332 input->absmax[ABS_MT_POSITION_X] = 1358;
333 input->absfuzz[ABS_MT_POSITION_X] = 4;
334
335 /* Note: Touch Y position from the device is inverted relative 315 /* Note: Touch Y position from the device is inverted relative
336 * to how pointer motion is reported (and relative to how USB 316 * to how pointer motion is reported (and relative to how USB
337 * HID recommends the coordinates work). This driver keeps 317 * HID recommends the coordinates work). This driver keeps
338 * the origin at the same position, and just uses the additive 318 * the origin at the same position, and just uses the additive
339 * inverse of the reported Y. 319 * inverse of the reported Y.
340 */ 320 */
341 set_bit(ABS_MT_POSITION_Y, input->absbit); 321 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047,
342 input->absmin[ABS_MT_POSITION_Y] = -1589; 322 4, 0);
343 input->absmax[ABS_MT_POSITION_Y] = 2047;
344 input->absfuzz[ABS_MT_POSITION_Y] = 4;
345 } 323 }
346 324
347 if (report_undeciphered) { 325 if (report_undeciphered) {
348 set_bit(EV_MSC, input->evbit); 326 __set_bit(EV_MSC, input->evbit);
349 set_bit(MSC_RAW, input->mscbit); 327 __set_bit(MSC_RAW, input->mscbit);
350 } 328 }
351} 329}
352 330
@@ -385,7 +363,7 @@ static int magicmouse_probe(struct hid_device *hdev,
385 if (!report) { 363 if (!report) {
386 dev_err(&hdev->dev, "unable to register touch report\n"); 364 dev_err(&hdev->dev, "unable to register touch report\n");
387 ret = -ENOMEM; 365 ret = -ENOMEM;
388 goto err_free; 366 goto err_stop_hw;
389 } 367 }
390 report->size = 6; 368 report->size = 6;
391 369
@@ -394,35 +372,37 @@ static int magicmouse_probe(struct hid_device *hdev,
394 if (ret != sizeof(feature_1)) { 372 if (ret != sizeof(feature_1)) {
395 dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", 373 dev_err(&hdev->dev, "unable to request touch data (1:%d)\n",
396 ret); 374 ret);
397 goto err_free; 375 goto err_stop_hw;
398 } 376 }
399 ret = hdev->hid_output_raw_report(hdev, feature_2, 377 ret = hdev->hid_output_raw_report(hdev, feature_2,
400 sizeof(feature_2), HID_FEATURE_REPORT); 378 sizeof(feature_2), HID_FEATURE_REPORT);
401 if (ret != sizeof(feature_2)) { 379 if (ret != sizeof(feature_2)) {
402 dev_err(&hdev->dev, "unable to request touch data (2:%d)\n", 380 dev_err(&hdev->dev, "unable to request touch data (2:%d)\n",
403 ret); 381 ret);
404 goto err_free; 382 goto err_stop_hw;
405 } 383 }
406 384
407 input = input_allocate_device(); 385 input = input_allocate_device();
408 if (!input) { 386 if (!input) {
409 dev_err(&hdev->dev, "can't alloc input device\n"); 387 dev_err(&hdev->dev, "can't alloc input device\n");
410 ret = -ENOMEM; 388 ret = -ENOMEM;
411 goto err_free; 389 goto err_stop_hw;
412 } 390 }
413 magicmouse_setup_input(input, hdev); 391 magicmouse_setup_input(input, hdev);
414 392
415 ret = input_register_device(input); 393 ret = input_register_device(input);
416 if (ret) { 394 if (ret) {
417 dev_err(&hdev->dev, "input device registration failed\n"); 395 dev_err(&hdev->dev, "input device registration failed\n");
418 goto err_both; 396 goto err_input;
419 } 397 }
420 msc->input = input; 398 msc->input = input;
421 399
422 return 0; 400 return 0;
423 err_both: 401err_input:
424 input_free_device(input); 402 input_free_device(input);
425 err_free: 403err_stop_hw:
404 hid_hw_stop(hdev);
405err_free:
426 kfree(msc); 406 kfree(msc);
427 return ret; 407 return ret;
428} 408}