diff options
author | Przemo Firszt <przemo@firszt.eu> | 2011-11-05 07:28:22 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-11-13 15:32:52 -0500 |
commit | 78761ff9bc4e944e0b4e5df1e7eedcfdbb1a9a1a (patch) | |
tree | 6cc95dc9c1f34759f56382f4d546c2190155e0f6 | |
parent | f6b7efc162caed555264cd73cd00103701fddbc0 (diff) |
HID: wacom: Initial driver for Wacom Intuos4 Wireless (Bluetooth)
This is very basic driver for Wacom Intuos4 Wireless tablet. It supports only
position, pressure and pen buttons. More features will be added in the future.
Signed-off-by: Przemo Firszt <przemo@firszt.eu>
Acked-by: Ping Cheng <pinglinux@gmail.com>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-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 848a56c0279..76a5ce54eb2 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 06ce996b8b6..6832a4cfcf1 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 db232231048..f2183486a9b 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 | }; |