diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-magicmouse.c | 100 |
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 | ||
21 | static bool emulate_3button = 1; | 21 | static bool emulate_3button = true; |
22 | module_param(emulate_3button, bool, 0644); | 22 | module_param(emulate_3button, bool, 0644); |
23 | MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); | 23 | MODULE_PARM_DESC(emulate_3button, "Emulate a middle button"); |
24 | 24 | ||
25 | static int middle_button_start = -350; | 25 | static int middle_button_start = -350; |
26 | static int middle_button_stop = +350; | 26 | static int middle_button_stop = +350; |
27 | 27 | ||
28 | static bool emulate_scroll_wheel = 1; | 28 | static bool emulate_scroll_wheel = true; |
29 | module_param(emulate_scroll_wheel, bool, 0644); | 29 | module_param(emulate_scroll_wheel, bool, 0644); |
30 | MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); | 30 | MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); |
31 | 31 | ||
32 | static bool report_touches = 1; | 32 | static bool report_touches = true; |
33 | module_param(report_touches, bool, 0644); | 33 | module_param(report_touches, bool, 0644); |
34 | MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); | 34 | MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); |
35 | 35 | ||
36 | static bool report_undeciphered = 0; | 36 | static bool report_undeciphered; |
37 | module_param(report_undeciphered, bool, 0644); | 37 | module_param(report_undeciphered, bool, 0644); |
38 | MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); | 38 | MODULE_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 | ||
109 | static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) | 109 | static 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: | 401 | err_input: |
424 | input_free_device(input); | 402 | input_free_device(input); |
425 | err_free: | 403 | err_stop_hw: |
404 | hid_hw_stop(hdev); | ||
405 | err_free: | ||
426 | kfree(msc); | 406 | kfree(msc); |
427 | return ret; | 407 | return ret; |
428 | } | 408 | } |