linux/drivers/hid/hid-wacom.c
<<
>>
Prefs
   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};
 956
 957static int __init wacom_init(void)
 958{
 959        int ret;
 960
 961        ret = hid_register_driver(&wacom_driver);
 962        if (ret)
 963                pr_err("can't register wacom driver\n");
 964        return ret;
 965}
 966
 967static void __exit wacom_exit(void)
 968{
 969        hid_unregister_driver(&wacom_driver);
 970}
 971
 972module_init(wacom_init);
 973module_exit(wacom_exit);
 974MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
 975MODULE_LICENSE("GPL");
 976
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.