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