linux/drivers/input/tablet/wacom_wac.c
<<
>>
Prefs
   1/*
   2 * drivers/input/tablet/wacom_wac.c
   3 *
   4 *  USB Wacom tablet support - Wacom specific code
   5 *
   6 */
   7
   8/*
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 */
  14
  15#include "wacom_wac.h"
  16#include "wacom.h"
  17#include <linux/input/mt.h>
  18#include <linux/hid.h>
  19
  20/* resolution for penabled devices */
  21#define WACOM_PL_RES            20
  22#define WACOM_PENPRTN_RES       40
  23#define WACOM_VOLITO_RES        50
  24#define WACOM_GRAPHIRE_RES      80
  25#define WACOM_INTUOS_RES        100
  26#define WACOM_INTUOS3_RES       200
  27
  28static int wacom_penpartner_irq(struct wacom_wac *wacom)
  29{
  30        unsigned char *data = wacom->data;
  31        struct input_dev *input = wacom->input;
  32
  33        switch (data[0]) {
  34        case 1:
  35                if (data[5] & 0x80) {
  36                        wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  37                        wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
  38                        input_report_key(input, wacom->tool[0], 1);
  39                        input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
  40                        input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
  41                        input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
  42                        input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
  43                        input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127));
  44                        input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
  45                } else {
  46                        input_report_key(input, wacom->tool[0], 0);
  47                        input_report_abs(input, ABS_MISC, 0); /* report tool id */
  48                        input_report_abs(input, ABS_PRESSURE, -1);
  49                        input_report_key(input, BTN_TOUCH, 0);
  50                }
  51                break;
  52
  53        case 2:
  54                input_report_key(input, BTN_TOOL_PEN, 1);
  55                input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
  56                input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
  57                input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
  58                input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
  59                input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
  60                input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
  61                break;
  62
  63        default:
  64                printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
  65                return 0;
  66        }
  67
  68        return 1;
  69}
  70
  71static int wacom_pl_irq(struct wacom_wac *wacom)
  72{
  73        struct wacom_features *features = &wacom->features;
  74        unsigned char *data = wacom->data;
  75        struct input_dev *input = wacom->input;
  76        int prox, pressure;
  77
  78        if (data[0] != WACOM_REPORT_PENABLED) {
  79                dbg("wacom_pl_irq: received unknown report #%d", data[0]);
  80                return 0;
  81        }
  82
  83        prox = data[1] & 0x40;
  84
  85        if (prox) {
  86                wacom->id[0] = ERASER_DEVICE_ID;
  87                pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
  88                if (features->pressure_max > 255)
  89                        pressure = (pressure << 1) | ((data[4] >> 6) & 1);
  90                pressure += (features->pressure_max + 1) / 2;
  91
  92                /*
  93                 * if going from out of proximity into proximity select between the eraser
  94                 * and the pen based on the state of the stylus2 button, choose eraser if
  95                 * pressed else choose pen. if not a proximity change from out to in, send
  96                 * an out of proximity for previous tool then a in for new tool.
  97                 */
  98                if (!wacom->tool[0]) {
  99                        /* Eraser bit set for DTF */
 100                        if (data[1] & 0x10)
 101                                wacom->tool[1] = BTN_TOOL_RUBBER;
 102                        else
 103                                /* Going into proximity select tool */
 104                                wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
 105                } else {
 106                        /* was entered with stylus2 pressed */
 107                        if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
 108                                /* report out proximity for previous tool */
 109                                input_report_key(input, wacom->tool[1], 0);
 110                                input_sync(input);
 111                                wacom->tool[1] = BTN_TOOL_PEN;
 112                                return 0;
 113                        }
 114                }
 115                if (wacom->tool[1] != BTN_TOOL_RUBBER) {
 116                        /* Unknown tool selected default to pen tool */
 117                        wacom->tool[1] = BTN_TOOL_PEN;
 118                        wacom->id[0] = STYLUS_DEVICE_ID;
 119                }
 120                input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */
 121                input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
 122                input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
 123                input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
 124                input_report_abs(input, ABS_PRESSURE, pressure);
 125
 126                input_report_key(input, BTN_TOUCH, data[4] & 0x08);
 127                input_report_key(input, BTN_STYLUS, data[4] & 0x10);
 128                /* Only allow the stylus2 button to be reported for the pen tool. */
 129                input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
 130        } else {
 131                /* report proximity-out of a (valid) tool */
 132                if (wacom->tool[1] != BTN_TOOL_RUBBER) {
 133                        /* Unknown tool selected default to pen tool */
 134                        wacom->tool[1] = BTN_TOOL_PEN;
 135                }
 136                input_report_key(input, wacom->tool[1], prox);
 137        }
 138
 139        wacom->tool[0] = prox; /* Save proximity state */
 140        return 1;
 141}
 142
 143static int wacom_ptu_irq(struct wacom_wac *wacom)
 144{
 145        unsigned char *data = wacom->data;
 146        struct input_dev *input = wacom->input;
 147
 148        if (data[0] != WACOM_REPORT_PENABLED) {
 149                printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
 150                return 0;
 151        }
 152
 153        if (data[1] & 0x04) {
 154                input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20);
 155                input_report_key(input, BTN_TOUCH, data[1] & 0x08);
 156                wacom->id[0] = ERASER_DEVICE_ID;
 157        } else {
 158                input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20);
 159                input_report_key(input, BTN_TOUCH, data[1] & 0x01);
 160                wacom->id[0] = STYLUS_DEVICE_ID;
 161        }
 162        input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
 163        input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
 164        input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
 165        input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6]));
 166        input_report_key(input, BTN_STYLUS, data[1] & 0x02);
 167        input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
 168        return 1;
 169}
 170
 171static int wacom_dtu_irq(struct wacom_wac *wacom)
 172{
 173        struct wacom_features *features = &wacom->features;
 174        char *data = wacom->data;
 175        struct input_dev *input = wacom->input;
 176        int prox = data[1] & 0x20, pressure;
 177
 178        dbg("wacom_dtu_irq: received report #%d", data[0]);
 179
 180        if (prox) {
 181                /* Going into proximity select tool */
 182                wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
 183                if (wacom->tool[0] == BTN_TOOL_PEN)
 184                        wacom->id[0] = STYLUS_DEVICE_ID;
 185                else
 186                        wacom->id[0] = ERASER_DEVICE_ID;
 187        }
 188        input_report_key(input, BTN_STYLUS, data[1] & 0x02);
 189        input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
 190        input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
 191        input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
 192        pressure = ((data[7] & 0x01) << 8) | data[6];
 193        if (pressure < 0)
 194                pressure = features->pressure_max + pressure + 1;
 195        input_report_abs(input, ABS_PRESSURE, pressure);
 196        input_report_key(input, BTN_TOUCH, data[1] & 0x05);
 197        if (!prox) /* out-prox */
 198                wacom->id[0] = 0;
 199        input_report_key(input, wacom->tool[0], prox);
 200        input_report_abs(input, ABS_MISC, wacom->id[0]);
 201        return 1;
 202}
 203
 204static int wacom_graphire_irq(struct wacom_wac *wacom)
 205{
 206        struct wacom_features *features = &wacom->features;
 207        unsigned char *data = wacom->data;
 208        struct input_dev *input = wacom->input;
 209        int prox;
 210        int rw = 0;
 211        int retval = 0;
 212
 213        if (data[0] != WACOM_REPORT_PENABLED) {
 214                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
 215                goto exit;
 216        }
 217
 218        prox = data[1] & 0x80;
 219        if (prox || wacom->id[0]) {
 220                if (prox) {
 221                        switch ((data[1] >> 5) & 3) {
 222
 223                        case 0: /* Pen */
 224                                wacom->tool[0] = BTN_TOOL_PEN;
 225                                wacom->id[0] = STYLUS_DEVICE_ID;
 226                                break;
 227
 228                        case 1: /* Rubber */
 229                                wacom->tool[0] = BTN_TOOL_RUBBER;
 230                                wacom->id[0] = ERASER_DEVICE_ID;
 231                                break;
 232
 233                        case 2: /* Mouse with wheel */
 234                                input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
 235                                /* fall through */
 236
 237                        case 3: /* Mouse without wheel */
 238                                wacom->tool[0] = BTN_TOOL_MOUSE;
 239                                wacom->id[0] = CURSOR_DEVICE_ID;
 240                                break;
 241                        }
 242                }
 243                input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
 244                input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
 245                if (wacom->tool[0] != BTN_TOOL_MOUSE) {
 246                        input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
 247                        input_report_key(input, BTN_TOUCH, data[1] & 0x01);
 248                        input_report_key(input, BTN_STYLUS, data[1] & 0x02);
 249                        input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
 250                } else {
 251                        input_report_key(input, BTN_LEFT, data[1] & 0x01);
 252                        input_report_key(input, BTN_RIGHT, data[1] & 0x02);
 253                        if (features->type == WACOM_G4 ||
 254                                        features->type == WACOM_MO) {
 255                                input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);
 256                                rw = (data[7] & 0x04) - (data[7] & 0x03);
 257                        } else {
 258                                input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);
 259                                rw = -(signed char)data[6];
 260                        }
 261                        input_report_rel(input, REL_WHEEL, rw);
 262                }
 263
 264                if (!prox)
 265                        wacom->id[0] = 0;
 266                input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
 267                input_report_key(input, wacom->tool[0], prox);
 268                input_event(input, EV_MSC, MSC_SERIAL, 1);
 269                input_sync(input); /* sync last event */
 270        }
 271
 272        /* send pad data */
 273        switch (features->type) {
 274        case WACOM_G4:
 275                prox = data[7] & 0xf8;
 276                if (prox || wacom->id[1]) {
 277                        wacom->id[1] = PAD_DEVICE_ID;
 278                        input_report_key(input, BTN_BACK, (data[7] & 0x40));
 279                        input_report_key(input, BTN_FORWARD, (data[7] & 0x80));
 280                        rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
 281                        input_report_rel(input, REL_WHEEL, rw);
 282                        if (!prox)
 283                                wacom->id[1] = 0;
 284                        input_report_abs(input, ABS_MISC, wacom->id[1]);
 285                        input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
 286                        retval = 1;
 287                }
 288                break;
 289
 290        case WACOM_MO:
 291                prox = (data[7] & 0xf8) || data[8];
 292                if (prox || wacom->id[1]) {
 293                        wacom->id[1] = PAD_DEVICE_ID;
 294                        input_report_key(input, BTN_BACK, (data[7] & 0x08));
 295                        input_report_key(input, BTN_LEFT, (data[7] & 0x20));
 296                        input_report_key(input, BTN_FORWARD, (data[7] & 0x10));
 297                        input_report_key(input, BTN_RIGHT, (data[7] & 0x40));
 298                        input_report_abs(input, ABS_WHEEL, (data[8] & 0x7f));
 299                        if (!prox)
 300                                wacom->id[1] = 0;
 301                        input_report_abs(input, ABS_MISC, wacom->id[1]);
 302                        input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
 303                        retval = 1;
 304                }
 305                break;
 306        }
 307exit:
 308        return retval;
 309}
 310
 311static int wacom_intuos_inout(struct wacom_wac *wacom)
 312{
 313        struct wacom_features *features = &wacom->features;
 314        unsigned char *data = wacom->data;
 315        struct input_dev *input = wacom->input;
 316        int idx = 0;
 317
 318        /* tool number */
 319        if (features->type == INTUOS)
 320                idx = data[1] & 0x01;
 321
 322        /* Enter report */
 323        if ((data[1] & 0xfc) == 0xc0) {
 324                /* serial number of the tool */
 325                wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
 326                        (data[4] << 20) + (data[5] << 12) +
 327                        (data[6] << 4) + (data[7] >> 4);
 328
 329                wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |
 330                        ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12);
 331
 332                switch (wacom->id[idx] & 0xfffff) {
 333                case 0x812: /* Inking pen */
 334                case 0x801: /* Intuos3 Inking pen */
 335                case 0x20802: /* Intuos4 Inking Pen */
 336                case 0x012:
 337                        wacom->tool[idx] = BTN_TOOL_PENCIL;
 338                        break;
 339
 340                case 0x822: /* Pen */
 341                case 0x842:
 342                case 0x852:
 343                case 0x823: /* Intuos3 Grip Pen */
 344                case 0x813: /* Intuos3 Classic Pen */
 345                case 0x885: /* Intuos3 Marker Pen */
 346                case 0x802: /* Intuos4 General Pen */
 347                case 0x804: /* Intuos4 Marker Pen */
 348                case 0x40802: /* Intuos4 Classic Pen */
 349                case 0x022:
 350                        wacom->tool[idx] = BTN_TOOL_PEN;
 351                        break;
 352
 353                case 0x832: /* Stroke pen */
 354                case 0x032:
 355                        wacom->tool[idx] = BTN_TOOL_BRUSH;
 356                        break;
 357
 358                case 0x007: /* Mouse 4D and 2D */
 359                case 0x09c:
 360                case 0x094:
 361                case 0x017: /* Intuos3 2D Mouse */
 362                case 0x806: /* Intuos4 Mouse */
 363                        wacom->tool[idx] = BTN_TOOL_MOUSE;
 364                        break;
 365
 366                case 0x096: /* Lens cursor */
 367                case 0x097: /* Intuos3 Lens cursor */
 368                case 0x006: /* Intuos4 Lens cursor */
 369                        wacom->tool[idx] = BTN_TOOL_LENS;
 370                        break;
 371
 372                case 0x82a: /* Eraser */
 373                case 0x85a:
 374                case 0x91a:
 375                case 0xd1a:
 376                case 0x0fa:
 377                case 0x82b: /* Intuos3 Grip Pen Eraser */
 378                case 0x81b: /* Intuos3 Classic Pen Eraser */
 379                case 0x91b: /* Intuos3 Airbrush Eraser */
 380                case 0x80c: /* Intuos4 Marker Pen Eraser */
 381                case 0x80a: /* Intuos4 General Pen Eraser */
 382                case 0x4080a: /* Intuos4 Classic Pen Eraser */
 383                case 0x90a: /* Intuos4 Airbrush Eraser */
 384                        wacom->tool[idx] = BTN_TOOL_RUBBER;
 385                        break;
 386
 387                case 0xd12:
 388                case 0x912:
 389                case 0x112:
 390                case 0x913: /* Intuos3 Airbrush */
 391                case 0x902: /* Intuos4 Airbrush */
 392                        wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
 393                        break;
 394
 395                default: /* Unknown tool */
 396                        wacom->tool[idx] = BTN_TOOL_PEN;
 397                        break;
 398                }
 399                return 1;
 400        }
 401
 402        /* older I4 styli don't work with new Cintiqs */
 403        if (!((wacom->id[idx] >> 20) & 0x01) &&
 404                        (features->type == WACOM_21UX2))
 405                return 1;
 406
 407        /* Exit report */
 408        if ((data[1] & 0xfe) == 0x80) {
 409                /*
 410                 * Reset all states otherwise we lose the initial states
 411                 * when in-prox next time
 412                 */
 413                input_report_abs(input, ABS_X, 0);
 414                input_report_abs(input, ABS_Y, 0);
 415                input_report_abs(input, ABS_DISTANCE, 0);
 416                input_report_abs(input, ABS_TILT_X, 0);
 417                input_report_abs(input, ABS_TILT_Y, 0);
 418                if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
 419                        input_report_key(input, BTN_LEFT, 0);
 420                        input_report_key(input, BTN_MIDDLE, 0);
 421                        input_report_key(input, BTN_RIGHT, 0);
 422                        input_report_key(input, BTN_SIDE, 0);
 423                        input_report_key(input, BTN_EXTRA, 0);
 424                        input_report_abs(input, ABS_THROTTLE, 0);
 425                        input_report_abs(input, ABS_RZ, 0);
 426                } else {
 427                        input_report_abs(input, ABS_PRESSURE, 0);
 428                        input_report_key(input, BTN_STYLUS, 0);
 429                        input_report_key(input, BTN_STYLUS2, 0);
 430                        input_report_key(input, BTN_TOUCH, 0);
 431                        input_report_abs(input, ABS_WHEEL, 0);
 432                        if (features->type >= INTUOS3S)
 433                                input_report_abs(input, ABS_Z, 0);
 434                }
 435                input_report_key(input, wacom->tool[idx], 0);
 436                input_report_abs(input, ABS_MISC, 0); /* reset tool id */
 437                input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 438                wacom->id[idx] = 0;
 439                return 2;
 440        }
 441        return 0;
 442}
 443
 444static void wacom_intuos_general(struct wacom_wac *wacom)
 445{
 446        struct wacom_features *features = &wacom->features;
 447        unsigned char *data = wacom->data;
 448        struct input_dev *input = wacom->input;
 449        unsigned int t;
 450
 451        /* general pen packet */
 452        if ((data[1] & 0xb8) == 0xa0) {
 453                t = (data[6] << 2) | ((data[7] >> 6) & 3);
 454                if ((features->type >= INTUOS4S && features->type <= INTUOS4L) ||
 455                    features->type == WACOM_21UX2) {
 456                        t = (t << 1) | (data[1] & 1);
 457                }
 458                input_report_abs(input, ABS_PRESSURE, t);
 459                input_report_abs(input, ABS_TILT_X,
 460                                ((data[7] << 1) & 0x7e) | (data[8] >> 7));
 461                input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
 462                input_report_key(input, BTN_STYLUS, data[1] & 2);
 463                input_report_key(input, BTN_STYLUS2, data[1] & 4);
 464                input_report_key(input, BTN_TOUCH, t > 10);
 465        }
 466
 467        /* airbrush second packet */
 468        if ((data[1] & 0xbc) == 0xb4) {
 469                input_report_abs(input, ABS_WHEEL,
 470                                (data[6] << 2) | ((data[7] >> 6) & 3));
 471                input_report_abs(input, ABS_TILT_X,
 472                                ((data[7] << 1) & 0x7e) | (data[8] >> 7));
 473                input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
 474        }
 475}
 476
 477static int wacom_intuos_irq(struct wacom_wac *wacom)
 478{
 479        struct wacom_features *features = &wacom->features;
 480        unsigned char *data = wacom->data;
 481        struct input_dev *input = wacom->input;
 482        unsigned int t;
 483        int idx = 0, result;
 484
 485        if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD
 486                && data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) {
 487                dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
 488                return 0;
 489        }
 490
 491        /* tool number */
 492        if (features->type == INTUOS)
 493                idx = data[1] & 0x01;
 494
 495        /* pad packets. Works as a second tool and is always in prox */
 496        if (data[0] == WACOM_REPORT_INTUOSPAD) {
 497                if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
 498                        input_report_key(input, BTN_0, (data[2] & 0x01));
 499                        input_report_key(input, BTN_1, (data[3] & 0x01));
 500                        input_report_key(input, BTN_2, (data[3] & 0x02));
 501                        input_report_key(input, BTN_3, (data[3] & 0x04));
 502                        input_report_key(input, BTN_4, (data[3] & 0x08));
 503                        input_report_key(input, BTN_5, (data[3] & 0x10));
 504                        input_report_key(input, BTN_6, (data[3] & 0x20));
 505                        if (data[1] & 0x80) {
 506                                input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
 507                        } else {
 508                                /* Out of proximity, clear wheel value. */
 509                                input_report_abs(input, ABS_WHEEL, 0);
 510                        }
 511                        if (features->type != INTUOS4S) {
 512                                input_report_key(input, BTN_7, (data[3] & 0x40));
 513                                input_report_key(input, BTN_8, (data[3] & 0x80));
 514                        }
 515                        if (data[1] | (data[2] & 0x01) | data[3]) {
 516                                input_report_key(input, wacom->tool[1], 1);
 517                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
 518                        } else {
 519                                input_report_key(input, wacom->tool[1], 0);
 520                                input_report_abs(input, ABS_MISC, 0);
 521                        }
 522                } else {
 523                        if (features->type == WACOM_21UX2) {
 524                                input_report_key(input, BTN_0, (data[5] & 0x01));
 525                                input_report_key(input, BTN_1, (data[6] & 0x01));
 526                                input_report_key(input, BTN_2, (data[6] & 0x02));
 527                                input_report_key(input, BTN_3, (data[6] & 0x04));
 528                                input_report_key(input, BTN_4, (data[6] & 0x08));
 529                                input_report_key(input, BTN_5, (data[6] & 0x10));
 530                                input_report_key(input, BTN_6, (data[6] & 0x20));
 531                                input_report_key(input, BTN_7, (data[6] & 0x40));
 532                                input_report_key(input, BTN_8, (data[6] & 0x80));
 533                                input_report_key(input, BTN_9, (data[7] & 0x01));
 534                                input_report_key(input, BTN_A, (data[8] & 0x01));
 535                                input_report_key(input, BTN_B, (data[8] & 0x02));
 536                                input_report_key(input, BTN_C, (data[8] & 0x04));
 537                                input_report_key(input, BTN_X, (data[8] & 0x08));
 538                                input_report_key(input, BTN_Y, (data[8] & 0x10));
 539                                input_report_key(input, BTN_Z, (data[8] & 0x20));
 540                                input_report_key(input, BTN_BASE, (data[8] & 0x40));
 541                                input_report_key(input, BTN_BASE2, (data[8] & 0x80));
 542                        } else {
 543                                input_report_key(input, BTN_0, (data[5] & 0x01));
 544                                input_report_key(input, BTN_1, (data[5] & 0x02));
 545                                input_report_key(input, BTN_2, (data[5] & 0x04));
 546                                input_report_key(input, BTN_3, (data[5] & 0x08));
 547                                input_report_key(input, BTN_4, (data[6] & 0x01));
 548                                input_report_key(input, BTN_5, (data[6] & 0x02));
 549                                input_report_key(input, BTN_6, (data[6] & 0x04));
 550                                input_report_key(input, BTN_7, (data[6] & 0x08));
 551                                input_report_key(input, BTN_8, (data[5] & 0x10));
 552                                input_report_key(input, BTN_9, (data[6] & 0x10));
 553                        }
 554                        input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
 555                        input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
 556
 557                        if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
 558                                data[2] | (data[3] & 0x1f) | data[4] | data[8] |
 559                                (data[7] & 0x01)) {
 560                                input_report_key(input, wacom->tool[1], 1);
 561                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
 562                        } else {
 563                                input_report_key(input, wacom->tool[1], 0);
 564                                input_report_abs(input, ABS_MISC, 0);
 565                        }
 566                }
 567                input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
 568                return 1;
 569        }
 570
 571        /* process in/out prox events */
 572        result = wacom_intuos_inout(wacom);
 573        if (result)
 574                return result - 1;
 575
 576        /* don't proceed if we don't know the ID */
 577        if (!wacom->id[idx])
 578                return 0;
 579
 580        /* Only large Intuos support Lense Cursor */
 581        if (wacom->tool[idx] == BTN_TOOL_LENS &&
 582            (features->type == INTUOS3 ||
 583             features->type == INTUOS3S ||
 584             features->type == INTUOS4 ||
 585             features->type == INTUOS4S)) {
 586
 587                return 0;
 588        }
 589
 590        /* Cintiq doesn't send data when RDY bit isn't set */
 591        if (features->type == CINTIQ && !(data[1] & 0x40))
 592                 return 0;
 593
 594        if (features->type >= INTUOS3S) {
 595                input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
 596                input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
 597                input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
 598        } else {
 599                input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2]));
 600                input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4]));
 601                input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
 602        }
 603
 604        /* process general packets */
 605        wacom_intuos_general(wacom);
 606
 607        /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */
 608        if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) {
 609
 610                if (data[1] & 0x02) {
 611                        /* Rotation packet */
 612                        if (features->type >= INTUOS3S) {
 613                                /* I3 marker pen rotation */
 614                                t = (data[6] << 3) | ((data[7] >> 5) & 7);
 615                                t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
 616                                        ((t-1) / 2 + 450)) : (450 - t / 2) ;
 617                                input_report_abs(input, ABS_Z, t);
 618                        } else {
 619                                /* 4D mouse rotation packet */
 620                                t = (data[6] << 3) | ((data[7] >> 5) & 7);
 621                                input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
 622                                        ((t - 1) / 2) : -t / 2);
 623                        }
 624
 625                } else if (!(data[1] & 0x10) && features->type < INTUOS3S) {
 626                        /* 4D mouse packet */
 627                        input_report_key(input, BTN_LEFT,   data[8] & 0x01);
 628                        input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
 629                        input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
 630
 631                        input_report_key(input, BTN_SIDE,   data[8] & 0x20);
 632                        input_report_key(input, BTN_EXTRA,  data[8] & 0x10);
 633                        t = (data[6] << 2) | ((data[7] >> 6) & 3);
 634                        input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
 635
 636                } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
 637                        /* I4 mouse */
 638                        if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
 639                                input_report_key(input, BTN_LEFT,   data[6] & 0x01);
 640                                input_report_key(input, BTN_MIDDLE, data[6] & 0x02);
 641                                input_report_key(input, BTN_RIGHT,  data[6] & 0x04);
 642                                input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)
 643                                                 - ((data[7] & 0x40) >> 6));
 644                                input_report_key(input, BTN_SIDE,   data[6] & 0x08);
 645                                input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
 646
 647                                input_report_abs(input, ABS_TILT_X,
 648                                        ((data[7] << 1) & 0x7e) | (data[8] >> 7));
 649                                input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
 650                        } else {
 651                                /* 2D mouse packet */
 652                                input_report_key(input, BTN_LEFT,   data[8] & 0x04);
 653                                input_report_key(input, BTN_MIDDLE, data[8] & 0x08);
 654                                input_report_key(input, BTN_RIGHT,  data[8] & 0x10);
 655                                input_report_rel(input, REL_WHEEL, (data[8] & 0x01)
 656                                                 - ((data[8] & 0x02) >> 1));
 657
 658                                /* I3 2D mouse side buttons */
 659                                if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
 660                                        input_report_key(input, BTN_SIDE,   data[8] & 0x40);
 661                                        input_report_key(input, BTN_EXTRA,  data[8] & 0x20);
 662                                }
 663                        }
 664                } else if ((features->type < INTUOS3S || features->type == INTUOS3L ||
 665                                features->type == INTUOS4L) &&
 666                           wacom->tool[idx] == BTN_TOOL_LENS) {
 667                        /* Lens cursor packets */
 668                        input_report_key(input, BTN_LEFT,   data[8] & 0x01);
 669                        input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
 670                        input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
 671                        input_report_key(input, BTN_SIDE,   data[8] & 0x10);
 672                        input_report_key(input, BTN_EXTRA,  data[8] & 0x08);
 673                }
 674        }
 675
 676        input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
 677        input_report_key(input, wacom->tool[idx], 1);
 678        input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 679        return 1;
 680}
 681
 682static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
 683{
 684        struct input_dev *input = wacom->input;
 685        unsigned char *data = wacom->data;
 686        int contact_with_no_pen_down_count = 0;
 687        int i;
 688
 689        for (i = 0; i < 2; i++) {
 690                int p = data[1] & (1 << i);
 691                bool touch = p && !wacom->shared->stylus_in_proximity;
 692
 693                input_mt_slot(input, i);
 694                input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
 695                if (touch) {
 696                        int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff;
 697                        int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff;
 698
 699                        input_report_abs(input, ABS_MT_POSITION_X, x);
 700                        input_report_abs(input, ABS_MT_POSITION_Y, y);
 701                        contact_with_no_pen_down_count++;
 702                }
 703        }
 704
 705        /* keep touch state for pen event */
 706        wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
 707
 708        input_mt_report_pointer_emulation(input, true);
 709
 710        return 1;
 711}
 712
 713static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
 714{
 715        char *data = wacom->data;
 716        struct input_dev *input = wacom->input;
 717        bool prox;
 718        int x = 0, y = 0;
 719
 720        if (!wacom->shared->stylus_in_proximity) {
 721                if (len == WACOM_PKGLEN_TPC1FG) {
 722                        prox = data[0] & 0x01;
 723                        x = get_unaligned_le16(&data[1]);
 724                        y = get_unaligned_le16(&data[3]);
 725                } else { /* with capacity */
 726                        prox = data[1] & 0x01;
 727                        x = le16_to_cpup((__le16 *)&data[2]);
 728                        y = le16_to_cpup((__le16 *)&data[4]);
 729                }
 730        } else
 731                /* force touch out when pen is in prox */
 732                prox = 0;
 733
 734        if (prox) {
 735                input_report_abs(input, ABS_X, x);
 736                input_report_abs(input, ABS_Y, y);
 737        }
 738        input_report_key(input, BTN_TOUCH, prox);
 739
 740        /* keep touch state for pen events */
 741        wacom->shared->touch_down = prox;
 742
 743        return 1;
 744}
 745
 746static int wacom_tpc_pen(struct wacom_wac *wacom)
 747{
 748        struct wacom_features *features = &wacom->features;
 749        char *data = wacom->data;
 750        struct input_dev *input = wacom->input;
 751        int pressure;
 752        bool prox = data[1] & 0x20;
 753
 754        if (!wacom->shared->stylus_in_proximity) /* first in prox */
 755                /* Going into proximity select tool */
 756                wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
 757
 758        /* keep pen state for touch events */
 759        wacom->shared->stylus_in_proximity = prox;
 760
 761        /* send pen events only when touch is up or forced out */
 762        if (!wacom->shared->touch_down) {
 763                input_report_key(input, BTN_STYLUS, data[1] & 0x02);
 764                input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
 765                input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
 766                input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
 767                pressure = ((data[7] & 0x01) << 8) | data[6];
 768                if (pressure < 0)
 769                        pressure = features->pressure_max + pressure + 1;
 770                input_report_abs(input, ABS_PRESSURE, pressure);
 771                input_report_key(input, BTN_TOUCH, data[1] & 0x05);
 772                input_report_key(input, wacom->tool[0], prox);
 773                return 1;
 774        }
 775
 776        return 0;
 777}
 778
 779static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
 780{
 781        char *data = wacom->data;
 782
 783        dbg("wacom_tpc_irq: received report #%d", data[0]);
 784
 785        if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG)
 786                return wacom_tpc_single_touch(wacom, len);
 787        else if (data[0] == WACOM_REPORT_TPC2FG)
 788                return wacom_tpc_mt_touch(wacom);
 789        else if (data[0] == WACOM_REPORT_PENABLED)
 790                return wacom_tpc_pen(wacom);
 791
 792        return 0;
 793}
 794
 795static int wacom_bpt_touch(struct wacom_wac *wacom)
 796{
 797        struct wacom_features *features = &wacom->features;
 798        struct input_dev *input = wacom->input;
 799        unsigned char *data = wacom->data;
 800        int i;
 801
 802        for (i = 0; i < 2; i++) {
 803                int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
 804                bool touch = data[offset + 3] & 0x80;
 805
 806                /*
 807                 * Touch events need to be disabled while stylus is
 808                 * in proximity because user's hand is resting on touchpad
 809                 * and sending unwanted events.  User expects tablet buttons
 810                 * to continue working though.
 811                 */
 812                touch = touch && !wacom->shared->stylus_in_proximity;
 813
 814                input_mt_slot(input, i);
 815                input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
 816                if (touch) {
 817                        int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
 818                        int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
 819                        if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
 820                                x <<= 5;
 821                                y <<= 5;
 822                        }
 823                        input_report_abs(input, ABS_MT_POSITION_X, x);
 824                        input_report_abs(input, ABS_MT_POSITION_Y, y);
 825                }
 826        }
 827
 828        input_mt_report_pointer_emulation(input, true);
 829
 830        input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
 831        input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
 832        input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
 833        input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
 834
 835        input_sync(input);
 836
 837        return 0;
 838}
 839
 840static int wacom_bpt_pen(struct wacom_wac *wacom)
 841{
 842        struct input_dev *input = wacom->input;
 843        unsigned char *data = wacom->data;
 844        int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
 845
 846        /*
 847         * Similar to Graphire protocol, data[1] & 0x20 is proximity and
 848         * data[1] & 0x18 is tool ID.  0x30 is safety check to ignore
 849         * 2 unused tool ID's.
 850         */
 851        prox = (data[1] & 0x30) == 0x30;
 852
 853        /*
 854         * All reports shared between PEN and RUBBER tool must be
 855         * forced to a known starting value (zero) when transitioning to
 856         * out-of-prox.
 857         *
 858         * If not reset then, to userspace, it will look like lost events
 859         * if new tool comes in-prox with same values as previous tool sent.
 860         *
 861         * Hardware does report zero in most out-of-prox cases but not all.
 862         */
 863        if (prox) {
 864                if (!wacom->shared->stylus_in_proximity) {
 865                        if (data[1] & 0x08) {
 866                                wacom->tool[0] = BTN_TOOL_RUBBER;
 867                                wacom->id[0] = ERASER_DEVICE_ID;
 868                        } else {
 869                                wacom->tool[0] = BTN_TOOL_PEN;
 870                                wacom->id[0] = STYLUS_DEVICE_ID;
 871                        }
 872                        wacom->shared->stylus_in_proximity = true;
 873                }
 874                x = le16_to_cpup((__le16 *)&data[2]);
 875                y = le16_to_cpup((__le16 *)&data[4]);
 876                p = le16_to_cpup((__le16 *)&data[6]);
 877                /*
 878                 * Convert distance from out prox to distance from tablet.
 879                 * distance will be greater than distance_max once
 880                 * touching and applying pressure; do not report negative
 881                 * distance.
 882                 */
 883                if (data[8] <= wacom->features.distance_max)
 884                        d = wacom->features.distance_max - data[8];
 885
 886                pen = data[1] & 0x01;
 887                btn1 = data[1] & 0x02;
 888                btn2 = data[1] & 0x04;
 889        }
 890
 891        input_report_key(input, BTN_TOUCH, pen);
 892        input_report_key(input, BTN_STYLUS, btn1);
 893        input_report_key(input, BTN_STYLUS2, btn2);
 894
 895        input_report_abs(input, ABS_X, x);
 896        input_report_abs(input, ABS_Y, y);
 897        input_report_abs(input, ABS_PRESSURE, p);
 898        input_report_abs(input, ABS_DISTANCE, d);
 899
 900        if (!prox) {
 901                wacom->id[0] = 0;
 902                wacom->shared->stylus_in_proximity = false;
 903        }
 904
 905        input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
 906        input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
 907
 908        return 1;
 909}
 910
 911static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
 912{
 913        if (len == WACOM_PKGLEN_BBTOUCH)
 914                return wacom_bpt_touch(wacom);
 915        else if (len == WACOM_PKGLEN_BBFUN)
 916                return wacom_bpt_pen(wacom);
 917
 918        return 0;
 919}
 920
 921void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
 922{
 923        bool sync;
 924
 925        switch (wacom_wac->features.type) {
 926        case PENPARTNER:
 927                sync = wacom_penpartner_irq(wacom_wac);
 928                break;
 929
 930        case PL:
 931                sync = wacom_pl_irq(wacom_wac);
 932                break;
 933
 934        case WACOM_G4:
 935        case GRAPHIRE:
 936        case WACOM_MO:
 937                sync = wacom_graphire_irq(wacom_wac);
 938                break;
 939
 940        case PTU:
 941                sync = wacom_ptu_irq(wacom_wac);
 942                break;
 943
 944        case DTU:
 945                sync = wacom_dtu_irq(wacom_wac);
 946                break;
 947
 948        case INTUOS:
 949        case INTUOS3S:
 950        case INTUOS3:
 951        case INTUOS3L:
 952        case INTUOS4S:
 953        case INTUOS4:
 954        case INTUOS4L:
 955        case CINTIQ:
 956        case WACOM_BEE:
 957        case WACOM_21UX2:
 958                sync = wacom_intuos_irq(wacom_wac);
 959                break;
 960
 961        case TABLETPC:
 962        case TABLETPC2FG:
 963                sync = wacom_tpc_irq(wacom_wac, len);
 964                break;
 965
 966        case BAMBOO_PT:
 967                sync = wacom_bpt_irq(wacom_wac, len);
 968                break;
 969
 970        default:
 971                sync = false;
 972                break;
 973        }
 974
 975        if (sync)
 976                input_sync(wacom_wac->input);
 977}
 978
 979static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
 980{
 981        struct input_dev *input_dev = wacom_wac->input;
 982
 983        input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
 984
 985        __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
 986        __set_bit(BTN_TOOL_PEN, input_dev->keybit);
 987        __set_bit(BTN_TOOL_BRUSH, input_dev->keybit);
 988        __set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
 989        __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
 990        __set_bit(BTN_STYLUS, input_dev->keybit);
 991        __set_bit(BTN_STYLUS2, input_dev->keybit);
 992
 993        input_set_abs_params(input_dev, ABS_DISTANCE,
 994                             0, wacom_wac->features.distance_max, 0, 0);
 995        input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
 996        input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
 997        input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
 998}
 999
