aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wacom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-wacom.c')
-rw-r--r--drivers/hid/hid-wacom.c95
1 files changed, 84 insertions, 11 deletions
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index acab74cde727..067e2963314c 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -31,10 +31,15 @@
31 31
32#include "hid-ids.h" 32#include "hid-ids.h"
33 33
34#define PAD_DEVICE_ID 0x0F
35
34struct wacom_data { 36struct wacom_data {
35 __u16 tool; 37 __u16 tool;
36 unsigned char butstate; 38 __u16 butstate;
39 __u8 whlstate;
37 __u8 features; 40 __u8 features;
41 __u32 id;
42 __u32 serial;
38 unsigned char high_speed; 43 unsigned char high_speed;
39#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 44#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
40 int battery_capacity; 45 int battery_capacity;
@@ -314,30 +319,82 @@ static int wacom_gr_parse_report(struct hid_device *hdev,
314 return 1; 319 return 1;
315} 320}
316 321
322static void wacom_i4_parse_button_report(struct wacom_data *wdata,
323 struct input_dev *input, unsigned char *data)
324{
325 __u16 new_butstate;
326 __u8 new_whlstate;
327 __u8 sync = 0;
328
329 new_whlstate = data[1];
330 if (new_whlstate != wdata->whlstate) {
331 wdata->whlstate = new_whlstate;
332 if (new_whlstate & 0x80) {
333 input_report_key(input, BTN_TOUCH, 1);
334 input_report_abs(input, ABS_WHEEL, (new_whlstate & 0x7f));
335 input_report_key(input, BTN_TOOL_FINGER, 1);
336 } else {
337 input_report_key(input, BTN_TOUCH, 0);
338 input_report_abs(input, ABS_WHEEL, 0);
339 input_report_key(input, BTN_TOOL_FINGER, 0);
340 }
341 sync = 1;
342 }
343
344 new_butstate = (data[3] << 1) | (data[2] & 0x01);
345 if (new_butstate != wdata->butstate) {
346 wdata->butstate = new_butstate;
347 input_report_key(input, BTN_0, new_butstate & 0x001);
348 input_report_key(input, BTN_1, new_butstate & 0x002);
349 input_report_key(input, BTN_2, new_butstate & 0x004);
350 input_report_key(input, BTN_3, new_butstate & 0x008);
351 input_report_key(input, BTN_4, new_butstate & 0x010);
352 input_report_key(input, BTN_5, new_butstate & 0x020);
353 input_report_key(input, BTN_6, new_butstate & 0x040);
354 input_report_key(input, BTN_7, new_butstate & 0x080);
355 input_report_key(input, BTN_8, new_butstate & 0x100);
356 input_report_key(input, BTN_TOOL_FINGER, 1);
357 sync = 1;
358 }
359
360 if (sync) {
361 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
362 input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
363 input_sync(input);
364 }
365}
366
317static void wacom_i4_parse_pen_report(struct wacom_data *wdata, 367static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
318 struct input_dev *input, unsigned char *data) 368 struct input_dev *input, unsigned char *data)
319{ 369{
320 __u16 x, y, pressure; 370 __u16 x, y, pressure;
321 __u32 id; 371 __u8 distance;
322 372
323 switch (data[1]) { 373 switch (data[1]) {
324 case 0x80: /* Out of proximity report */ 374 case 0x80: /* Out of proximity report */
325 wdata->tool = 0;
326 input_report_key(input, BTN_TOUCH, 0); 375 input_report_key(input, BTN_TOUCH, 0);
327 input_report_abs(input, ABS_PRESSURE, 0); 376 input_report_abs(input, ABS_PRESSURE, 0);
377 input_report_key(input, BTN_STYLUS, 0);
378 input_report_key(input, BTN_STYLUS2, 0);
328 input_report_key(input, wdata->tool, 0); 379 input_report_key(input, wdata->tool, 0);
380 input_report_abs(input, ABS_MISC, 0);
381 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
382 wdata->tool = 0;
329 input_sync(input); 383 input_sync(input);
330 break; 384 break;
331 case 0xC2: /* Tool report */ 385 case 0xC2: /* Tool report */
332 id = ((data[2] << 4) | (data[3] >> 4) | 386 wdata->id = ((data[2] << 4) | (data[3] >> 4) |
333 ((data[7] & 0x0f) << 20) | 387 ((data[7] & 0x0f) << 20) |
334 ((data[8] & 0xf0) << 12)) & 0xfffff; 388 ((data[8] & 0xf0) << 12));
389 wdata->serial = ((data[3] & 0x0f) << 28) +
390 (data[4] << 20) + (data[5] << 12) +
391 (data[6] << 4) + (data[7] >> 4);
335 392
336 switch (id) { 393 switch (wdata->id) {
337 case 0x802: 394 case 0x100802:
338 wdata->tool = BTN_TOOL_PEN; 395 wdata->tool = BTN_TOOL_PEN;
339 break; 396 break;
340 case 0x80A: 397 case 0x10080A:
341 wdata->tool = BTN_TOOL_RUBBER; 398 wdata->tool = BTN_TOOL_RUBBER;
342 break; 399 break;
343 } 400 }
@@ -347,6 +404,7 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
347 y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01); 404 y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
348 pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) 405 pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
349 | (data[1] & 0x01); 406 | (data[1] & 0x01);
407 distance = (data[9] >> 2) & 0x3f;
350 408
351 input_report_key(input, BTN_TOUCH, pressure > 1); 409 input_report_key(input, BTN_TOUCH, pressure > 1);
352 410
@@ -356,6 +414,10 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
356 input_report_abs(input, ABS_X, x); 414 input_report_abs(input, ABS_X, x);
357 input_report_abs(input, ABS_Y, y); 415 input_report_abs(input, ABS_Y, y);
358 input_report_abs(input, ABS_PRESSURE, pressure); 416 input_report_abs(input, ABS_PRESSURE, pressure);
417 input_report_abs(input, ABS_DISTANCE, distance);
418 input_report_abs(input, ABS_MISC, wdata->id);
419 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
420 input_report_key(input, wdata->tool, 1);
359 input_sync(input); 421 input_sync(input);
360 break; 422 break;
361 } 423 }
@@ -377,6 +439,7 @@ static void wacom_i4_parse_report(struct hid_device *hdev,
377 wdata->features = data[2]; 439 wdata->features = data[2];
378 break; 440 break;
379 case 0x0C: /* Button report */ 441 case 0x0C: /* Button report */
442 wacom_i4_parse_button_report(wdata, input, data);
380 break; 443 break;
381 default: 444 default:
382 hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]); 445 hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]);
@@ -451,9 +514,7 @@ static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
451 __set_bit(BTN_MIDDLE, input->keybit); 514 __set_bit(BTN_MIDDLE, input->keybit);
452 515
453 /* Pad */ 516 /* Pad */
454 input->evbit[0] |= BIT(EV_MSC); 517 input_set_capability(input, EV_MSC, MSC_SERIAL);
455
456 __set_bit(MSC_SERIAL, input->mscbit);
457 518
458 __set_bit(BTN_0, input->keybit); 519 __set_bit(BTN_0, input->keybit);
459 __set_bit(BTN_1, input->keybit); 520 __set_bit(BTN_1, input->keybit);
@@ -471,9 +532,20 @@ static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
471 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); 532 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
472 break; 533 break;
473 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: 534 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
535 __set_bit(ABS_WHEEL, input->absbit);
536 __set_bit(ABS_MISC, input->absbit);
537 __set_bit(BTN_2, input->keybit);
538 __set_bit(BTN_3, input->keybit);
539 __set_bit(BTN_4, input->keybit);
540 __set_bit(BTN_5, input->keybit);
541 __set_bit(BTN_6, input->keybit);
542 __set_bit(BTN_7, input->keybit);
543 __set_bit(BTN_8, input->keybit);
544 input_set_abs_params(input, ABS_WHEEL, 0, 71, 0, 0);
474 input_set_abs_params(input, ABS_X, 0, 40640, 4, 0); 545 input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
475 input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); 546 input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
476 input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); 547 input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
548 input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0);
477 break; 549 break;
478 } 550 }
479 551
@@ -518,6 +590,7 @@ static int wacom_probe(struct hid_device *hdev,
518 wacom_poke(hdev, 1); 590 wacom_poke(hdev, 1);
519 break; 591 break;
520 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: 592 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
593 sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
521 wdata->features = 0; 594 wdata->features = 0;
522 wacom_set_features(hdev); 595 wacom_set_features(hdev);
523 break; 596 break;