1/* 2 * HID driver for UC-Logic devices not fully compliant with HID standard 3 * 4 * Copyright (c) 2010 Nikolai Kondrashov 5 */ 6 7/* 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 */ 13 14#include <linux/device.h> 15#include <linux/hid.h> 16#include <linux/module.h> 17 18#include "hid-ids.h" 19 20/* 21 * The original descriptors of WPXXXXU tablets have three report IDs, of 22 * which only two are used (8 and 9), and the remaining (7) seems to have 23 * the originally intended pen description which was abandoned for some 24 * reason. From this unused description it is possible to extract the 25 * actual physical extents and resolution. All the models use the same 26 * descriptor with different extents for the unused report ID. 27 * 28 * Here it is: 29 * 30 * Usage Page (Digitizer), ; Digitizer (0Dh) 31 * Usage (Pen), ; Pen (02h, application collection) 32 * Collection (Application), 33 * Report ID (7), 34 * Usage (Stylus), ; Stylus (20h, logical collection) 35 * Collection (Physical), 36 * Usage (Tip Switch), ; Tip switch (42h, momentary control) 37 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control) 38 * Usage (Eraser), ; Eraser (45h, momentary control) 39 * Logical Minimum (0), 40 * Logical Maximum (1), 41 * Report Size (1), 42 * Report Count (3), 43 * Input (Variable), 44 * Report Count (3), 45 * Input (Constant, Variable), 46 * Usage (In Range), ; In range (32h, momentary control) 47 * Report Count (1), 48 * Input (Variable), 49 * Report Count (1), 50 * Input (Constant, Variable), 51 * Usage Page (Desktop), ; Generic desktop controls (01h) 52 * Usage (X), ; X (30h, dynamic value) 53 * Report Size (16), 54 * Report Count (1), 55 * Push, 56 * Unit Exponent (13), 57 * Unit (Inch^3), 58 * Physical Minimum (0), 59 * Physical Maximum (Xpm), 60 * Logical Maximum (Xlm), 61 * Input (Variable), 62 * Usage (Y), ; Y (31h, dynamic value) 63 * Physical Maximum (Ypm), 64 * Logical Maximum (Ylm), 65 * Input (Variable), 66 * Pop, 67 * Usage Page (Digitizer), ; Digitizer (0Dh) 68 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value) 69 * Logical Maximum (1023), 70 * Input (Variable), 71 * Report Size (16), 72 * End Collection, 73 * End Collection, 74 * Usage Page (Desktop), ; Generic desktop controls (01h) 75 * Usage (Mouse), ; Mouse (02h, application collection) 76 * Collection (Application), 77 * Report ID (8), 78 * Usage (Pointer), ; Pointer (01h, physical collection) 79 * Collection (Physical), 80 * Usage Page (Button), ; Button (09h) 81 * Usage Minimum (01h), 82 * Usage Maximum (03h), 83 * Logical Minimum (0), 84 * Logical Maximum (1), 85 * Report Count (3), 86 * Report Size (1), 87 * Input (Variable), 88 * Report Count (5), 89 * Input (Constant), 90 * Usage Page (Desktop), ; Generic desktop controls (01h) 91 * Usage (X), ; X (30h, dynamic value) 92 * Usage (Y), ; Y (31h, dynamic value) 93 * Usage (Wheel), ; Wheel (38h, dynamic value) 94 * Usage (00h), 95 * Logical Minimum (-127), 96 * Logical Maximum (127), 97 * Report Size (8), 98 * Report Count (4), 99 * Input (Variable, Relative), 100 * End Collection, 101 * End Collection, 102 * Usage Page (Desktop), ; Generic desktop controls (01h) 103 * Usage (Mouse), ; Mouse (02h, application collection) 104 * Collection (Application), 105 * Report ID (9), 106 * Usage (Pointer), ; Pointer (01h, physical collection) 107 * Collection (Physical), 108 * Usage Page (Button), ; Button (09h) 109 * Usage Minimum (01h), 110 * Usage Maximum (03h), 111 * Logical Minimum (0), 112 * Logical Maximum (1), 113 * Report Count (3), 114 * Report Size (1), 115 * Input (Variable), 116 * Report Count (5), 117 * Input (Constant), 118 * Usage Page (Desktop), ; Generic desktop controls (01h) 119 * Usage (X), ; X (30h, dynamic value) 120 * Usage (Y), ; Y (31h, dynamic value) 121 * Logical Minimum (0), 122 * Logical Maximum (32767), 123 * Physical Minimum (0), 124 * Physical Maximum (32767), 125 * Report Count (2), 126 * Report Size (16), 127 * Input (Variable), 128 * Usage Page (Digitizer), ; Digitizer (0Dh) 129 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value) 130 * Logical Maximum (1023), 131 * Report Count (1), 132 * Report Size (16), 133 * Input (Variable), 134 * End Collection, 135 * End Collection 136 * 137 * Here are the extents values for the WPXXXXU models: 138 * 139 * Xpm Xlm Ypm Ylm 140 * WP4030U 4000 8000 3000 6000 141 * WP5540U 5500 11000 4000 8000 142 * WP8060U 8000 16000 6000 12000 143 * 144 * This suggests that all of them have 2000 LPI resolution, as advertised. 145 */ 146 147/* Size of the original descriptor of WPXXXXU tablets */ 148#define WPXXXXU_RDESC_ORIG_SIZE 212 149 150/* 151 * Fixed WP4030U report descriptor. 152 * Although the hardware might actually support it, the mouse description 153 * has been removed, since there seems to be no devices having one and it 154 * wouldn't make much sense because of the working area size. 155 */ 156static __u8 wp4030u_rdesc_fixed[] = { 157 0x05, 0x0D, /* Usage Page (Digitizer), */ 158 0x09, 0x02, /* Usage (Pen), */ 159 0xA1, 0x01, /* Collection (Application), */ 160 0x85, 0x09, /* Report ID (9), */ 161 0x09, 0x20, /* Usage (Stylus), */ 162 0xA0, /* Collection (Physical), */ 163 0x75, 0x01, /* Report Size (1), */ 164 0x09, 0x42, /* Usage (Tip Switch), */ 165 0x09, 0x44, /* Usage (Barrel Switch), */ 166 0x09, 0x46, /* Usage (Tablet Pick), */ 167 0x14, /* Logical Minimum (0), */ 168 0x25, 0x01, /* Logical Maximum (1), */ 169 0x95, 0x03, /* Report Count (3), */ 170 0x81, 0x02, /* Input (Variable), */ 171 0x95, 0x05, /* Report Count (5), */ 172 0x81, 0x01, /* Input (Constant), */ 173 0x75, 0x10, /* Report Size (16), */ 174 0x95, 0x01, /* Report Count (1), */ 175 0x14, /* Logical Minimum (0), */ 176 0xA4, /* Push, */ 177 0x05, 0x01, /* Usage Page (Desktop), */ 178 0x55, 0xFD, /* Unit Exponent (-3), */ 179 0x65, 0x13, /* Unit (Inch), */ 180 0x34, /* Physical Minimum (0), */ 181 0x09, 0x30, /* Usage (X), */ 182 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 183 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 184 0x81, 0x02, /* Input (Variable), */ 185 0x09, 0x31, /* Usage (Y), */ 186 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */ 187 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 188 0x81, 0x02, /* Input (Variable), */ 189 0xB4, /* Pop, */ 190 0x09, 0x30, /* Usage (Tip Pressure), */ 191 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 192 0x81, 0x02, /* Input (Variable), */ 193 0xC0, /* End Collection, */ 194 0xC0 /* End Collection */ 195}; 196 197/* Fixed WP5540U report descriptor */ 198static __u8 wp5540u_rdesc_fixed[] = { 199 0x05, 0x0D, /* Usage Page (Digitizer), */ 200 0x09, 0x02, /* Usage (Pen), */ 201 0xA1, 0x01, /* Collection (Application), */ 202 0x85, 0x09, /* Report ID (9), */ 203 0x09, 0x20, /* Usage (Stylus), */ 204 0xA0, /* Collection (Physical), */ 205 0x75, 0x01, /* Report Size (1), */ 206 0x09, 0x42, /* Usage (Tip Switch), */ 207 0x09, 0x44, /* Usage (Barrel Switch), */ 208 0x09, 0x46, /* Usage (Tablet Pick), */ 209 0x14, /* Logical Minimum (0), */ 210 0x25, 0x01, /* Logical Maximum (1), */ 211 0x95, 0x03, /* Report Count (3), */ 212 0x81, 0x02, /* Input (Variable), */ 213 0x95, 0x05, /* Report Count (5), */ 214 0x81, 0x01, /* Input (Constant), */ 215 0x75, 0x10, /* Report Size (16), */ 216 0x95, 0x01, /* Report Count (1), */ 217 0x14, /* Logical Minimum (0), */ 218 0xA4, /* Push, */ 219 0x05, 0x01, /* Usage Page (Desktop), */ 220 0x55, 0xFD, /* Unit Exponent (-3), */ 221 0x65, 0x13, /* Unit (Inch), */ 222 0x34, /* Physical Minimum (0), */ 223 0x09, 0x30, /* Usage (X), */ 224 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ 225 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 226 0x81, 0x02, /* Input (Variable), */ 227 0x09, 0x31, /* Usage (Y), */ 228 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ 229 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 230 0x81, 0x02, /* Input (Variable), */ 231 0xB4, /* Pop, */ 232 0x09, 0x30, /* Usage (Tip Pressure), */ 233 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 234 0x81, 0x02, /* Input (Variable), */ 235 0xC0, /* End Collection, */ 236 0xC0, /* End Collection, */ 237 0x05, 0x01, /* Usage Page (Desktop), */ 238 0x09, 0x02, /* Usage (Mouse), */ 239 0xA1, 0x01, /* Collection (Application), */ 240 0x85, 0x08, /* Report ID (8), */ 241 0x09, 0x01, /* Usage (Pointer), */ 242 0xA0, /* Collection (Physical), */ 243 0x75, 0x01, /* Report Size (1), */ 244 0x05, 0x09, /* Usage Page (Button), */ 245 0x19, 0x01, /* Usage Minimum (01h), */ 246 0x29, 0x03, /* Usage Maximum (03h), */ 247 0x14, /* Logical Minimum (0), */ 248 0x25, 0x01, /* Logical Maximum (1), */ 249 0x95, 0x03, /* Report Count (3), */ 250 0x81, 0x02, /* Input (Variable), */ 251 0x95, 0x05, /* Report Count (5), */ 252 0x81, 0x01, /* Input (Constant), */ 253 0x05, 0x01, /* Usage Page (Desktop), */ 254 0x75, 0x08, /* Report Size (8), */ 255 0x09, 0x30, /* Usage (X), */ 256 0x09, 0x31, /* Usage (Y), */ 257 0x15, 0x81, /* Logical Minimum (-127), */ 258 0x25, 0x7F, /* Logical Maximum (127), */ 259 0x95, 0x02, /* Report Count (2), */ 260 0x81, 0x06, /* Input (Variable, Relative), */ 261 0x09, 0x38, /* Usage (Wheel), */ 262 0x15, 0xFF, /* Logical Minimum (-1), */ 263 0x25, 0x01, /* Logical Maximum (1), */ 264 0x95, 0x01, /* Report Count (1), */ 265 0x81, 0x06, /* Input (Variable, Relative), */ 266 0x81, 0x01, /* Input (Constant), */ 267 0xC0, /* End Collection, */ 268 0xC0 /* End Collection */ 269}; 270 271/* Fixed WP8060U report descriptor */ 272static __u8 wp8060u_rdesc_fixed[] = { 273 0x05, 0x0D, /* Usage Page (Digitizer), */ 274 0x09, 0x02, /* Usage (Pen), */ 275 0xA1, 0x01, /* Collection (Application), */ 276 0x85, 0x09, /* Report ID (9), */ 277 0x09, 0x20, /* Usage (Stylus), */ 278 0xA0, /* Collection (Physical), */ 279 0x75, 0x01, /* Report Size (1), */ 280 0x09, 0x42, /* Usage (Tip Switch), */ 281 0x09, 0x44, /* Usage (Barrel Switch), */ 282 0x09, 0x46, /* Usage (Tablet Pick), */ 283 0x14, /* Logical Minimum (0), */ 284 0x25, 0x01, /* Logical Maximum (1), */ 285 0x95, 0x03, /* Report Count (3), */ 286 0x81, 0x02, /* Input (Variable), */ 287 0x95, 0x05, /* Report Count (5), */ 288 0x81, 0x01, /* Input (Constant), */ 289 0x75, 0x10, /* Report Size (16), */ 290 0x95, 0x01, /* Report Count (1), */ 291 0x14, /* Logical Minimum (0), */ 292 0xA4, /* Push, */ 293 0x05, 0x01, /* Usage Page (Desktop), */ 294 0x55, 0xFD, /* Unit Exponent (-3), */ 295 0x65, 0x13, /* Unit (Inch), */ 296 0x34, /* Physical Minimum (0), */ 297 0x09, 0x30, /* Usage (X), */ 298 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 299 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 300 0x81, 0x02, /* Input (Variable), */ 301 0x09, 0x31, /* Usage (Y), */ 302 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 303 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 304 0x81, 0x02, /* Input (Variable), */ 305 0xB4, /* Pop, */ 306 0x09, 0x30, /* Usage (Tip Pressure), */ 307 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 308 0x81, 0x02, /* Input (Variable), */ 309 0xC0, /* End Collection, */ 310 0xC0, /* End Collection, */ 311 0x05, 0x01, /* Usage Page (Desktop), */ 312 0x09, 0x02, /* Usage (Mouse), */ 313 0xA1, 0x01, /* Collection (Application), */ 314 0x85, 0x08, /* Report ID (8), */ 315 0x09, 0x01, /* Usage (Pointer), */ 316 0xA0, /* Collection (Physical), */ 317 0x75, 0x01, /* Report Size (1), */ 318 0x05, 0x09, /* Usage Page (Button), */ 319 0x19, 0x01, /* Usage Minimum (01h), */ 320 0x29, 0x03, /* Usage Maximum (03h), */ 321 0x14, /* Logical Minimum (0), */ 322 0x25, 0x01, /* Logical Maximum (1), */ 323 0x95, 0x03, /* Report Count (3), */ 324 0x81, 0x02, /* Input (Variable), */ 325 0x95, 0x05, /* Report Count (5), */ 326 0x81, 0x01, /* Input (Constant), */ 327 0x05, 0x01, /* Usage Page (Desktop), */ 328 0x75, 0x08, /* Report Size (8), */ 329 0x09, 0x30, /* Usage (X), */ 330 0x09, 0x31, /* Usage (Y), */ 331 0x15, 0x81, /* Logical Minimum (-127), */ 332 0x25, 0x7F, /* Logical Maximum (127), */ 333 0x95, 0x02, /* Report Count (2), */ 334 0x81, 0x06, /* Input (Variable, Relative), */ 335 0x09, 0x38, /* Usage (Wheel), */ 336 0x15, 0xFF, /* Logical Minimum (-1), */ 337 0x25, 0x01, /* Logical Maximum (1), */ 338 0x95, 0x01, /* Report Count (1), */ 339 0x81, 0x06, /* Input (Variable, Relative), */ 340 0x81, 0x01, /* Input (Constant), */ 341 0xC0, /* End Collection, */ 342 0xC0 /* End Collection */ 343}; 344 345/* 346 * Original PF1209 report descriptor. 347 * 348 * The descriptor is similar to WPXXXXU descriptors, with an addition of a 349 * feature report (ID 4) of unknown purpose. 350 * 351 * Although the advertised resolution is 4000 LPI the unused report ID 352 * (taken from WPXXXXU, it seems) states 2000 LPI, but it is probably 353 * incorrect and is a result of blind copying without understanding. Anyway 354 * the real logical extents are always scaled to 0..32767, which IMHO spoils 355 * the precision. 356 * 357 * Usage Page (Digitizer), ; Digitizer (0Dh) 358 * Usage (Pen), ; Pen (02h, application collection) 359 * Collection (Application), 360 * Report ID (7), 361 * Usage (Stylus), ; Stylus (20h, logical collection) 362 * Collection (Physical), 363 * Usage (Tip Switch), ; Tip switch (42h, momentary control) 364 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control) 365 * Usage (Eraser), ; Eraser (45h, momentary control) 366 * Logical Minimum (0), 367 * Logical Maximum (1), 368 * Report Size (1), 369 * Report Count (3), 370 * Input (Variable), 371 * Report Count (3), 372 * Input (Constant, Variable), 373 * Usage (In Range), ; In range (32h, momentary control) 374 * Report Count (1), 375 * Input (Variable), 376 * Report Count (1), 377 * Input (Constant, Variable), 378 * Usage Page (Desktop), ; Generic desktop controls (01h) 379 * Usage (X), ; X (30h, dynamic value) 380 * Report Size (16), 381 * Report Count (1), 382 * Push, 383 * Unit Exponent (13), 384 * Unit (Inch^3), 385 * Physical Minimum (0), 386 * Physical Maximum (12000), 387 * Logical Maximum (24000), 388 * Input (Variable), 389 * Usage (Y), ; Y (31h, dynamic value) 390 * Physical Maximum (9000), 391 * Logical Maximum (18000), 392 * Input (Variable), 393 * Pop, 394 * Usage Page (Digitizer), ; Digitizer (0Dh) 395 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value) 396 * Logical Maximum (1023), 397 * Input (Variable), 398 * Report Size (16), 399 * End Collection, 400 * End Collection, 401 * Usage Page (Desktop), ; Generic desktop controls (01h) 402 * Usage (Mouse), ; Mouse (02h, application collection) 403 * Collection (Application), 404 * Report ID (8), 405 * Usage (Pointer), ; Pointer (01h, physical collection) 406 * Collection (Physical), 407 * Usage Page (Button), ; Button (09h) 408 * Usage Minimum (01h), 409 * Usage Maximum (03h), 410 * Logical Minimum (0), 411 * Logical Maximum (1), 412 * Report Count (3), 413 * Report Size (1), 414 * Input (Variable), 415 * Report Count (5), 416 * Input (Constant), 417 * Usage Page (Desktop), ; Generic desktop controls (01h) 418 * Usage (X), ; X (30h, dynamic value) 419 * Usage (Y), ; Y (31h, dynamic value) 420 * Usage (Wheel), ; Wheel (38h, dynamic value) 421 * Usage (00h), 422 * Logical Minimum (-127), 423 * Logical Maximum (127), 424 * Report Size (8), 425 * Report Count (4), 426 * Input (Variable, Relative), 427 * End Collection, 428 * End Collection, 429 * Usage Page (Desktop), ; Generic desktop controls (01h) 430 * Usage (Mouse), ; Mouse (02h, application collection) 431 * Collection (Application), 432 * Report ID (9), 433 * Usage (Pointer), ; Pointer (01h, physical collection) 434 * Collection (Physical), 435 * Usage Page (Button), ; Button (09h) 436 * Usage Minimum (01h), 437 * Usage Maximum (03h), 438 * Logical Minimum (0), 439 * Logical Maximum (1), 440 * Report Count (3), 441 * Report Size (1), 442 * Input (Variable), 443 * Report Count (5), 444 * Input (Constant), 445 * Usage Page (Desktop), ; Generic desktop controls (01h) 446 * Usage (X), ; X (30h, dynamic value) 447 * Usage (Y), ; Y (31h, dynamic value) 448 * Logical Minimum (0), 449 * Logical Maximum (32767), 450 * Physical Minimum (0), 451 * Physical Maximum (32767), 452 * Report Count (2), 453 * Report Size (16), 454 * Input (Variable), 455 * Usage Page (Digitizer), ; Digitizer (0Dh) 456 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value) 457 * Logical Maximum (1023), 458 * Report Count (1), 459 * Report Size (16), 460 * Input (Variable), 461 * End Collection, 462 * End Collection, 463 * Usage Page (Desktop), ; Generic desktop controls (01h) 464 * Usage (00h), 465 * Collection (Application), 466 * Report ID (4), 467 * Logical Minimum (0), 468 * Logical Maximum (255), 469 * Usage (00h), 470 * Report Size (8), 471 * Report Count (3), 472 * Feature (Variable), 473 * End Collection 474 */ 475 476/* Size of the original descriptor of PF1209 tablet */ 477#define PF1209_RDESC_ORIG_SIZE 234 478 479/* 480 * Fixed PF1209 report descriptor 481 * 482 * The descriptor is fixed similarly to WP5540U and WP8060U, plus the 483 * feature report is removed, because its purpose is unknown and it is of no 484 * use to the generic HID driver anyway for now. 485 */ 486static __u8 pf1209_rdesc_fixed[] = { 487 0x05, 0x0D, /* Usage Page (Digitizer), */ 488 0x09, 0x02, /* Usage (Pen), */ 489 0xA1, 0x01, /* Collection (Application), */ 490 0x85, 0x09, /* Report ID (9), */ 491 0x09, 0x20, /* Usage (Stylus), */ 492 0xA0, /* Collection (Physical), */ 493 0x75, 0x01, /* Report Size (1), */ 494 0x09, 0x42, /* Usage (Tip Switch), */ 495 0x09, 0x44, /* Usage (Barrel Switch), */ 496 0x09, 0x46, /* Usage (Tablet Pick), */ 497 0x14, /* Logical Minimum (0), */ 498 0x25, 0x01, /* Logical Maximum (1), */ 499 0x95, 0x03, /* Report Count (3), */ 500 0x81, 0x02, /* Input (Variable), */ 501 0x95, 0x05, /* Report Count (5), */ 502 0x81, 0x01, /* Input (Constant), */ 503 0x75, 0x10, /* Report Size (16), */ 504 0x95, 0x01, /* Report Count (1), */ 505 0x14, /* Logical Minimum (0), */ 506 0xA4, /* Push, */ 507 0x05, 0x01, /* Usage Page (Desktop), */ 508 0x55, 0xFD, /* Unit Exponent (-3), */ 509 0x65, 0x13, /* Unit (Inch), */ 510 0x34, /* Physical Minimum (0), */ 511 0x09, 0x30, /* Usage (X), */ 512 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 513 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 514 0x81, 0x02, /* Input (Variable), */ 515 0x09, 0x31, /* Usage (Y), */ 516 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 517 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ 518 0x81, 0x02, /* Input (Variable), */ 519 0xB4, /* Pop, */ 520 0x09, 0x30, /* Usage (Tip Pressure), */ 521 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 522 0x81, 0x02, /* Input (Variable), */ 523 0xC0, /* End Collection, */ 524 0xC0, /* End Collection, */ 525 0x05, 0x01, /* Usage Page (Desktop), */ 526 0x09, 0x02, /* Usage (Mouse), */ 527 0xA1, 0x01, /* Collection (Application), */ 528 0x85, 0x08, /* Report ID (8), */ 529 0x09, 0x01, /* Usage (Pointer), */ 530 0xA0, /* Collection (Physical), */ 531 0x75, 0x01, /* Report Size (1), */ 532 0x05, 0x09, /* Usage Page (Button), */ 533 0x19, 0x01, /* Usage Minimum (01h), */ 534 0x29, 0x03, /* Usage Maximum (03h), */ 535 0x14, /* Logical Minimum (0), */ 536 0x25, 0x01, /* Logical Maximum (1), */ 537 0x95, 0x03, /* Report Count (3), */ 538 0x81, 0x02, /* Input (Variable), */ 539 0x95, 0x05, /* Report Count (5), */ 540 0x81, 0x01, /* Input (Constant), */ 541 0x05, 0x01, /* Usage Page (Desktop), */ 542 0x75, 0x08, /* Report Size (8), */ 543 0x09, 0x30, /* Usage (X), */ 544 0x09, 0x31, /* Usage (Y), */ 545 0x15, 0x81, /* Logical Minimum (-127), */ 546 0x25, 0x7F, /* Logical Maximum (127), */ 547 0x95, 0x02, /* Report Count (2), */ 548 0x81, 0x06, /* Input (Variable, Relative), */ 549 0x09, 0x38, /* Usage (Wheel), */ 550 0x15, 0xFF, /* Logical Minimum (-1), */ 551 0x25, 0x01, /* Logical Maximum (1), */ 552 0x95, 0x01, /* Report Count (1), */ 553 0x81, 0x06, /* Input (Variable, Relative), */ 554 0x81, 0x01, /* Input (Constant), */ 555 0xC0, /* End Collection, */ 556 0xC0 /* End Collection */ 557}; 558 559static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, 560 unsigned int *rsize) 561{ 562 switch (hdev->product) { 563 case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209: 564 if (*rsize == PF1209_RDESC_ORIG_SIZE) { 565 rdesc = pf1209_rdesc_fixed; 566 *rsize = sizeof(pf1209_rdesc_fixed); 567 } 568 break; 569 case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U: 570 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) { 571 rdesc = wp4030u_rdesc_fixed; 572 *rsize = sizeof(wp4030u_rdesc_fixed); 573 } 574 break; 575 case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U: 576 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) { 577 rdesc = wp5540u_rdesc_fixed; 578 *rsize = sizeof(wp5540u_rdesc_fixed); 579 } 580 break; 581 case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U: 582 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) { 583 rdesc = wp8060u_rdesc_fixed; 584 *rsize = sizeof(wp8060u_rdesc_fixed); 585 } 586 break; 587 } 588 589 return rdesc; 590} 591 592static const struct hid_device_id uclogic_devices[] = { 593 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 594 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, 595 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 596 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, 597 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 598 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, 599 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 600 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, 601 { } 602}; 603MODULE_DEVICE_TABLE(hid, uclogic_devices); 604 605static struct hid_driver uclogic_driver = { 606 .name = "uclogic", 607 .id_table = uclogic_devices, 608 .report_fixup = uclogic_report_fixup, 609}; 610 611static int __init uclogic_init(void) 612{ 613 return hid_register_driver(&uclogic_driver); 614} 615 616static void __exit uclogic_exit(void) 617{ 618 hid_unregister_driver(&uclogic_driver); 619} 620 621module_init(uclogic_init); 622module_exit(uclogic_exit); 623MODULE_LICENSE("GPL"); 624