1000static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
1001{
1002        struct input_dev *input_dev = wacom_wac->input;
1003
1004        input_set_capability(input_dev, EV_REL, REL_WHEEL);
1005
1006        wacom_setup_cintiq(wacom_wac);
1007
1008        __set_bit(BTN_LEFT, input_dev->keybit);
1009        __set_bit(BTN_RIGHT, input_dev->keybit);
1010        __set_bit(BTN_MIDDLE, input_dev->keybit);
1011        __set_bit(BTN_SIDE, input_dev->keybit);
1012        __set_bit(BTN_EXTRA, input_dev->keybit);
1013        __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
1014        __set_bit(BTN_TOOL_LENS, input_dev->keybit);
1015
1016        input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
1017        input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
1018}
1019
1020void wacom_setup_device_quirks(struct wacom_features *features)
1021{
1022
1023        /* touch device found but size is not defined. use default */
1024        if (features->device_type == BTN_TOOL_FINGER && !features->x_max) {
1025                features->x_max = 1023;
1026                features->y_max = 1023;
1027        }
1028
1029        /* these device have multiple inputs */
1030        if (features->type == TABLETPC || features->type == TABLETPC2FG ||
1031            features->type == BAMBOO_PT)
1032                features->quirks |= WACOM_QUIRK_MULTI_INPUT;
1033
1034        /* quirks for bamboo touch */
1035        if (features->type == BAMBOO_PT &&
1036            features->device_type == BTN_TOOL_DOUBLETAP) {
1037                features->x_max <<= 5;
1038                features->y_max <<= 5;
1039                features->x_fuzz <<= 5;
1040                features->y_fuzz <<= 5;
1041                features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
1042        }
1043}
1044
1045static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
1046                                              unsigned int physical_max)
1047{
1048       /* Touch physical dimensions are in 100th of mm */
1049       return (logical_max * 100) / physical_max;
1050}
1051
1052void wacom_setup_input_capabilities(struct input_dev *input_dev,
1053                                    struct wacom_wac *wacom_wac)
1054{
1055        struct wacom_features *features = &wacom_wac->features;
1056        int i;
1057
1058        input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1059
1060        __set_bit(BTN_TOUCH, input_dev->keybit);
1061
1062        input_set_abs_params(input_dev, ABS_X, 0, features->x_max,
1063                             features->x_fuzz, 0);
1064        input_set_abs_params(input_dev, ABS_Y, 0, features->y_max,
1065                             features->y_fuzz, 0);
1066
1067        if (features->device_type == BTN_TOOL_PEN) {
1068                input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max,
1069                             features->pressure_fuzz, 0);
1070
1071                /* penabled devices have fixed resolution for each model */
1072                input_abs_set_res(input_dev, ABS_X, features->x_resolution);
1073                input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
1074        } else {
1075                input_abs_set_res(input_dev, ABS_X,
1076                        wacom_calculate_touch_res(features->x_max,
1077                                                features->x_phy));
1078                input_abs_set_res(input_dev, ABS_Y,
1079                        wacom_calculate_touch_res(features->y_max,
1080                                                features->y_phy));
1081        }
1082
1083        __set_bit(ABS_MISC, input_dev->absbit);
1084
1085        switch (wacom_wac->features.type) {
1086        case WACOM_MO:
1087                input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
1088                /* fall through */
1089
1090        case WACOM_G4:
1091                input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
1092
1093                __set_bit(BTN_BACK, input_dev->keybit);
1094                __set_bit(BTN_FORWARD, input_dev->keybit);
1095                /* fall through */
1096
1097        case GRAPHIRE:
1098                input_set_capability(input_dev, EV_REL, REL_WHEEL);
1099
1100                __set_bit(BTN_LEFT, input_dev->keybit);
1101                __set_bit(BTN_RIGHT, input_dev->keybit);
1102                __set_bit(BTN_MIDDLE, input_dev->keybit);
1103
1104                __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1105                __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1106                __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
1107                __set_bit(BTN_STYLUS, input_dev->keybit);
1108                __set_bit(BTN_STYLUS2, input_dev->keybit);
1109
1110                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1111                break;
1112
1113        case WACOM_21UX2:
1114                __set_bit(BTN_A, input_dev->keybit);
1115                __set_bit(BTN_B, input_dev->keybit);
1116                __set_bit(BTN_C, input_dev->keybit);
1117                __set_bit(BTN_X, input_dev->keybit);
1118                __set_bit(BTN_Y, input_dev->keybit);
1119                __set_bit(BTN_Z, input_dev->keybit);
1120                __set_bit(BTN_BASE, input_dev->keybit);
1121                __set_bit(BTN_BASE2, input_dev->keybit);
1122                /* fall through */
1123
1124        case WACOM_BEE:
1125                __set_bit(BTN_8, input_dev->keybit);
1126                __set_bit(BTN_9, input_dev->keybit);
1127                /* fall through */
1128
1129        case CINTIQ:
1130                for (i = 0; i < 8; i++)
1131                        __set_bit(BTN_0 + i, input_dev->keybit);
1132
1133                input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
1134                input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
1135                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1136
1137                __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1138
1139                wacom_setup_cintiq(wacom_wac);
1140                break;
1141
1142        case INTUOS3:
1143        case INTUOS3L:
1144                __set_bit(BTN_4, input_dev->keybit);
1145                __set_bit(BTN_5, input_dev->keybit);
1146                __set_bit(BTN_6, input_dev->keybit);
1147                __set_bit(BTN_7, input_dev->keybit);
1148
1149                input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
1150                /* fall through */
1151
1152        case INTUOS3S:
1153                __set_bit(BTN_0, input_dev->keybit);
1154                __set_bit(BTN_1, input_dev->keybit);
1155                __set_bit(BTN_2, input_dev->keybit);
1156                __set_bit(BTN_3, input_dev->keybit);
1157
1158                input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
1159                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1160                /* fall through */
1161
1162        case INTUOS:
1163                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1164
1165                wacom_setup_intuos(wacom_wac);
1166                break;
1167
1168        case INTUOS4:
1169        case INTUOS4L:
1170                __set_bit(BTN_7, input_dev->keybit);
1171                __set_bit(BTN_8, input_dev->keybit);
1172                /* fall through */
1173
1174        case INTUOS4S:
1175                for (i = 0; i < 7; i++)
1176                        __set_bit(BTN_0 + i, input_dev->keybit);
1177
1178                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1179                wacom_setup_intuos(wacom_wac);
1180
1181                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1182                break;
1183
1184        case TABLETPC2FG:
1185                if (features->device_type == BTN_TOOL_DOUBLETAP) {
1186
1187                        input_mt_init_slots(input_dev, 2);
1188                        input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
1189                                        0, MT_TOOL_MAX, 0, 0);
1190                        input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1191                                        0, features->x_max, 0, 0);
1192                        input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1193                                        0, features->y_max, 0, 0);
1194                }
1195                /* fall through */
1196
1197        case TABLETPC:
1198                __clear_bit(ABS_MISC, input_dev->absbit);
1199
1200                __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1201
1202                if (features->device_type != BTN_TOOL_PEN)
1203                        break;  /* no need to process stylus stuff */
1204
1205                /* fall through */
1206
1207        case PL:
1208        case DTU:
1209                __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1210                __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1211                __set_bit(BTN_STYLUS, input_dev->keybit);
1212                __set_bit(BTN_STYLUS2, input_dev->keybit);
1213
1214                __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
1215                break;
1216
1217        case PTU:
1218                __set_bit(BTN_STYLUS2, input_dev->keybit);
1219                /* fall through */
1220
1221        case PENPARTNER:
1222                __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1223                __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1224                __set_bit(BTN_STYLUS, input_dev->keybit);
1225
1226                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1227                break;
1228
1229        case BAMBOO_PT:
1230                __clear_bit(ABS_MISC, input_dev->absbit);
1231
1232                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1233
1234                if (features->device_type == BTN_TOOL_DOUBLETAP) {
1235                        __set_bit(BTN_LEFT, input_dev->keybit);
1236                        __set_bit(BTN_FORWARD, input_dev->keybit);
1237                        __set_bit(BTN_BACK, input_dev->keybit);
1238                        __set_bit(BTN_RIGHT, input_dev->keybit);
1239
1240                        __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
1241                        __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
1242
1243                        input_mt_init_slots(input_dev, 2);
1244                        input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1245                                             0, features->x_max,
1246                                             features->x_fuzz, 0);
1247                        input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1248                                             0, features->y_max,
1249                                             features->y_fuzz, 0);
1250                } else if (features->device_type == BTN_TOOL_PEN) {
1251                        __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1252                        __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1253                        __set_bit(BTN_STYLUS, input_dev->keybit);
1254                        __set_bit(BTN_STYLUS2, input_dev->keybit);
1255                        input_set_abs_params(input_dev, ABS_DISTANCE, 0,
1256                                              features->distance_max,
1257                                              0, 0);
1258                }
1259                break;
1260        }
1261}
1262
1263static const struct wacom_features wacom_features_0x00 =
1264        { "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,
1265          0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
1266static const struct wacom_features wacom_features_0x10 =
1267        { "Wacom Graphire",       WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511,
1268          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1269static const struct wacom_features wacom_features_0x11 =
1270        { "Wacom Graphire2 4x5",  WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511,
1271          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1272static const struct wacom_features wacom_features_0x12 =
1273        { "Wacom Graphire2 5x7",  WACOM_PKGLEN_GRAPHIRE,  13918, 10206,  511,
1274          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1275static const struct wacom_features wacom_features_0x13 =
1276        { "Wacom Graphire3",      WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511,
1277          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1278static const struct wacom_features wacom_features_0x14 =
1279        { "Wacom Graphire3 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
1280          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1281static const struct wacom_features wacom_features_0x15 =
1282        { "Wacom Graphire4 4x5",  WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511,
1283          63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1284static const struct wacom_features wacom_features_0x16 =
1285        { "Wacom Graphire4 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
1286          63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1287static const struct wacom_features wacom_features_0x17 =
1288        { "Wacom BambooFun 4x5",  WACOM_PKGLEN_BBFUN,     14760,  9225,  511,
1289          63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1290static const struct wacom_features wacom_features_0x18 =
1291        { "Wacom BambooFun 6x8",  WACOM_PKGLEN_BBFUN,     21648, 13530,  511,
1292          63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1293static const struct wacom_features wacom_features_0x19 =
1294        { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
1295          63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1296static const struct wacom_features wacom_features_0x60 =
1297        { "Wacom Volito",         WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
1298          63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1299static const struct wacom_features wacom_features_0x61 =
1300        { "Wacom PenStation2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  255,
1301          63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1302static const struct wacom_features wacom_features_0x62 =
1303        { "Wacom Volito2 4x5",    WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
1304          63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1305static const struct wacom_features wacom_features_0x63 =
1306        { "Wacom Volito2 2x3",    WACOM_PKGLEN_GRAPHIRE,   3248,  2320,  511,
1307          63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1308static const struct wacom_features wacom_features_0x64 =
1309        { "Wacom PenPartner2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  511,
1310          63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1311static const struct wacom_features wacom_features_0x65 =
1312        { "Wacom Bamboo",         WACOM_PKGLEN_BBFUN,     14760,  9225,  511,
1313          63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1314static const struct wacom_features wacom_features_0x69 =
1315        { "Wacom Bamboo1",        WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
1316          63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
1317static const struct wacom_features wacom_features_0x6A =
1318        { "Wacom Bamboo1 4x6",    WACOM_PKGLEN_GRAPHIRE,  14760,  9225, 1023,
1319          63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1320static const struct wacom_features wacom_features_0x6B =
1321        { "Wacom Bamboo1 5x8",    WACOM_PKGLEN_GRAPHIRE,  21648, 13530, 1023,
1322          63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1323static const struct wacom_features wacom_features_0x20 =
1324        { "Wacom Intuos 4x5",     WACOM_PKGLEN_INTUOS,    12700, 10600, 1023,
1325          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1326static const struct wacom_features wacom_features_0x21 =
1327        { "Wacom Intuos 6x8",     WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
1328          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1329static const struct wacom_features wacom_features_0x22 =
1330        { "Wacom Intuos 9x12",    WACOM_PKGLEN_INTUOS,    30480, 24060, 1023,
1331          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1332static const struct wacom_features wacom_features_0x23 =
1333        { "Wacom Intuos 12x12",   WACOM_PKGLEN_INTUOS,    30480, 31680, 1023,
1334          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1335static const struct wacom_features wacom_features_0x24 =
1336        { "Wacom Intuos 12x18",   WACOM_PKGLEN_INTUOS,    45720, 31680, 1023,
1337          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1338static const struct wacom_features wacom_features_0x30 =
1339        { "Wacom PL400",          WACOM_PKGLEN_GRAPHIRE,   5408,  4056,  255,
1340          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1341static const struct wacom_features wacom_features_0x31 =
1342        { "Wacom PL500",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  255,
1343          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1344static const struct wacom_features wacom_features_0x32 =
1345        { "Wacom PL600",          WACOM_PKGLEN_GRAPHIRE,   6126,  4604,  255,
1346          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1347static const struct wacom_features wacom_features_0x33 =
1348        { "Wacom PL600SX",        WACOM_PKGLEN_GRAPHIRE,   6260,  5016,  255,
1349          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1350static const struct wacom_features wacom_features_0x34 =
1351        { "Wacom PL550",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  511,
1352          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1353static const struct wacom_features wacom_features_0x35 =
1354        { "Wacom PL800",          WACOM_PKGLEN_GRAPHIRE,   7220,  5780,  511,
1355          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1356static const struct wacom_features wacom_features_0x37 =
1357        { "Wacom PL700",          WACOM_PKGLEN_GRAPHIRE,   6758,  5406,  511,
1358          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1359static const struct wacom_features wacom_features_0x38 =
1360        { "Wacom PL510",          WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,
1361          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1362static const struct wacom_features wacom_features_0x39 =
1363        { "Wacom DTU710",         WACOM_PKGLEN_GRAPHIRE,  34080, 27660,  511,
1364          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1365static const struct wacom_features wacom_features_0xC4 =
1366        { "Wacom DTF521",         WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,
1367          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1368static const struct wacom_features wacom_features_0xC0 =
1369        { "Wacom DTF720",         WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,
1370          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1371static const struct wacom_features wacom_features_0xC2 =
1372        { "Wacom DTF720a",        WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,
1373          0, PL, WACOM_PL_RES, WACOM_PL_RES };
1374static const struct wacom_features wacom_features_0x03 =
1375        { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE,  20480, 15360,  511,
1376          0, PTU, WACOM_PL_RES, WACOM_PL_RES };
1377static const struct wacom_features wacom_features_0x41 =
1378        { "Wacom Intuos2 4x5",    WACOM_PKGLEN_INTUOS,    12700, 10600, 1023,
1379          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1380static const struct wacom_features wacom_features_0x42 =
1381        { "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
1382          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1383static const struct wacom_features wacom_features_0x43 =
1384        { "Wacom Intuos2 9x12",   WACOM_PKGLEN_INTUOS,    30480, 24060, 1023,
1385          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1386static const struct wacom_features wacom_features_0x44 =
1387        { "Wacom Intuos2 12x12",  WACOM_PKGLEN_INTUOS,    30480, 31680, 1023,
1388          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1389static const struct wacom_features wacom_features_0x45 =
1390        { "Wacom Intuos2 12x18",  WACOM_PKGLEN_INTUOS,    45720, 31680, 1023,
1391          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1392static const struct wacom_features wacom_features_0xB0 =
1393        { "Wacom Intuos3 4x5",    WACOM_PKGLEN_INTUOS,    25400, 20320, 1023,
1394          63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1395static const struct wacom_features wacom_features_0xB1 =
1396        { "Wacom Intuos3 6x8",    WACOM_PKGLEN_INTUOS,    40640, 30480, 1023,
1397          63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1398static const struct wacom_features wacom_features_0xB2 =
1399        { "Wacom Intuos3 9x12",   WACOM_PKGLEN_INTUOS,    60960, 45720, 1023,
1400          63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1401static const struct wacom_features wacom_features_0xB3 =
1402        { "Wacom Intuos3 12x12",  WACOM_PKGLEN_INTUOS,    60960, 60960, 1023,
1403          63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1404static const struct wacom_features wacom_features_0xB4 =
1405        { "Wacom Intuos3 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 1023,
1406          63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1407static const struct wacom_features wacom_features_0xB5 =
1408        { "Wacom Intuos3 6x11",   WACOM_PKGLEN_INTUOS,    54204, 31750, 1023,
1409          63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1410static const struct wacom_features wacom_features_0xB7 =
1411        { "Wacom Intuos3 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 1023,
1412          63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1413static const struct wacom_features wacom_features_0xB8 =
1414        { "Wacom Intuos4 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 2047,
1415          63, INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1416static const struct wacom_features wacom_features_0xB9 =
1417        { "Wacom Intuos4 6x9",    WACOM_PKGLEN_INTUOS,    44704, 27940, 2047,
1418          63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1419static const struct wacom_features wacom_features_0xBA =
1420        { "Wacom Intuos4 8x13",   WACOM_PKGLEN_INTUOS,    65024, 40640, 2047,
1421          63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1422static const struct wacom_features wacom_features_0xBB =
1423        { "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047,
1424          63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1425static const struct wacom_features wacom_features_0xBC =
1426        { "Wacom Intuos4 WL",     WACOM_PKGLEN_INTUOS,    40840, 25400, 2047,
1427          63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1428static const struct wacom_features wacom_features_0x3F =
1429        { "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023,
1430          63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1431static const struct wacom_features wacom_features_0xC5 =
1432        { "Wacom Cintiq 20WSX",   WACOM_PKGLEN_INTUOS,    86680, 54180, 1023,
1433          63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1434static const struct wacom_features wacom_features_0xC6 =
1435        { "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023,
1436          63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1437static const struct wacom_features wacom_features_0xC7 =
1438        { "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,
1439          0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1440static const struct wacom_features wacom_features_0xCE =
1441        { "Wacom DTU2231",        WACOM_PKGLEN_GRAPHIRE,  47864, 27011,  511,
1442          0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1443static const struct wacom_features wacom_features_0xF0 =
1444        { "Wacom DTU1631",        WACOM_PKGLEN_GRAPHIRE,  34623, 19553,  511,
1445          0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1446static const struct wacom_features wacom_features_0xCC =
1447        { "Wacom Cintiq 21UX2",   WACOM_PKGLEN_INTUOS,    87200, 65600, 2047,
1448          63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
1449static const struct wacom_features wacom_features_0x90 =
1450        { "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
1451          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1452static const struct wacom_features wacom_features_0x93 =
1453        { "Wacom ISDv4 93",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
1454          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1455static const struct wacom_features wacom_features_0x97 =
1456        { "Wacom ISDv4 97",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  511,
1457          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1458static const struct wacom_features wacom_features_0x9A =
1459        { "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
1460          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1461static const struct wacom_features wacom_features_0x9F =
1462        { "Wacom ISDv4 9F",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
1463          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1464static const struct wacom_features wacom_features_0xE2 =
1465        { "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,
1466          0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1467static const struct wacom_features wacom_features_0xE3 =
1468        { "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,
1469          0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1470static const struct wacom_features wacom_features_0xE6 =
1471        { "Wacom ISDv4 E6",       WACOM_PKGLEN_TPC2FG,    27760, 15694,  255,
1472          0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1473static const struct wacom_features wacom_features_0xEC =
1474        { "Wacom ISDv4 EC",       WACOM_PKGLEN_GRAPHIRE,  25710, 14500,  255,
1475          0, TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1476static const struct wacom_features wacom_features_0x47 =
1477        { "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
1478          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1479static const struct wacom_features wacom_features_0xD0 =
1480        { "Wacom Bamboo 2FG",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
1481          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1482static const struct wacom_features wacom_features_0xD1 =
1483        { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
1484          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1485static const struct wacom_features wacom_features_0xD2 =
1486        { "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
1487          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1488static const struct wacom_features wacom_features_0xD3 =
1489        { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13700, 1023,
1490          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1491static const struct wacom_features wacom_features_0xD4 =
1492        { "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
1493          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1494static const struct wacom_features wacom_features_0xD5 =
1495        { "Wacom Bamboo Pen 6x8",     WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
1496          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1497static const struct wacom_features wacom_features_0xD6 =
1498        { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN,   14720,  9200, 1023,
1499          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1500static const struct wacom_features wacom_features_0xD7 =
1501        { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720,  9200, 1023,
1502          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1503static const struct wacom_features wacom_features_0xD8 =
1504        { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13700, 1023,
1505          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1506static const struct wacom_features wacom_features_0xDA =
1507        { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN,  14720,  9200, 1023,
1508          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1509static struct wacom_features wacom_features_0xDB =
1510        { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN,  21648, 13700, 1023,
1511          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1512static const struct wacom_features wacom_features_0x6004 =
1513        { "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
1514          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1515
1516#define USB_DEVICE_WACOM(prod)                                  \
1517        USB_DEVICE(USB_VENDOR_ID_WACOM, prod),                  \
1518        .driver_info = (kernel_ulong_t)&wacom_features_##prod
1519
1520#define USB_DEVICE_DETAILED(prod, class, sub, proto)                    \
1521        USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_WACOM, prod, class, \
1522                                      sub, proto),                      \
1523        .driver_info = (kernel_ulong_t)&wacom_features_##prod
1524
1525#define USB_DEVICE_LENOVO(prod)                                 \
1526        USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),                 \
1527        .driver_info = (kernel_ulong_t)&wacom_features_##prod
1528
1529const struct usb_device_id wacom_ids[] = {
1530        { USB_DEVICE_WACOM(0x00) },
1531        { USB_DEVICE_WACOM(0x10) },
1532        { USB_DEVICE_WACOM(0x11) },
1533        { USB_DEVICE_WACOM(0x12) },
1534        { USB_DEVICE_WACOM(0x13) },
1535        { USB_DEVICE_WACOM(0x14) },
1536        { USB_DEVICE_WACOM(0x15) },
1537        { USB_DEVICE_WACOM(0x16) },
1538        { USB_DEVICE_WACOM(0x17) },
1539        { USB_DEVICE_WACOM(0x18) },
1540        { USB_DEVICE_WACOM(0x19) },
1541        { USB_DEVICE_WACOM(0x60) },
1542        { USB_DEVICE_WACOM(0x61) },
1543        { USB_DEVICE_WACOM(0x62) },
1544        { USB_DEVICE_WACOM(0x63) },
1545        { USB_DEVICE_WACOM(0x64) },
1546        { USB_DEVICE_WACOM(0x65) },
1547        { USB_DEVICE_WACOM(0x69) },
1548        { USB_DEVICE_WACOM(0x6A) },
1549        { USB_DEVICE_WACOM(0x6B) },
1550        { USB_DEVICE_WACOM(0x20) },
1551        { USB_DEVICE_WACOM(0x21) },
1552        { USB_DEVICE_WACOM(0x22) },
1553        { USB_DEVICE_WACOM(0x23) },
1554        { USB_DEVICE_WACOM(0x24) },
1555        { USB_DEVICE_WACOM(0x30) },
1556        { USB_DEVICE_WACOM(0x31) },
1557        { USB_DEVICE_WACOM(0x32) },
1558        { USB_DEVICE_WACOM(0x33) },
1559        { USB_DEVICE_WACOM(0x34) },
1560        { USB_DEVICE_WACOM(0x35) },
1561        { USB_DEVICE_WACOM(0x37) },
1562        { USB_DEVICE_WACOM(0x38) },
1563        { USB_DEVICE_WACOM(0x39) },
1564        { USB_DEVICE_WACOM(0xC4) },
1565        { USB_DEVICE_WACOM(0xC0) },
1566        { USB_DEVICE_WACOM(0xC2) },
1567        { USB_DEVICE_WACOM(0x03) },
1568        { USB_DEVICE_WACOM(0x41) },
1569        { USB_DEVICE_WACOM(0x42) },
1570        { USB_DEVICE_WACOM(0x43) },
1571        { USB_DEVICE_WACOM(0x44) },
1572        { USB_DEVICE_WACOM(0x45) },
1573        { USB_DEVICE_WACOM(0xB0) },
1574        { USB_DEVICE_WACOM(0xB1) },
1575        { USB_DEVICE_WACOM(0xB2) },
1576        { USB_DEVICE_WACOM(0xB3) },
1577        { USB_DEVICE_WACOM(0xB4) },
1578        { USB_DEVICE_WACOM(0xB5) },
1579        { USB_DEVICE_WACOM(0xB7) },
1580        { USB_DEVICE_WACOM(0xB8) },
1581        { USB_DEVICE_WACOM(0xB9) },
1582        { USB_DEVICE_WACOM(0xBA) },
1583        { USB_DEVICE_WACOM(0xBB) },
1584        { USB_DEVICE_WACOM(0xBC) },
1585        { USB_DEVICE_WACOM(0x3F) },
1586        { USB_DEVICE_WACOM(0xC5) },
1587        { USB_DEVICE_WACOM(0xC6) },
1588        { USB_DEVICE_WACOM(0xC7) },
1589        /*
1590         * DTU-2231 has two interfaces on the same configuration,
1591         * only one is used.
1592         */
1593        { USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID,
1594                              USB_INTERFACE_SUBCLASS_BOOT,
1595                              USB_INTERFACE_PROTOCOL_MOUSE) },
1596        { USB_DEVICE_WACOM(0xD0) },
1597        { USB_DEVICE_WACOM(0xD1) },
1598        { USB_DEVICE_WACOM(0xD2) },
1599        { USB_DEVICE_WACOM(0xD3) },
1600        { USB_DEVICE_WACOM(0xD4) },
1601        { USB_DEVICE_WACOM(0xD5) },
1602        { USB_DEVICE_WACOM(0xD6) },
1603        { USB_DEVICE_WACOM(0xD7) },
1604        { USB_DEVICE_WACOM(0xD8) },
1605        { USB_DEVICE_WACOM(0xDA) },
1606        { USB_DEVICE_WACOM(0xDB) },
1607        { USB_DEVICE_WACOM(0xF0) },
1608        { USB_DEVICE_WACOM(0xCC) },
1609        { USB_DEVICE_WACOM(0x90) },
1610        { USB_DEVICE_WACOM(0x93) },
1611        { USB_DEVICE_WACOM(0x97) },
1612        { USB_DEVICE_WACOM(0x9A) },
1613        { USB_DEVICE_WACOM(0x9F) },
1614        { USB_DEVICE_WACOM(0xE2) },
1615        { USB_DEVICE_WACOM(0xE3) },
1616        { USB_DEVICE_WACOM(0xE6) },
1617        { USB_DEVICE_WACOM(0xEC) },
1618        { USB_DEVICE_WACOM(0x47) },
1619        { USB_DEVICE_LENOVO(0x6004) },
1620        { }
1621};
1622MODULE_DEVICE_TABLE(usb, wacom_ids);
1623
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.