linux/drivers/hid/hid-uclogic.c
<<
>>
Prefs
   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#include <linux/usb.h>
  18
  19#include "hid-ids.h"
  20
  21/*
  22 * See WPXXXXU model descriptions, device and HID report descriptors at
  23 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP4030U
  24 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP5540U
  25 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP8060U
  26 */
  27
  28/* Size of the original descriptor of WPXXXXU tablets */
  29#define WPXXXXU_RDESC_ORIG_SIZE 212
  30
  31/* Fixed WP4030U report descriptor */
  32static __u8 wp4030u_rdesc_fixed[] = {
  33        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
  34        0x09, 0x02,         /*  Usage (Pen),                        */
  35        0xA1, 0x01,         /*  Collection (Application),           */
  36        0x85, 0x09,         /*      Report ID (9),                  */
  37        0x09, 0x20,         /*      Usage (Stylus),                 */
  38        0xA0,               /*      Collection (Physical),          */
  39        0x75, 0x01,         /*          Report Size (1),            */
  40        0x09, 0x42,         /*          Usage (Tip Switch),         */
  41        0x09, 0x44,         /*          Usage (Barrel Switch),      */
  42        0x09, 0x46,         /*          Usage (Tablet Pick),        */
  43        0x14,               /*          Logical Minimum (0),        */
  44        0x25, 0x01,         /*          Logical Maximum (1),        */
  45        0x95, 0x03,         /*          Report Count (3),           */
  46        0x81, 0x02,         /*          Input (Variable),           */
  47        0x95, 0x05,         /*          Report Count (5),           */
  48        0x81, 0x01,         /*          Input (Constant),           */
  49        0x75, 0x10,         /*          Report Size (16),           */
  50        0x95, 0x01,         /*          Report Count (1),           */
  51        0x14,               /*          Logical Minimum (0),        */
  52        0xA4,               /*          Push,                       */
  53        0x05, 0x01,         /*          Usage Page (Desktop),       */
  54        0x55, 0xFD,         /*          Unit Exponent (-3),         */
  55        0x65, 0x13,         /*          Unit (Inch),                */
  56        0x34,               /*          Physical Minimum (0),       */
  57        0x09, 0x30,         /*          Usage (X),                  */
  58        0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
  59        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  60        0x81, 0x02,         /*          Input (Variable),           */
  61        0x09, 0x31,         /*          Usage (Y),                  */
  62        0x46, 0xB8, 0x0B,   /*          Physical Maximum (3000),    */
  63        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  64        0x81, 0x02,         /*          Input (Variable),           */
  65        0xB4,               /*          Pop,                        */
  66        0x09, 0x30,         /*          Usage (Tip Pressure),       */
  67        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
  68        0x81, 0x02,         /*          Input (Variable),           */
  69        0xC0,               /*      End Collection,                 */
  70        0xC0                /*  End Collection                      */
  71};
  72
  73/* Fixed WP5540U report descriptor */
  74static __u8 wp5540u_rdesc_fixed[] = {
  75        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
  76        0x09, 0x02,         /*  Usage (Pen),                        */
  77        0xA1, 0x01,         /*  Collection (Application),           */
  78        0x85, 0x09,         /*      Report ID (9),                  */
  79        0x09, 0x20,         /*      Usage (Stylus),                 */
  80        0xA0,               /*      Collection (Physical),          */
  81        0x75, 0x01,         /*          Report Size (1),            */
  82        0x09, 0x42,         /*          Usage (Tip Switch),         */
  83        0x09, 0x44,         /*          Usage (Barrel Switch),      */
  84        0x09, 0x46,         /*          Usage (Tablet Pick),        */
  85        0x14,               /*          Logical Minimum (0),        */
  86        0x25, 0x01,         /*          Logical Maximum (1),        */
  87        0x95, 0x03,         /*          Report Count (3),           */
  88        0x81, 0x02,         /*          Input (Variable),           */
  89        0x95, 0x05,         /*          Report Count (5),           */
  90        0x81, 0x01,         /*          Input (Constant),           */
  91        0x75, 0x10,         /*          Report Size (16),           */
  92        0x95, 0x01,         /*          Report Count (1),           */
  93        0x14,               /*          Logical Minimum (0),        */
  94        0xA4,               /*          Push,                       */
  95        0x05, 0x01,         /*          Usage Page (Desktop),       */
  96        0x55, 0xFD,         /*          Unit Exponent (-3),         */
  97        0x65, 0x13,         /*          Unit (Inch),                */
  98        0x34,               /*          Physical Minimum (0),       */
  99        0x09, 0x30,         /*          Usage (X),                  */
 100        0x46, 0x7C, 0x15,   /*          Physical Maximum (5500),    */
 101        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 102        0x81, 0x02,         /*          Input (Variable),           */
 103        0x09, 0x31,         /*          Usage (Y),                  */
 104        0x46, 0xA0, 0x0F,   /*          Physical Maximum (4000),    */
 105        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 106        0x81, 0x02,         /*          Input (Variable),           */
 107        0xB4,               /*          Pop,                        */
 108        0x09, 0x30,         /*          Usage (Tip Pressure),       */
 109        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
 110        0x81, 0x02,         /*          Input (Variable),           */
 111        0xC0,               /*      End Collection,                 */
 112        0xC0,               /*  End Collection,                     */
 113        0x05, 0x01,         /*  Usage Page (Desktop),               */
 114        0x09, 0x02,         /*  Usage (Mouse),                      */
 115        0xA1, 0x01,         /*  Collection (Application),           */
 116        0x85, 0x08,         /*      Report ID (8),                  */
 117        0x09, 0x01,         /*      Usage (Pointer),                */
 118        0xA0,               /*      Collection (Physical),          */
 119        0x75, 0x01,         /*          Report Size (1),            */
 120        0x05, 0x09,         /*          Usage Page (Button),        */
 121        0x19, 0x01,         /*          Usage Minimum (01h),        */
 122        0x29, 0x03,         /*          Usage Maximum (03h),        */
 123        0x14,               /*          Logical Minimum (0),        */
 124        0x25, 0x01,         /*          Logical Maximum (1),        */
 125        0x95, 0x03,         /*          Report Count (3),           */
 126        0x81, 0x02,         /*          Input (Variable),           */
 127        0x95, 0x05,         /*          Report Count (5),           */
 128        0x81, 0x01,         /*          Input (Constant),           */
 129        0x05, 0x01,         /*          Usage Page (Desktop),       */
 130        0x75, 0x08,         /*          Report Size (8),            */
 131        0x09, 0x30,         /*          Usage (X),                  */
 132        0x09, 0x31,         /*          Usage (Y),                  */
 133        0x15, 0x81,         /*          Logical Minimum (-127),     */
 134        0x25, 0x7F,         /*          Logical Maximum (127),      */
 135        0x95, 0x02,         /*          Report Count (2),           */
 136        0x81, 0x06,         /*          Input (Variable, Relative), */
 137        0x09, 0x38,         /*          Usage (Wheel),              */
 138        0x15, 0xFF,         /*          Logical Minimum (-1),       */
 139        0x25, 0x01,         /*          Logical Maximum (1),        */
 140        0x95, 0x01,         /*          Report Count (1),           */
 141        0x81, 0x06,         /*          Input (Variable, Relative), */
 142        0x81, 0x01,         /*          Input (Constant),           */
 143        0xC0,               /*      End Collection,                 */
 144        0xC0                /*  End Collection                      */
 145};
 146
 147/* Fixed WP8060U report descriptor */
 148static __u8 wp8060u_rdesc_fixed[] = {
 149        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
 150        0x09, 0x02,         /*  Usage (Pen),                        */
 151        0xA1, 0x01,         /*  Collection (Application),           */
 152        0x85, 0x09,         /*      Report ID (9),                  */
 153        0x09, 0x20,         /*      Usage (Stylus),                 */
 154        0xA0,               /*      Collection (Physical),          */
 155        0x75, 0x01,         /*          Report Size (1),            */
 156        0x09, 0x42,         /*          Usage (Tip Switch),         */
 157        0x09, 0x44,         /*          Usage (Barrel Switch),      */
 158        0x09, 0x46,         /*          Usage (Tablet Pick),        */
 159        0x14,               /*          Logical Minimum (0),        */
 160        0x25, 0x01,         /*          Logical Maximum (1),        */
 161        0x95, 0x03,         /*          Report Count (3),           */
 162        0x81, 0x02,         /*          Input (Variable),           */
 163        0x95, 0x05,         /*          Report Count (5),           */
 164        0x81, 0x01,         /*          Input (Constant),           */
 165        0x75, 0x10,         /*          Report Size (16),           */
 166        0x95, 0x01,         /*          Report Count (1),           */
 167        0x14,               /*          Logical Minimum (0),        */
 168        0xA4,               /*          Push,                       */
 169        0x05, 0x01,         /*          Usage Page (Desktop),       */
 170        0x55, 0xFD,         /*          Unit Exponent (-3),         */
 171        0x65, 0x13,         /*          Unit (Inch),                */
 172        0x34,               /*          Physical Minimum (0),       */
 173        0x09, 0x30,         /*          Usage (X),                  */
 174        0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
 175        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 176        0x81, 0x02,         /*          Input (Variable),           */
 177        0x09, 0x31,         /*          Usage (Y),                  */
 178        0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */
 179        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 180        0x81, 0x02,         /*          Input (Variable),           */
 181        0xB4,               /*          Pop,                        */
 182        0x09, 0x30,         /*          Usage (Tip Pressure),       */
 183        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
 184        0x81, 0x02,         /*          Input (Variable),           */
 185        0xC0,               /*      End Collection,                 */
 186        0xC0,               /*  End Collection,                     */
 187        0x05, 0x01,         /*  Usage Page (Desktop),               */
 188        0x09, 0x02,         /*  Usage (Mouse),                      */
 189        0xA1, 0x01,         /*  Collection (Application),           */
 190        0x85, 0x08,         /*      Report ID (8),                  */
 191        0x09, 0x01,         /*      Usage (Pointer),                */
 192        0xA0,               /*      Collection (Physical),          */
 193        0x75, 0x01,         /*          Report Size (1),            */
 194        0x05, 0x09,         /*          Usage Page (Button),        */
 195        0x19, 0x01,         /*          Usage Minimum (01h),        */
 196        0x29, 0x03,         /*          Usage Maximum (03h),        */
 197        0x14,               /*          Logical Minimum (0),        */
 198        0x25, 0x01,         /*          Logical Maximum (1),        */
 199        0x95, 0x03,         /*          Report Count (3),           */
 200        0x81, 0x02,         /*          Input (Variable),           */
 201        0x95, 0x05,         /*          Report Count (5),           */
 202        0x81, 0x01,         /*          Input (Constant),           */
 203        0x05, 0x01,         /*          Usage Page (Desktop),       */
 204        0x75, 0x08,         /*          Report Size (8),            */
 205        0x09, 0x30,         /*          Usage (X),                  */
 206        0x09, 0x31,         /*          Usage (Y),                  */
 207        0x15, 0x81,         /*          Logical Minimum (-127),     */
 208        0x25, 0x7F,         /*          Logical Maximum (127),      */
 209        0x95, 0x02,         /*          Report Count (2),           */
 210        0x81, 0x06,         /*          Input (Variable, Relative), */
 211        0x09, 0x38,         /*          Usage (Wheel),              */
 212        0x15, 0xFF,         /*          Logical Minimum (-1),       */
 213        0x25, 0x01,         /*          Logical Maximum (1),        */
 214        0x95, 0x01,         /*          Report Count (1),           */
 215        0x81, 0x06,         /*          Input (Variable, Relative), */
 216        0x81, 0x01,         /*          Input (Constant),           */
 217        0xC0,               /*      End Collection,                 */
 218        0xC0                /*  End Collection                      */
 219};
 220
 221/*
 222 * See WP1062 description, device and HID report descriptors at
 223 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP1062
 224 */
 225
 226/* Size of the original descriptor of WP1062 tablet */
 227#define WP1062_RDESC_ORIG_SIZE  254
 228
 229/* Fixed WP1062 report descriptor */
 230static __u8 wp1062_rdesc_fixed[] = {
 231        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
 232        0x09, 0x02,         /*  Usage (Pen),                        */
 233        0xA1, 0x01,         /*  Collection (Application),           */
 234        0x85, 0x09,         /*      Report ID (9),                  */
 235        0x09, 0x20,         /*      Usage (Stylus),                 */
 236        0xA0,               /*      Collection (Physical),          */
 237        0x75, 0x01,         /*          Report Size (1),            */
 238        0x09, 0x42,         /*          Usage (Tip Switch),         */
 239        0x09, 0x44,         /*          Usage (Barrel Switch),      */
 240        0x09, 0x46,         /*          Usage (Tablet Pick),        */
 241        0x14,               /*          Logical Minimum (0),        */
 242        0x25, 0x01,         /*          Logical Maximum (1),        */
 243        0x95, 0x03,         /*          Report Count (3),           */
 244        0x81, 0x02,         /*          Input (Variable),           */
 245        0x95, 0x04,         /*          Report Count (4),           */
 246        0x81, 0x01,         /*          Input (Constant),           */
 247        0x09, 0x32,         /*          Usage (In Range),           */
 248        0x95, 0x01,         /*          Report Count (1),           */
 249        0x81, 0x02,         /*          Input (Variable),           */
 250        0x75, 0x10,         /*          Report Size (16),           */
 251        0x95, 0x01,         /*          Report Count (1),           */
 252        0x14,               /*          Logical Minimum (0),        */
 253        0xA4,               /*          Push,                       */
 254        0x05, 0x01,         /*          Usage Page (Desktop),       */
 255        0x55, 0xFD,         /*          Unit Exponent (-3),         */
 256        0x65, 0x13,         /*          Unit (Inch),                */
 257        0x34,               /*          Physical Minimum (0),       */
 258        0x09, 0x30,         /*          Usage (X),                  */
 259        0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */
 260        0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
 261        0x81, 0x02,         /*          Input (Variable),           */
 262        0x09, 0x31,         /*          Usage (Y),                  */
 263        0x46, 0xB7, 0x19,   /*          Physical Maximum (6583),    */
 264        0x26, 0x6E, 0x33,   /*          Logical Maximum (13166),    */
 265        0x81, 0x02,         /*          Input (Variable),           */
 266        0xB4,               /*          Pop,                        */
 267        0x09, 0x30,         /*          Usage (Tip Pressure),       */
 268        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
 269        0x81, 0x02,         /*          Input (Variable),           */
 270        0xC0,               /*      End Collection,                 */
 271        0xC0                /*  End Collection                      */
 272};
 273
 274/*
 275 * See PF1209 description, device and HID report descriptors at
 276 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_PF1209
 277 */
 278
 279/* Size of the original descriptor of PF1209 tablet */
 280#define PF1209_RDESC_ORIG_SIZE  234
 281
 282/* Fixed PF1209 report descriptor */
 283static __u8 pf1209_rdesc_fixed[] = {
 284        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
 285        0x09, 0x02,         /*  Usage (Pen),                        */
 286        0xA1, 0x01,         /*  Collection (Application),           */
 287        0x85, 0x09,         /*      Report ID (9),                  */
 288        0x09, 0x20,         /*      Usage (Stylus),                 */
 289        0xA0,               /*      Collection (Physical),          */
 290        0x75, 0x01,         /*          Report Size (1),            */
 291        0x09, 0x42,         /*          Usage (Tip Switch),         */
 292        0x09, 0x44,         /*          Usage (Barrel Switch),      */
 293        0x09, 0x46,         /*          Usage (Tablet Pick),        */
 294        0x14,               /*          Logical Minimum (0),        */
 295        0x25, 0x01,         /*          Logical Maximum (1),        */
 296        0x95, 0x03,         /*          Report Count (3),           */
 297        0x81, 0x02,         /*          Input (Variable),           */
 298        0x95, 0x05,         /*          Report Count (5),           */
 299        0x81, 0x01,         /*          Input (Constant),           */
 300        0x75, 0x10,         /*          Report Size (16),           */
 301        0x95, 0x01,         /*          Report Count (1),           */
 302        0x14,               /*          Logical Minimum (0),        */
 303        0xA4,               /*          Push,                       */
 304        0x05, 0x01,         /*          Usage Page (Desktop),       */
 305        0x55, 0xFD,         /*          Unit Exponent (-3),         */
 306        0x65, 0x13,         /*          Unit (Inch),                */
 307        0x34,               /*          Physical Minimum (0),       */
 308        0x09, 0x30,         /*          Usage (X),                  */
 309        0x46, 0xE0, 0x2E,   /*          Physical Maximum (12000),   */
 310        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 311        0x81, 0x02,         /*          Input (Variable),           */
 312        0x09, 0x31,         /*          Usage (Y),                  */
 313        0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */
 314        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 315        0x81, 0x02,         /*          Input (Variable),           */
 316        0xB4,               /*          Pop,                        */
 317        0x09, 0x30,         /*          Usage (Tip Pressure),       */
 318        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
 319        0x81, 0x02,         /*          Input (Variable),           */
 320        0xC0,               /*      End Collection,                 */
 321        0xC0,               /*  End Collection,                     */
 322        0x05, 0x01,         /*  Usage Page (Desktop),               */
 323        0x09, 0x02,         /*  Usage (Mouse),                      */
 324        0xA1, 0x01,         /*  Collection (Application),           */
 325        0x85, 0x08,         /*      Report ID (8),                  */
 326        0x09, 0x01,         /*      Usage (Pointer),                */
 327        0xA0,               /*      Collection (Physical),          */
 328        0x75, 0x01,         /*          Report Size (1),            */
 329        0x05, 0x09,         /*          Usage Page (Button),        */
 330        0x19, 0x01,         /*          Usage Minimum (01h),        */
 331        0x29, 0x03,         /*          Usage Maximum (03h),        */
 332        0x14,               /*          Logical Minimum (0),        */
 333        0x25, 0x01,         /*          Logical Maximum (1),        */
 334        0x95, 0x03,         /*          Report Count (3),           */
 335        0x81, 0x02,         /*          Input (Variable),           */
 336        0x95, 0x05,         /*          Report Count (5),           */
 337        0x81, 0x01,         /*          Input (Constant),           */
 338        0x05, 0x01,         /*          Usage Page (Desktop),       */
 339        0x75, 0x08,         /*          Report Size (8),            */
 340        0x09, 0x30,         /*          Usage (X),                  */
 341        0x09, 0x31,         /*          Usage (Y),                  */
 342        0x15, 0x81,         /*          Logical Minimum (-127),     */
 343        0x25, 0x7F,         /*          Logical Maximum (127),      */
 344        0x95, 0x02,         /*          Report Count (2),           */
 345        0x81, 0x06,         /*          Input (Variable, Relative), */
 346        0x09, 0x38,         /*          Usage (Wheel),              */
 347        0x15, 0xFF,         /*          Logical Minimum (-1),       */
 348        0x25, 0x01,         /*          Logical Maximum (1),        */
 349        0x95, 0x01,         /*          Report Count (1),           */
 350        0x81, 0x06,         /*          Input (Variable, Relative), */
 351        0x81, 0x01,         /*          Input (Constant),           */
 352        0xC0,               /*      End Collection,                 */
 353        0xC0                /*  End Collection                      */
 354};
 355
 356/*
 357 * See TWHL850 description, device and HID report descriptors at
 358 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Wireless_Tablet_TWHL850
 359 */
 360
 361/* Size of the original descriptors of TWHL850 tablet */
 362#define TWHL850_RDESC_ORIG_SIZE0        182
 363#define TWHL850_RDESC_ORIG_SIZE1        161
 364#define TWHL850_RDESC_ORIG_SIZE2        92
 365
 366/* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
 367static __u8 twhl850_rdesc_fixed0[] = {
 368        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
 369        0x09, 0x02,         /*  Usage (Pen),                        */
 370        0xA1, 0x01,         /*  Collection (Application),           */
 371        0x85, 0x09,         /*      Report ID (9),                  */
 372        0x09, 0x20,         /*      Usage (Stylus),                 */
 373        0xA0,               /*      Collection (Physical),          */
 374        0x14,               /*          Logical Minimum (0),        */
 375        0x25, 0x01,         /*          Logical Maximum (1),        */
 376        0x75, 0x01,         /*          Report Size (1),            */
 377        0x95, 0x03,         /*          Report Count (3),           */
 378        0x09, 0x42,         /*          Usage (Tip Switch),         */
 379        0x09, 0x44,         /*          Usage (Barrel Switch),      */
 380        0x09, 0x46,         /*          Usage (Tablet Pick),        */
 381        0x81, 0x02,         /*          Input (Variable),           */
 382        0x81, 0x03,         /*          Input (Constant, Variable), */
 383        0x95, 0x01,         /*          Report Count (1),           */
 384        0x09, 0x32,         /*          Usage (In Range),           */
 385        0x81, 0x02,         /*          Input (Variable),           */
 386        0x81, 0x03,         /*          Input (Constant, Variable), */
 387        0x75, 0x10,         /*          Report Size (16),           */
 388        0xA4,               /*          Push,                       */
 389        0x05, 0x01,         /*          Usage Page (Desktop),       */
 390        0x65, 0x13,         /*          Unit (Inch),                */
 391        0x55, 0xFD,         /*          Unit Exponent (-3),         */
 392        0x34,               /*          Physical Minimum (0),       */
 393        0x09, 0x30,         /*          Usage (X),                  */
 394        0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
 395        0x26, 0x00, 0x7D,   /*          Logical Maximum (32000),    */
 396        0x81, 0x02,         /*          Input (Variable),           */
 397        0x09, 0x31,         /*          Usage (Y),                  */
 398        0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */
 399        0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
 400        0x81, 0x02,         /*          Input (Variable),           */
 401        0xB4,               /*          Pop,                        */
 402        0x09, 0x30,         /*          Usage (Tip Pressure),       */
 403        0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
 404        0x81, 0x02,         /*          Input (Variable),           */
 405        0xC0,               /*      End Collection,                 */
 406        0xC0                /*  End Collection                      */
 407};
 408
 409/* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */
 410static __u8 twhl850_rdesc_fixed1[] = {
 411        0x05, 0x01,         /*  Usage Page (Desktop),               */
 412        0x09, 0x02,         /*  Usage (Mouse),                      */
 413        0xA1, 0x01,         /*  Collection (Application),           */
 414        0x85, 0x01,         /*      Report ID (1),                  */
 415        0x09, 0x01,         /*      Usage (Pointer),                */
 416        0xA0,               /*      Collection (Physical),          */
 417        0x05, 0x09,         /*          Usage Page (Button),        */
 418        0x75, 0x01,         /*          Report Size (1),            */
 419        0x95, 0x03,         /*          Report Count (3),           */
 420        0x19, 0x01,         /*          Usage Minimum (01h),        */
 421        0x29, 0x03,         /*          Usage Maximum (03h),        */
 422        0x14,               /*          Logical Minimum (0),        */
 423        0x25, 0x01,         /*          Logical Maximum (1),        */
 424        0x81, 0x02,         /*          Input (Variable),           */
 425        0x95, 0x05,         /*          Report Count (5),           */
 426        0x81, 0x03,         /*          Input (Constant, Variable), */
 427        0x05, 0x01,         /*          Usage Page (Desktop),       */
 428        0x09, 0x30,         /*          Usage (X),                  */
 429        0x09, 0x31,         /*          Usage (Y),                  */
 430        0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),   */
 431        0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
 432        0x75, 0x10,         /*          Report Size (16),           */
 433        0x95, 0x02,         /*          Report Count (2),           */
 434        0x81, 0x06,         /*          Input (Variable, Relative), */
 435        0x09, 0x38,         /*          Usage (Wheel),              */
 436        0x15, 0xFF,         /*          Logical Minimum (-1),       */
 437        0x25, 0x01,         /*          Logical Maximum (1),        */
 438        0x95, 0x01,         /*          Report Count (1),           */
 439        0x75, 0x08,         /*          Report Size (8),            */
 440        0x81, 0x06,         /*          Input (Variable, Relative), */
 441        0x81, 0x03,         /*          Input (Constant, Variable), */
 442        0xC0,               /*      End Collection,                 */
 443        0xC0                /*  End Collection                      */
 444};
 445
 446/* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */
 447static __u8 twhl850_rdesc_fixed2[] = {
 448        0x05, 0x01,         /*  Usage Page (Desktop),               */
 449        0x09, 0x06,         /*  Usage (Keyboard),                   */
 450        0xA1, 0x01,         /*  Collection (Application),           */
 451        0x85, 0x03,         /*      Report ID (3),                  */
 452        0x05, 0x07,         /*      Usage Page (Keyboard),          */
 453        0x14,               /*      Logical Minimum (0),            */
 454        0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
 455        0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
 456        0x25, 0x01,         /*      Logical Maximum (1),            */
 457        0x75, 0x01,         /*      Report Size (1),                */
 458        0x95, 0x08,         /*      Report Count (8),               */
 459        0x81, 0x02,         /*      Input (Variable),               */
 460        0x18,               /*      Usage Minimum (None),           */
 461        0x29, 0xFF,         /*      Usage Maximum (FFh),            */
 462        0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
 463        0x75, 0x08,         /*      Report Size (8),                */
 464        0x95, 0x06,         /*      Report Count (6),               */
 465        0x80,               /*      Input,                          */
 466        0xC0                /*  End Collection                      */
 467};
 468
 469static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 470                                        unsigned int *rsize)
 471{
 472        struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
 473        __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
 474
 475        switch (hdev->product) {
 476        case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209:
 477                if (*rsize == PF1209_RDESC_ORIG_SIZE) {
 478                        rdesc = pf1209_rdesc_fixed;
 479                        *rsize = sizeof(pf1209_rdesc_fixed);
 480                }
 481                break;
 482        case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U:
 483                if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
 484                        rdesc = wp4030u_rdesc_fixed;
 485                        *rsize = sizeof(wp4030u_rdesc_fixed);
 486                }
 487                break;
 488        case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U:
 489                if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
 490                        rdesc = wp5540u_rdesc_fixed;
 491                        *rsize = sizeof(wp5540u_rdesc_fixed);
 492                }
 493                break;
 494        case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U:
 495                if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
 496                        rdesc = wp8060u_rdesc_fixed;
 497                        *rsize = sizeof(wp8060u_rdesc_fixed);
 498                }
 499                break;
 500        case USB_DEVICE_ID_UCLOGIC_TABLET_WP1062:
 501                if (*rsize == WP1062_RDESC_ORIG_SIZE) {
 502                        rdesc = wp1062_rdesc_fixed;
 503                        *rsize = sizeof(wp1062_rdesc_fixed);
 504                }
 505                break;
 506        case USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850:
 507                switch (iface_num) {
 508                case 0:
 509                        if (*rsize == TWHL850_RDESC_ORIG_SIZE0) {
 510                                rdesc = twhl850_rdesc_fixed0;
 511                                *rsize = sizeof(twhl850_rdesc_fixed0);
 512                        }
 513                        break;
 514                case 1:
 515                        if (*rsize == TWHL850_RDESC_ORIG_SIZE1) {
 516                                rdesc = twhl850_rdesc_fixed1;
 517                                *rsize = sizeof(twhl850_rdesc_fixed1);
 518                        }
 519                        break;
 520                case 2:
 521                        if (*rsize == TWHL850_RDESC_ORIG_SIZE2) {
 522                                rdesc = twhl850_rdesc_fixed2;
 523                                *rsize = sizeof(twhl850_rdesc_fixed2);
 524                        }
 525                        break;
 526                }
 527                break;
 528        }
 529
 530        return rdesc;
 531}
 532
 533static const struct hid_device_id uclogic_devices[] = {
 534        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 535                                USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
 536        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 537                                USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
 538        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 539                                USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
 540        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 541                                USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
 542        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 543                                USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
 544        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
 545                                USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
 546        { }
 547};
 548MODULE_DEVICE_TABLE(hid, uclogic_devices);
 549
 550static struct hid_driver uclogic_driver = {
 551        .name = "uclogic",
 552        .id_table = uclogic_devices,
 553        .report_fixup = uclogic_report_fixup,
 554};
 555
 556static int __init uclogic_init(void)
 557{
 558        return hid_register_driver(&uclogic_driver);
 559}
 560
 561static void __exit uclogic_exit(void)
 562{
 563        hid_unregister_driver(&uclogic_driver);
 564}
 565
 566module_init(uclogic_init);
 567module_exit(uclogic_exit);
 568MODULE_LICENSE("GPL");
 569
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.