Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc2 959 lines 25 kB view raw
1/* 2 * Bluetooth Wacom Tablet support 3 * 4 * Copyright (c) 1999 Andreas Gal 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7 * Copyright (c) 2006-2007 Jiri Kosina 8 * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> 9 * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru> 10 * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net> 11 * Copyright (c) 2011 Przemysław Firszt <przemo@firszt.eu> 12 */ 13 14/* 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the Free 17 * Software Foundation; either version 2 of the License, or (at your option) 18 * any later version. 19 */ 20 21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 23#include <linux/device.h> 24#include <linux/hid.h> 25#include <linux/module.h> 26#include <linux/leds.h> 27#include <linux/slab.h> 28#include <linux/power_supply.h> 29 30#include "hid-ids.h" 31 32#define PAD_DEVICE_ID 0x0F 33 34#define WAC_CMD_LED_CONTROL 0x20 35#define WAC_CMD_ICON_START_STOP 0x21 36#define WAC_CMD_ICON_TRANSFER 0x26 37 38struct wacom_data { 39 __u16 tool; 40 __u16 butstate; 41 __u8 whlstate; 42 __u8 features; 43 __u32 id; 44 __u32 serial; 45 unsigned char high_speed; 46 __u8 battery_capacity; 47 __u8 power_raw; 48 __u8 ps_connected; 49 struct power_supply battery; 50 struct power_supply ac; 51 __u8 led_selector; 52 struct led_classdev *leds[4]; 53}; 54 55/*percent of battery capacity for Graphire 56 8th value means AC online and show 100% capacity */ 57static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; 58/*percent of battery capacity for Intuos4 WL, AC has a separate bit*/ 59static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; 60 61static enum power_supply_property wacom_battery_props[] = { 62 POWER_SUPPLY_PROP_PRESENT, 63 POWER_SUPPLY_PROP_CAPACITY, 64 POWER_SUPPLY_PROP_SCOPE, 65}; 66 67static enum power_supply_property wacom_ac_props[] = { 68 POWER_SUPPLY_PROP_PRESENT, 69 POWER_SUPPLY_PROP_ONLINE, 70 POWER_SUPPLY_PROP_SCOPE, 71}; 72 73static void wacom_scramble(__u8 *image) 74{ 75 __u16 mask; 76 __u16 s1; 77 __u16 s2; 78 __u16 r1 ; 79 __u16 r2 ; 80 __u16 r; 81 __u8 buf[256]; 82 int i, w, x, y, z; 83 84 for (x = 0; x < 32; x++) { 85 for (y = 0; y < 8; y++) 86 buf[(8 * x) + (7 - y)] = image[(8 * x) + y]; 87 } 88 89 /* Change 76543210 into GECA6420 as required by Intuos4 WL 90 * HGFEDCBA HFDB7531 91 */ 92 for (x = 0; x < 4; x++) { 93 for (y = 0; y < 4; y++) { 94 for (z = 0; z < 8; z++) { 95 mask = 0x0001; 96 r1 = 0; 97 r2 = 0; 98 i = (x << 6) + (y << 4) + z; 99 s1 = buf[i]; 100 s2 = buf[i+8]; 101 for (w = 0; w < 8; w++) { 102 r1 |= (s1 & mask); 103 r2 |= (s2 & mask); 104 s1 <<= 1; 105 s2 <<= 1; 106 mask <<= 2; 107 } 108 r = r1 | (r2 << 1); 109 i = (x << 6) + (y << 4) + (z << 1); 110 image[i] = 0xFF & r; 111 image[i+1] = (0xFF00 & r) >> 8; 112 } 113 } 114 } 115} 116 117static void wacom_set_image(struct hid_device *hdev, const char *image, 118 __u8 icon_no) 119{ 120 __u8 rep_data[68]; 121 __u8 p[256]; 122 int ret, i, j; 123 124 for (i = 0; i < 256; i++) 125 p[i] = image[i]; 126 127 rep_data[0] = WAC_CMD_ICON_START_STOP; 128 rep_data[1] = 0; 129 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 130 HID_FEATURE_REPORT); 131 if (ret < 0) 132 goto err; 133 134 rep_data[0] = WAC_CMD_ICON_TRANSFER; 135 rep_data[1] = icon_no & 0x07; 136 137 wacom_scramble(p); 138 139 for (i = 0; i < 4; i++) { 140 for (j = 0; j < 64; j++) 141 rep_data[j + 3] = p[(i << 6) + j]; 142 143 rep_data[2] = i; 144 ret = hdev->hid_output_raw_report(hdev, rep_data, 67, 145 HID_FEATURE_REPORT); 146 } 147 148 rep_data[0] = WAC_CMD_ICON_START_STOP; 149 rep_data[1] = 0; 150 151 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 152 HID_FEATURE_REPORT); 153 154err: 155 return; 156} 157 158static void wacom_leds_set_brightness(struct led_classdev *led_dev, 159 enum led_brightness value) 160{ 161 struct device *dev = led_dev->dev->parent; 162 struct hid_device *hdev; 163 struct wacom_data *wdata; 164 unsigned char *buf; 165 __u8 led = 0; 166 int i; 167 168 hdev = container_of(dev, struct hid_device, dev); 169 wdata = hid_get_drvdata(hdev); 170 for (i = 0; i < 4; ++i) { 171 if (wdata->leds[i] == led_dev) 172 wdata->led_selector = i; 173 } 174 175 led = wdata->led_selector | 0x04; 176 buf = kzalloc(9, GFP_KERNEL); 177 if (buf) { 178 buf[0] = WAC_CMD_LED_CONTROL; 179 buf[1] = led; 180 buf[2] = value >> 2; 181 buf[3] = value; 182 /* use fixed brightness for OLEDs */ 183 buf[4] = 0x08; 184 hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT); 185 kfree(buf); 186 } 187 188 return; 189} 190 191static enum led_brightness wacom_leds_get_brightness(struct led_classdev *led_dev) 192{ 193 struct wacom_data *wdata; 194 struct device *dev = led_dev->dev->parent; 195 int value = 0; 196 int i; 197 198 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); 199 200 for (i = 0; i < 4; ++i) { 201 if (wdata->leds[i] == led_dev) { 202 value = wdata->leds[i]->brightness; 203 break; 204 } 205 } 206 207 return value; 208} 209 210 211static int wacom_initialize_leds(struct hid_device *hdev) 212{ 213 struct wacom_data *wdata = hid_get_drvdata(hdev); 214 struct led_classdev *led; 215 struct device *dev = &hdev->dev; 216 size_t namesz = strlen(dev_name(dev)) + 12; 217 char *name; 218 int i, ret; 219 220 wdata->led_selector = 0; 221 222 for (i = 0; i < 4; i++) { 223 led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL); 224 if (!led) { 225 hid_warn(hdev, 226 "can't allocate memory for LED selector\n"); 227 ret = -ENOMEM; 228 goto err; 229 } 230 231 name = (void *)&led[1]; 232 snprintf(name, namesz, "%s:selector:%d", dev_name(dev), i); 233 led->name = name; 234 led->brightness = 0; 235 led->max_brightness = 127; 236 led->brightness_get = wacom_leds_get_brightness; 237 led->brightness_set = wacom_leds_set_brightness; 238 239 wdata->leds[i] = led; 240 241 ret = led_classdev_register(dev, wdata->leds[i]); 242 243 if (ret) { 244 wdata->leds[i] = NULL; 245 kfree(led); 246 hid_warn(hdev, "can't register LED\n"); 247 goto err; 248 } 249 } 250 251err: 252 return ret; 253} 254 255static void wacom_destroy_leds(struct hid_device *hdev) 256{ 257 struct wacom_data *wdata = hid_get_drvdata(hdev); 258 struct led_classdev *led; 259 int i; 260 261 for (i = 0; i < 4; ++i) { 262 if (wdata->leds[i]) { 263 led = wdata->leds[i]; 264 wdata->leds[i] = NULL; 265 led_classdev_unregister(led); 266 kfree(led); 267 } 268 } 269 270} 271 272static int wacom_battery_get_property(struct power_supply *psy, 273 enum power_supply_property psp, 274 union power_supply_propval *val) 275{ 276 struct wacom_data *wdata = container_of(psy, 277 struct wacom_data, battery); 278 int ret = 0; 279 280 switch (psp) { 281 case POWER_SUPPLY_PROP_PRESENT: 282 val->intval = 1; 283 break; 284 case POWER_SUPPLY_PROP_SCOPE: 285 val->intval = POWER_SUPPLY_SCOPE_DEVICE; 286 break; 287 case POWER_SUPPLY_PROP_CAPACITY: 288 val->intval = wdata->battery_capacity; 289 break; 290 default: 291 ret = -EINVAL; 292 break; 293 } 294 return ret; 295} 296 297static int wacom_ac_get_property(struct power_supply *psy, 298 enum power_supply_property psp, 299 union power_supply_propval *val) 300{ 301 struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); 302 int ret = 0; 303 304 switch (psp) { 305 case POWER_SUPPLY_PROP_PRESENT: 306 /* fall through */ 307 case POWER_SUPPLY_PROP_ONLINE: 308 val->intval = wdata->ps_connected; 309 break; 310 case POWER_SUPPLY_PROP_SCOPE: 311 val->intval = POWER_SUPPLY_SCOPE_DEVICE; 312 break; 313 default: 314 ret = -EINVAL; 315 break; 316 } 317 return ret; 318} 319 320static void wacom_set_features(struct hid_device *hdev, u8 speed) 321{ 322 struct wacom_data *wdata = hid_get_drvdata(hdev); 323 int limit, ret; 324 __u8 rep_data[2]; 325 326 switch (hdev->product) { 327 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: 328 rep_data[0] = 0x03 ; rep_data[1] = 0x00; 329 limit = 3; 330 do { 331 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 332 HID_FEATURE_REPORT); 333 } while (ret < 0 && limit-- > 0); 334 335 if (ret >= 0) { 336 if (speed == 0) 337 rep_data[0] = 0x05; 338 else 339 rep_data[0] = 0x06; 340 341 rep_data[1] = 0x00; 342 limit = 3; 343 do { 344 ret = hdev->hid_output_raw_report(hdev, 345 rep_data, 2, HID_FEATURE_REPORT); 346 } while (ret < 0 && limit-- > 0); 347 348 if (ret >= 0) { 349 wdata->high_speed = speed; 350 return; 351 } 352 } 353 354 /* 355 * Note that if the raw queries fail, it's not a hard failure 356 * and it is safe to continue 357 */ 358 hid_warn(hdev, "failed to poke device, command %d, err %d\n", 359 rep_data[0], ret); 360 break; 361 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: 362 if (speed == 1) 363 wdata->features &= ~0x20; 364 else 365 wdata->features |= 0x20; 366 367 rep_data[0] = 0x03; 368 rep_data[1] = wdata->features; 369 370 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 371 HID_FEATURE_REPORT); 372 if (ret >= 0) 373 wdata->high_speed = speed; 374 break; 375 } 376 377 return; 378} 379 380static ssize_t wacom_show_speed(struct device *dev, 381 struct device_attribute 382 *attr, char *buf) 383{ 384 struct wacom_data *wdata = dev_get_drvdata(dev); 385 386 return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed); 387} 388 389static ssize_t wacom_store_speed(struct device *dev, 390 struct device_attribute *attr, 391 const char *buf, size_t count) 392{ 393 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 394 int new_speed; 395 396 if (sscanf(buf, "%1d", &new_speed ) != 1) 397 return -EINVAL; 398 399 if (new_speed == 0 || new_speed == 1) { 400 wacom_set_features(hdev, new_speed); 401 return strnlen(buf, PAGE_SIZE); 402 } else 403 return -EINVAL; 404} 405 406static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP, 407 wacom_show_speed, wacom_store_speed); 408 409#define WACOM_STORE(OLED_ID) \ 410static ssize_t wacom_oled##OLED_ID##_store(struct device *dev, \ 411 struct device_attribute *attr, \ 412 const char *buf, size_t count) \ 413{ \ 414 struct hid_device *hdev = container_of(dev, struct hid_device, \ 415 dev); \ 416 \ 417 if (count != 256) \ 418 return -EINVAL; \ 419 \ 420 wacom_set_image(hdev, buf, OLED_ID); \ 421 \ 422 return count; \ 423} \ 424 \ 425static DEVICE_ATTR(oled##OLED_ID##_img, S_IWUSR | S_IWGRP, NULL, \ 426 wacom_oled##OLED_ID##_store) 427 428WACOM_STORE(0); 429WACOM_STORE(1); 430WACOM_STORE(2); 431WACOM_STORE(3); 432WACOM_STORE(4); 433WACOM_STORE(5); 434WACOM_STORE(6); 435WACOM_STORE(7); 436 437static int wacom_gr_parse_report(struct hid_device *hdev, 438 struct wacom_data *wdata, 439 struct input_dev *input, unsigned char *data) 440{ 441 int tool, x, y, rw; 442 443 tool = 0; 444 /* Get X & Y positions */ 445 x = le16_to_cpu(*(__le16 *) &data[2]); 446 y = le16_to_cpu(*(__le16 *) &data[4]); 447 448 /* Get current tool identifier */ 449 if (data[1] & 0x90) { /* If pen is in the in/active area */ 450 switch ((data[1] >> 5) & 3) { 451 case 0: /* Pen */ 452 tool = BTN_TOOL_PEN; 453 break; 454 455 case 1: /* Rubber */ 456 tool = BTN_TOOL_RUBBER; 457 break; 458 459 case 2: /* Mouse with wheel */ 460 case 3: /* Mouse without wheel */ 461 tool = BTN_TOOL_MOUSE; 462 break; 463 } 464 465 /* Reset tool if out of active tablet area */ 466 if (!(data[1] & 0x10)) 467 tool = 0; 468 } 469 470 /* If tool changed, notify input subsystem */ 471 if (wdata->tool != tool) { 472 if (wdata->tool) { 473 /* Completely reset old tool state */ 474 if (wdata->tool == BTN_TOOL_MOUSE) { 475 input_report_key(input, BTN_LEFT, 0); 476 input_report_key(input, BTN_RIGHT, 0); 477 input_report_key(input, BTN_MIDDLE, 0); 478 input_report_abs(input, ABS_DISTANCE, 479 input_abs_get_max(input, ABS_DISTANCE)); 480 } else { 481 input_report_key(input, BTN_TOUCH, 0); 482 input_report_key(input, BTN_STYLUS, 0); 483 input_report_key(input, BTN_STYLUS2, 0); 484 input_report_abs(input, ABS_PRESSURE, 0); 485 } 486 input_report_key(input, wdata->tool, 0); 487 input_sync(input); 488 } 489 wdata->tool = tool; 490 if (tool) 491 input_report_key(input, tool, 1); 492 } 493 494 if (tool) { 495 input_report_abs(input, ABS_X, x); 496 input_report_abs(input, ABS_Y, y); 497 498 switch ((data[1] >> 5) & 3) { 499 case 2: /* Mouse with wheel */ 500 input_report_key(input, BTN_MIDDLE, data[1] & 0x04); 501 rw = (data[6] & 0x01) ? -1 : 502 (data[6] & 0x02) ? 1 : 0; 503 input_report_rel(input, REL_WHEEL, rw); 504 /* fall through */ 505 506 case 3: /* Mouse without wheel */ 507 input_report_key(input, BTN_LEFT, data[1] & 0x01); 508 input_report_key(input, BTN_RIGHT, data[1] & 0x02); 509 /* Compute distance between mouse and tablet */ 510 rw = 44 - (data[6] >> 2); 511 if (rw < 0) 512 rw = 0; 513 else if (rw > 31) 514 rw = 31; 515 input_report_abs(input, ABS_DISTANCE, rw); 516 break; 517 518 default: 519 input_report_abs(input, ABS_PRESSURE, 520 data[6] | (((__u16) (data[1] & 0x08)) << 5)); 521 input_report_key(input, BTN_TOUCH, data[1] & 0x01); 522 input_report_key(input, BTN_STYLUS, data[1] & 0x02); 523 input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04); 524 break; 525 } 526 527 input_sync(input); 528 } 529 530 /* Report the state of the two buttons at the top of the tablet 531 * as two extra fingerpad keys (buttons 4 & 5). */ 532 rw = data[7] & 0x03; 533 if (rw != wdata->butstate) { 534 wdata->butstate = rw; 535 input_report_key(input, BTN_0, rw & 0x02); 536 input_report_key(input, BTN_1, rw & 0x01); 537 input_report_key(input, BTN_TOOL_FINGER, 0xf0); 538 input_event(input, EV_MSC, MSC_SERIAL, 0xf0); 539 input_sync(input); 540 } 541 542 /* Store current battery capacity and power supply state*/ 543 rw = (data[7] >> 2 & 0x07); 544 if (rw != wdata->power_raw) { 545 wdata->power_raw = rw; 546 wdata->battery_capacity = batcap_gr[rw]; 547 if (rw == 7) 548 wdata->ps_connected = 1; 549 else 550 wdata->ps_connected = 0; 551 } 552 return 1; 553} 554 555static void wacom_i4_parse_button_report(struct wacom_data *wdata, 556 struct input_dev *input, unsigned char *data) 557{ 558 __u16 new_butstate; 559 __u8 new_whlstate; 560 __u8 sync = 0; 561 562 new_whlstate = data[1]; 563 if (new_whlstate != wdata->whlstate) { 564 wdata->whlstate = new_whlstate; 565 if (new_whlstate & 0x80) { 566 input_report_key(input, BTN_TOUCH, 1); 567 input_report_abs(input, ABS_WHEEL, (new_whlstate & 0x7f)); 568 input_report_key(input, BTN_TOOL_FINGER, 1); 569 } else { 570 input_report_key(input, BTN_TOUCH, 0); 571 input_report_abs(input, ABS_WHEEL, 0); 572 input_report_key(input, BTN_TOOL_FINGER, 0); 573 } 574 sync = 1; 575 } 576 577 new_butstate = (data[3] << 1) | (data[2] & 0x01); 578 if (new_butstate != wdata->butstate) { 579 wdata->butstate = new_butstate; 580 input_report_key(input, BTN_0, new_butstate & 0x001); 581 input_report_key(input, BTN_1, new_butstate & 0x002); 582 input_report_key(input, BTN_2, new_butstate & 0x004); 583 input_report_key(input, BTN_3, new_butstate & 0x008); 584 input_report_key(input, BTN_4, new_butstate & 0x010); 585 input_report_key(input, BTN_5, new_butstate & 0x020); 586 input_report_key(input, BTN_6, new_butstate & 0x040); 587 input_report_key(input, BTN_7, new_butstate & 0x080); 588 input_report_key(input, BTN_8, new_butstate & 0x100); 589 input_report_key(input, BTN_TOOL_FINGER, 1); 590 sync = 1; 591 } 592 593 if (sync) { 594 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); 595 input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff); 596 input_sync(input); 597 } 598} 599 600static void wacom_i4_parse_pen_report(struct wacom_data *wdata, 601 struct input_dev *input, unsigned char *data) 602{ 603 __u16 x, y, pressure; 604 __u8 distance; 605 __u8 tilt_x, tilt_y; 606 607 switch (data[1]) { 608 case 0x80: /* Out of proximity report */ 609 input_report_key(input, BTN_TOUCH, 0); 610 input_report_abs(input, ABS_PRESSURE, 0); 611 input_report_key(input, BTN_STYLUS, 0); 612 input_report_key(input, BTN_STYLUS2, 0); 613 input_report_key(input, wdata->tool, 0); 614 input_report_abs(input, ABS_MISC, 0); 615 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); 616 wdata->tool = 0; 617 input_sync(input); 618 break; 619 case 0xC2: /* Tool report */ 620 wdata->id = ((data[2] << 4) | (data[3] >> 4) | 621 ((data[7] & 0x0f) << 20) | 622 ((data[8] & 0xf0) << 12)); 623 wdata->serial = ((data[3] & 0x0f) << 28) + 624 (data[4] << 20) + (data[5] << 12) + 625 (data[6] << 4) + (data[7] >> 4); 626 627 switch (wdata->id) { 628 case 0x100802: 629 wdata->tool = BTN_TOOL_PEN; 630 break; 631 case 0x10080A: 632 wdata->tool = BTN_TOOL_RUBBER; 633 break; 634 } 635 break; 636 default: /* Position/pressure report */ 637 x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1); 638 y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01); 639 pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) 640 | (data[1] & 0x01); 641 distance = (data[9] >> 2) & 0x3f; 642 tilt_x = ((data[7] << 1) & 0x7e) | (data[8] >> 7); 643 tilt_y = data[8] & 0x7f; 644 645 input_report_key(input, BTN_TOUCH, pressure > 1); 646 647 input_report_key(input, BTN_STYLUS, data[1] & 0x02); 648 input_report_key(input, BTN_STYLUS2, data[1] & 0x04); 649 input_report_key(input, wdata->tool, 1); 650 input_report_abs(input, ABS_X, x); 651 input_report_abs(input, ABS_Y, y); 652 input_report_abs(input, ABS_PRESSURE, pressure); 653 input_report_abs(input, ABS_DISTANCE, distance); 654 input_report_abs(input, ABS_TILT_X, tilt_x); 655 input_report_abs(input, ABS_TILT_Y, tilt_y); 656 input_report_abs(input, ABS_MISC, wdata->id); 657 input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); 658 input_report_key(input, wdata->tool, 1); 659 input_sync(input); 660 break; 661 } 662 663 return; 664} 665 666static void wacom_i4_parse_report(struct hid_device *hdev, 667 struct wacom_data *wdata, 668 struct input_dev *input, unsigned char *data) 669{ 670 switch (data[0]) { 671 case 0x00: /* Empty report */ 672 break; 673 case 0x02: /* Pen report */ 674 wacom_i4_parse_pen_report(wdata, input, data); 675 break; 676 case 0x03: /* Features Report */ 677 wdata->features = data[2]; 678 break; 679 case 0x0C: /* Button report */ 680 wacom_i4_parse_button_report(wdata, input, data); 681 break; 682 default: 683 hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]); 684 break; 685 } 686} 687 688static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, 689 u8 *raw_data, int size) 690{ 691 struct wacom_data *wdata = hid_get_drvdata(hdev); 692 struct hid_input *hidinput; 693 struct input_dev *input; 694 unsigned char *data = (unsigned char *) raw_data; 695 int i; 696 __u8 power_raw; 697 698 if (!(hdev->claimed & HID_CLAIMED_INPUT)) 699 return 0; 700 701 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 702 input = hidinput->input; 703 704 switch (hdev->product) { 705 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: 706 if (data[0] == 0x03) { 707 return wacom_gr_parse_report(hdev, wdata, input, data); 708 } else { 709 hid_err(hdev, "Unknown report: %d,%d size:%d\n", 710 data[0], data[1], size); 711 return 0; 712 } 713 break; 714 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: 715 i = 1; 716 717 switch (data[0]) { 718 case 0x04: 719 wacom_i4_parse_report(hdev, wdata, input, data + i); 720 i += 10; 721 /* fall through */ 722 case 0x03: 723 wacom_i4_parse_report(hdev, wdata, input, data + i); 724 i += 10; 725 wacom_i4_parse_report(hdev, wdata, input, data + i); 726 power_raw = data[i+10]; 727 if (power_raw != wdata->power_raw) { 728 wdata->power_raw = power_raw; 729 wdata->battery_capacity = batcap_i4[power_raw & 0x07]; 730 wdata->ps_connected = power_raw & 0x08; 731 } 732 733 break; 734 default: 735 hid_err(hdev, "Unknown report: %d,%d size:%d\n", 736 data[0], data[1], size); 737 return 0; 738 } 739 } 740 return 1; 741} 742 743static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, 744 struct hid_field *field, struct hid_usage *usage, unsigned long **bit, 745 int *max) 746{ 747 struct input_dev *input = hi->input; 748 749 __set_bit(INPUT_PROP_POINTER, input->propbit); 750 751 /* Basics */ 752 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); 753 754 __set_bit(REL_WHEEL, input->relbit); 755 756 __set_bit(BTN_TOOL_PEN, input->keybit); 757 __set_bit(BTN_TOUCH, input->keybit); 758 __set_bit(BTN_STYLUS, input->keybit); 759 __set_bit(BTN_STYLUS2, input->keybit); 760 __set_bit(BTN_LEFT, input->keybit); 761 __set_bit(BTN_RIGHT, input->keybit); 762 __set_bit(BTN_MIDDLE, input->keybit); 763 764 /* Pad */ 765 input_set_capability(input, EV_MSC, MSC_SERIAL); 766 767 __set_bit(BTN_0, input->keybit); 768 __set_bit(BTN_1, input->keybit); 769 __set_bit(BTN_TOOL_FINGER, input->keybit); 770 771 /* Distance, rubber and mouse */ 772 __set_bit(BTN_TOOL_RUBBER, input->keybit); 773 __set_bit(BTN_TOOL_MOUSE, input->keybit); 774 775 switch (hdev->product) { 776 case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: 777 input_set_abs_params(input, ABS_X, 0, 16704, 4, 0); 778 input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0); 779 input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0); 780 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); 781 break; 782 case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: 783 __set_bit(ABS_WHEEL, input->absbit); 784 __set_bit(ABS_MISC, input->absbit); 785 __set_bit(BTN_2, input->keybit); 786 __set_bit(BTN_3, input->keybit); 787 __set_bit(BTN_4, input->keybit); 788 __set_bit(BTN_5, input->keybit); 789 __set_bit(BTN_6, input->keybit); 790 __set_bit(BTN_7, input->keybit); 791 __set_bit(BTN_8, input->keybit); 792 input_set_abs_params(input, ABS_WHEEL, 0, 71, 0, 0); 793 input_set_abs_params(input, ABS_X, 0, 40640, 4, 0); 794 input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); 795 input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); 796 input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0); 797 input_set_abs_params(input, ABS_TILT_X, 0, 127, 0, 0); 798 input_set_abs_params(input, ABS_TILT_Y, 0, 127, 0, 0); 799 break; 800 } 801 802 return 0; 803} 804 805static int wacom_probe(struct hid_device *hdev, 806 const struct hid_device_id *id) 807{ 808 struct wacom_data *wdata; 809 int ret; 810 811 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); 812 if (wdata == NULL) { 813 hid_err(hdev, "can't alloc wacom descriptor\n"); 814 return -ENOMEM; 815 } 816 817 hid_set_drvdata(hdev, wdata); 818 819 /* Parse the HID report now */ 820 ret = hid_parse(hdev); 821 if (ret) { 822 hid_err(hdev, "parse failed\n"); 823 goto err_free; 824 } 825 826 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 827 if (ret) { 828 hid_err(hdev, "hw start failed\n"); 829 goto err_free; 830 } 831 832 ret = device_create_file(&hdev->dev, &dev_attr_speed); 833 if (ret) 834 hid_warn(hdev, 835 "can't create sysfs speed attribute err: %d\n", ret); 836 837#define OLED_INIT(OLED_ID) \ 838 do { \ 839 ret = device_create_file(&hdev->dev, \ 840 &dev_attr_oled##OLED_ID##_img); \ 841 if (ret) \ 842 hid_warn(hdev, \ 843 "can't create sysfs oled attribute, err: %d\n", ret);\ 844 } while (0) 845 846OLED_INIT(0); 847OLED_INIT(1); 848OLED_INIT(2); 849OLED_INIT(3); 850OLED_INIT(4); 851OLED_INIT(5); 852OLED_INIT(6); 853OLED_INIT(7); 854 855 wdata->features = 0; 856 wacom_set_features(hdev, 1); 857 858 if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) { 859 sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); 860 ret = wacom_initialize_leds(hdev); 861 if (ret) 862 hid_warn(hdev, 863 "can't create led attribute, err: %d\n", ret); 864 } 865 866 wdata->battery.properties = wacom_battery_props; 867 wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); 868 wdata->battery.get_property = wacom_battery_get_property; 869 wdata->battery.name = "wacom_battery"; 870 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; 871 wdata->battery.use_for_apm = 0; 872 873 874 ret = power_supply_register(&hdev->dev, &wdata->battery); 875 if (ret) { 876 hid_err(hdev, "can't create sysfs battery attribute, err: %d\n", 877 ret); 878 goto err_battery; 879 } 880 881 power_supply_powers(&wdata->battery, &hdev->dev); 882 883 wdata->ac.properties = wacom_ac_props; 884 wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props); 885 wdata->ac.get_property = wacom_ac_get_property; 886 wdata->ac.name = "wacom_ac"; 887 wdata->ac.type = POWER_SUPPLY_TYPE_MAINS; 888 wdata->ac.use_for_apm = 0; 889 890 ret = power_supply_register(&hdev->dev, &wdata->ac); 891 if (ret) { 892 hid_err(hdev, 893 "can't create ac battery attribute, err: %d\n", ret); 894 goto err_ac; 895 } 896 897 power_supply_powers(&wdata->ac, &hdev->dev); 898 return 0; 899 900err_ac: 901 power_supply_unregister(&wdata->battery); 902err_battery: 903 wacom_destroy_leds(hdev); 904 device_remove_file(&hdev->dev, &dev_attr_oled0_img); 905 device_remove_file(&hdev->dev, &dev_attr_oled1_img); 906 device_remove_file(&hdev->dev, &dev_attr_oled2_img); 907 device_remove_file(&hdev->dev, &dev_attr_oled3_img); 908 device_remove_file(&hdev->dev, &dev_attr_oled4_img); 909 device_remove_file(&hdev->dev, &dev_attr_oled5_img); 910 device_remove_file(&hdev->dev, &dev_attr_oled6_img); 911 device_remove_file(&hdev->dev, &dev_attr_oled7_img); 912 device_remove_file(&hdev->dev, &dev_attr_speed); 913 hid_hw_stop(hdev); 914err_free: 915 kfree(wdata); 916 return ret; 917} 918 919static void wacom_remove(struct hid_device *hdev) 920{ 921 struct wacom_data *wdata = hid_get_drvdata(hdev); 922 923 wacom_destroy_leds(hdev); 924 device_remove_file(&hdev->dev, &dev_attr_oled0_img); 925 device_remove_file(&hdev->dev, &dev_attr_oled1_img); 926 device_remove_file(&hdev->dev, &dev_attr_oled2_img); 927 device_remove_file(&hdev->dev, &dev_attr_oled3_img); 928 device_remove_file(&hdev->dev, &dev_attr_oled4_img); 929 device_remove_file(&hdev->dev, &dev_attr_oled5_img); 930 device_remove_file(&hdev->dev, &dev_attr_oled6_img); 931 device_remove_file(&hdev->dev, &dev_attr_oled7_img); 932 device_remove_file(&hdev->dev, &dev_attr_speed); 933 hid_hw_stop(hdev); 934 935 power_supply_unregister(&wdata->battery); 936 power_supply_unregister(&wdata->ac); 937 kfree(hid_get_drvdata(hdev)); 938} 939 940static const struct hid_device_id wacom_devices[] = { 941 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 942 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, 943 944 { } 945}; 946MODULE_DEVICE_TABLE(hid, wacom_devices); 947 948static struct hid_driver wacom_driver = { 949 .name = "wacom", 950 .id_table = wacom_devices, 951 .probe = wacom_probe, 952 .remove = wacom_remove, 953 .raw_event = wacom_raw_event, 954 .input_mapped = wacom_input_mapped, 955}; 956module_hid_driver(wacom_driver); 957 958MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); 959MODULE_LICENSE("GPL");