aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrzemo Firszt <przemo@firszt.eu>2011-11-05 07:28:22 -0400
committerJiri Kosina <jkosina@suse.cz>2011-11-13 15:32:52 -0500
commit78761ff9bc4e944e0b4e5df1e7eedcfdbb1a9a1a (patch)
tree6cc95dc9c1f34759f56382f4d546c2190155e0f6
parentf6b7efc162caed555264cd73cd00103701fddbc0 (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.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-wacom.c142
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 @@
33struct wacom_data { 34struct 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
112static 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
110static void wacom_poke(struct hid_device *hdev, u8 speed) 125static 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
309static 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
358static 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
293static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, 379static 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
314static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, 424static 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
449static const struct hid_device_id wacom_devices[] = { 576static 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};