diff options
| -rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-wacom.c | 142 |
3 files changed, 137 insertions, 7 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 848a56c0279c..76a5ce54eb2f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1544,6 +1544,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1544 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, | 1544 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, |
| 1545 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, | 1545 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, |
| 1546 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, | 1546 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, |
| 1547 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, | ||
| 1547 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, | 1548 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, |
| 1548 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, | 1549 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, |
| 1549 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, | 1550 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 06ce996b8b65..6832a4cfcf1f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -679,6 +679,7 @@ | |||
| 679 | 679 | ||
| 680 | #define USB_VENDOR_ID_WACOM 0x056a | 680 | #define USB_VENDOR_ID_WACOM 0x056a |
| 681 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 | 681 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 |
| 682 | #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD | ||
| 682 | 683 | ||
| 683 | #define USB_VENDOR_ID_WALTOP 0x172f | 684 | #define USB_VENDOR_ID_WALTOP 0x172f |
| 684 | #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032 | 685 | #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032 |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index db2322310486..f2183486a9b6 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> | 9 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> |
| 10 | * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru> | 10 | * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru> |
| 11 | * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net> | 11 | * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net> |
| 12 | * Copyright (c) 2011 Przemysław Firszt <przemo@firszt.eu> | ||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | /* | 15 | /* |
| @@ -33,6 +34,7 @@ | |||
| 33 | struct wacom_data { | 34 | struct wacom_data { |
| 34 | __u16 tool; | 35 | __u16 tool; |
| 35 | unsigned char butstate; | 36 | unsigned char butstate; |
| 37 | __u8 features; | ||
| 36 | unsigned char high_speed; | 38 | unsigned char high_speed; |
| 37 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 39 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY |
| 38 | int battery_capacity; | 40 | int battery_capacity; |
| @@ -107,6 +109,19 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
| 107 | } | 109 | } |
| 108 | #endif | 110 | #endif |
| 109 | 111 | ||
| 112 | static void wacom_set_features(struct hid_device *hdev) | ||
| 113 | { | ||
| 114 | int ret; | ||
| 115 | __u8 rep_data[2]; | ||
| 116 | |||
| 117 | /*set high speed, tablet mode*/ | ||
| 118 | rep_data[0] = 0x03; | ||
| 119 | rep_data[1] = 0x20; | ||
| 120 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
| 121 | HID_FEATURE_REPORT); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 110 | static void wacom_poke(struct hid_device *hdev, u8 speed) | 125 | static void wacom_poke(struct hid_device *hdev, u8 speed) |
| 111 | { | 126 | { |
| 112 | struct wacom_data *wdata = hid_get_drvdata(hdev); | 127 | struct wacom_data *wdata = hid_get_drvdata(hdev); |
| @@ -290,6 +305,77 @@ static int wacom_gr_parse_report(struct hid_device *hdev, | |||
| 290 | #endif | 305 | #endif |
| 291 | return 1; | 306 | return 1; |
| 292 | } | 307 | } |
| 308 | |||
| 309 | static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | ||
| 310 | struct input_dev *input, unsigned char *data) | ||
| 311 | { | ||
| 312 | __u16 x, y, pressure; | ||
| 313 | __u32 id; | ||
| 314 | |||
| 315 | switch (data[1]) { | ||
| 316 | case 0x80: /* Out of proximity report */ | ||
| 317 | wdata->tool = 0; | ||
| 318 | input_report_key(input, BTN_TOUCH, 0); | ||
| 319 | input_report_abs(input, ABS_PRESSURE, 0); | ||
| 320 | input_report_key(input, wdata->tool, 0); | ||
| 321 | input_sync(input); | ||
| 322 | break; | ||
| 323 | case 0xC2: /* Tool report */ | ||
| 324 | id = ((data[2] << 4) | (data[3] >> 4) | | ||
| 325 | ((data[7] & 0x0f) << 20) | | ||
| 326 | ((data[8] & 0xf0) << 12)) & 0xfffff; | ||
| 327 | |||
| 328 | switch (id) { | ||
| 329 | case 0x802: | ||
| 330 | wdata->tool = BTN_TOOL_PEN; | ||
| 331 | break; | ||
| 332 | case 0x80A: | ||
| 333 | wdata->tool = BTN_TOOL_RUBBER; | ||
| 334 | break; | ||
| 335 | } | ||
| 336 | break; | ||
| 337 | default: /* Position/pressure report */ | ||
| 338 | x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1); | ||
| 339 | y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01); | ||
| 340 | pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | ||
| 341 | | (data[1] & 0x01); | ||
| 342 | |||
| 343 | input_report_key(input, BTN_TOUCH, pressure > 1); | ||
| 344 | |||
| 345 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | ||
| 346 | input_report_key(input, BTN_STYLUS2, data[1] & 0x04); | ||
| 347 | input_report_key(input, wdata->tool, 1); | ||
| 348 | input_report_abs(input, ABS_X, x); | ||
| 349 | input_report_abs(input, ABS_Y, y); | ||
| 350 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
| 351 | input_sync(input); | ||
| 352 | break; | ||
| 353 | } | ||
| 354 | |||
| 355 | return; | ||
| 356 | } | ||
| 357 | |||
| 358 | static void wacom_i4_parse_report(struct hid_device *hdev, | ||
| 359 | struct wacom_data *wdata, | ||
| 360 | struct input_dev *input, unsigned char *data) | ||
| 361 | { | ||
| 362 | switch (data[0]) { | ||
| 363 | case 0x00: /* Empty report */ | ||
| 364 | break; | ||
| 365 | case 0x02: /* Pen report */ | ||
| 366 | wacom_i4_parse_pen_report(wdata, input, data); | ||
| 367 | break; | ||
| 368 | case 0x03: /* Features Report */ | ||
| 369 | wdata->features = data[2]; | ||
| 370 | break; | ||
| 371 | case 0x0C: /* Button report */ | ||
| 372 | break; | ||
| 373 | default: | ||
| 374 | hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]); | ||
| 375 | break; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 293 | static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | 379 | static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, |
| 294 | u8 *raw_data, int size) | 380 | u8 *raw_data, int size) |
| 295 | { | 381 | { |
| @@ -297,6 +383,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 297 | struct hid_input *hidinput; | 383 | struct hid_input *hidinput; |
| 298 | struct input_dev *input; | 384 | struct input_dev *input; |
| 299 | unsigned char *data = (unsigned char *) raw_data; | 385 | unsigned char *data = (unsigned char *) raw_data; |
| 386 | int i; | ||
| 300 | 387 | ||
| 301 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) | 388 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) |
| 302 | return 0; | 389 | return 0; |
| @@ -308,7 +395,30 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 308 | if (data[0] != 0x03) | 395 | if (data[0] != 0x03) |
| 309 | return 0; | 396 | return 0; |
| 310 | 397 | ||
| 311 | return wacom_gr_parse_report(hdev, wdata, input, data); | 398 | switch (hdev->product) { |
| 399 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | ||
| 400 | return wacom_gr_parse_report(hdev, wdata, input, data); | ||
| 401 | break; | ||
| 402 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
| 403 | i = 1; | ||
| 404 | |||
| 405 | switch (data[0]) { | ||
| 406 | case 0x04: | ||
| 407 | wacom_i4_parse_report(hdev, wdata, input, data + i); | ||
| 408 | i += 10; | ||
| 409 | /* fall through */ | ||
| 410 | case 0x03: | ||
| 411 | wacom_i4_parse_report(hdev, wdata, input, data + i); | ||
| 412 | i += 10; | ||
| 413 | wacom_i4_parse_report(hdev, wdata, input, data + i); | ||
| 414 | break; | ||
| 415 | default: | ||
| 416 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", | ||
| 417 | data[0], data[1], size); | ||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | return 1; | ||
| 312 | } | 422 | } |
| 313 | 423 | ||
| 314 | static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 424 | static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
| @@ -345,10 +455,19 @@ static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
| 345 | __set_bit(BTN_TOOL_RUBBER, input->keybit); | 455 | __set_bit(BTN_TOOL_RUBBER, input->keybit); |
| 346 | __set_bit(BTN_TOOL_MOUSE, input->keybit); | 456 | __set_bit(BTN_TOOL_MOUSE, input->keybit); |
| 347 | 457 | ||
| 348 | input_set_abs_params(input, ABS_X, 0, 16704, 4, 0); | 458 | switch (hdev->product) { |
| 349 | input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0); | 459 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: |
| 350 | input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0); | 460 | input_set_abs_params(input, ABS_X, 0, 16704, 4, 0); |
| 351 | input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); | 461 | input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0); |
| 462 | input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0); | ||
| 463 | input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); | ||
| 464 | break; | ||
| 465 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
| 466 | input_set_abs_params(input, ABS_X, 0, 40640, 4, 0); | ||
| 467 | input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); | ||
| 468 | input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); | ||
| 469 | break; | ||
| 470 | } | ||
| 352 | 471 | ||
| 353 | return 0; | 472 | return 0; |
| 354 | } | 473 | } |
| @@ -385,8 +504,16 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 385 | hid_warn(hdev, | 504 | hid_warn(hdev, |
| 386 | "can't create sysfs speed attribute err: %d\n", ret); | 505 | "can't create sysfs speed attribute err: %d\n", ret); |
| 387 | 506 | ||
| 388 | /* Set Wacom mode 2 with high reporting speed */ | 507 | switch (hdev->product) { |
| 389 | wacom_poke(hdev, 1); | 508 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: |
| 509 | /* Set Wacom mode 2 with high reporting speed */ | ||
| 510 | wacom_poke(hdev, 1); | ||
| 511 | break; | ||
| 512 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
| 513 | wdata->features = 0; | ||
| 514 | wacom_set_features(hdev); | ||
| 515 | break; | ||
| 516 | } | ||
| 390 | 517 | ||
| 391 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 518 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY |
| 392 | wdata->battery.properties = wacom_battery_props; | 519 | wdata->battery.properties = wacom_battery_props; |
| @@ -448,6 +575,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
| 448 | 575 | ||
| 449 | static const struct hid_device_id wacom_devices[] = { | 576 | static const struct hid_device_id wacom_devices[] = { |
| 450 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, | 577 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, |
| 578 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, | ||
| 451 | 579 | ||
| 452 | { } | 580 | { } |
| 453 | }; | 581 | }; |
