![]() |
|
|||
0001 // SPDX-License-Identifier: GPL-2.0-or-later 0002 /* 0003 * HID driver for Waltop devices not fully compliant with HID standard 0004 * 0005 * Copyright (c) 2010 Nikolai Kondrashov 0006 */ 0007 0008 /* 0009 */ 0010 0011 #include <linux/device.h> 0012 #include <linux/hid.h> 0013 #include <linux/module.h> 0014 0015 #include "hid-ids.h" 0016 0017 /* 0018 * There exists an official driver on the manufacturer's website, which 0019 * wasn't submitted to the kernel, for some reason. The official driver 0020 * doesn't seem to support extra features of some tablets, like wheels. 0021 * 0022 * It shows that the feature report ID 2 could be used to control any waltop 0023 * tablet input mode, switching it between "default", "tablet" and "ink". 0024 * 0025 * This driver only uses "default" mode for all the supported tablets. This 0026 * mode tries to be HID-compatible (not very successfully), but cripples the 0027 * resolution of some tablets. 0028 * 0029 * The "tablet" mode uses some proprietary, yet decipherable protocol, which 0030 * represents the correct resolution, but is possibly HID-incompatible (i.e. 0031 * indescribable by a report descriptor). 0032 * 0033 * The purpose of the "ink" mode is unknown. 0034 * 0035 * The feature reports needed for switching to each mode are these: 0036 * 0037 * 02 16 00 default 0038 * 02 16 01 tablet 0039 * 02 16 02 ink 0040 */ 0041 0042 /* Size of the original report descriptor of Slim Tablet 5.8 inch */ 0043 #define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE 222 0044 0045 /* Fixed Slim Tablet 5.8 inch descriptor */ 0046 static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = { 0047 0x05, 0x0D, /* Usage Page (Digitizer), */ 0048 0x09, 0x02, /* Usage (Pen), */ 0049 0xA1, 0x01, /* Collection (Application), */ 0050 0x85, 0x10, /* Report ID (16), */ 0051 0x09, 0x20, /* Usage (Stylus), */ 0052 0xA0, /* Collection (Physical), */ 0053 0x09, 0x42, /* Usage (Tip Switch), */ 0054 0x09, 0x44, /* Usage (Barrel Switch), */ 0055 0x09, 0x46, /* Usage (Tablet Pick), */ 0056 0x15, 0x01, /* Logical Minimum (1), */ 0057 0x25, 0x03, /* Logical Maximum (3), */ 0058 0x75, 0x04, /* Report Size (4), */ 0059 0x95, 0x01, /* Report Count (1), */ 0060 0x80, /* Input, */ 0061 0x09, 0x32, /* Usage (In Range), */ 0062 0x14, /* Logical Minimum (0), */ 0063 0x25, 0x01, /* Logical Maximum (1), */ 0064 0x75, 0x01, /* Report Size (1), */ 0065 0x95, 0x01, /* Report Count (1), */ 0066 0x81, 0x02, /* Input (Variable), */ 0067 0x95, 0x03, /* Report Count (3), */ 0068 0x81, 0x03, /* Input (Constant, Variable), */ 0069 0x75, 0x10, /* Report Size (16), */ 0070 0x95, 0x01, /* Report Count (1), */ 0071 0x14, /* Logical Minimum (0), */ 0072 0xA4, /* Push, */ 0073 0x05, 0x01, /* Usage Page (Desktop), */ 0074 0x65, 0x13, /* Unit (Inch), */ 0075 0x55, 0xFD, /* Unit Exponent (-3), */ 0076 0x34, /* Physical Minimum (0), */ 0077 0x09, 0x30, /* Usage (X), */ 0078 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ 0079 0x26, 0x10, 0x27, /* Logical Maximum (10000), */ 0080 0x81, 0x02, /* Input (Variable), */ 0081 0x09, 0x31, /* Usage (Y), */ 0082 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */ 0083 0x26, 0x70, 0x17, /* Logical Maximum (6000), */ 0084 0x81, 0x02, /* Input (Variable), */ 0085 0xB4, /* Pop, */ 0086 0x09, 0x30, /* Usage (Tip Pressure), */ 0087 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0088 0x81, 0x02, /* Input (Variable), */ 0089 0xC0, /* End Collection, */ 0090 0xC0 /* End Collection */ 0091 }; 0092 0093 /* Size of the original report descriptor of Slim Tablet 12.1 inch */ 0094 #define SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE 269 0095 0096 /* Fixed Slim Tablet 12.1 inch descriptor */ 0097 static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = { 0098 0x05, 0x0D, /* Usage Page (Digitizer), */ 0099 0x09, 0x02, /* Usage (Pen), */ 0100 0xA1, 0x01, /* Collection (Application), */ 0101 0x85, 0x10, /* Report ID (16), */ 0102 0x09, 0x20, /* Usage (Stylus), */ 0103 0xA0, /* Collection (Physical), */ 0104 0x09, 0x42, /* Usage (Tip Switch), */ 0105 0x09, 0x44, /* Usage (Barrel Switch), */ 0106 0x09, 0x46, /* Usage (Tablet Pick), */ 0107 0x15, 0x01, /* Logical Minimum (1), */ 0108 0x25, 0x03, /* Logical Maximum (3), */ 0109 0x75, 0x04, /* Report Size (4), */ 0110 0x95, 0x01, /* Report Count (1), */ 0111 0x80, /* Input, */ 0112 0x09, 0x32, /* Usage (In Range), */ 0113 0x14, /* Logical Minimum (0), */ 0114 0x25, 0x01, /* Logical Maximum (1), */ 0115 0x75, 0x01, /* Report Size (1), */ 0116 0x95, 0x01, /* Report Count (1), */ 0117 0x81, 0x02, /* Input (Variable), */ 0118 0x95, 0x03, /* Report Count (3), */ 0119 0x81, 0x03, /* Input (Constant, Variable), */ 0120 0x75, 0x10, /* Report Size (16), */ 0121 0x95, 0x01, /* Report Count (1), */ 0122 0x14, /* Logical Minimum (0), */ 0123 0xA4, /* Push, */ 0124 0x05, 0x01, /* Usage Page (Desktop), */ 0125 0x65, 0x13, /* Unit (Inch), */ 0126 0x55, 0xFD, /* Unit Exponent (-3), */ 0127 0x34, /* Physical Minimum (0), */ 0128 0x09, 0x30, /* Usage (X), */ 0129 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 0130 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 0131 0x81, 0x02, /* Input (Variable), */ 0132 0x09, 0x31, /* Usage (Y), */ 0133 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */ 0134 0x26, 0xD4, 0x30, /* Logical Maximum (12500), */ 0135 0x81, 0x02, /* Input (Variable), */ 0136 0xB4, /* Pop, */ 0137 0x09, 0x30, /* Usage (Tip Pressure), */ 0138 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0139 0x81, 0x02, /* Input (Variable), */ 0140 0xC0, /* End Collection, */ 0141 0xC0 /* End Collection */ 0142 }; 0143 0144 /* Size of the original report descriptor of Q Pad */ 0145 #define Q_PAD_RDESC_ORIG_SIZE 241 0146 0147 /* Fixed Q Pad descriptor */ 0148 static __u8 q_pad_rdesc_fixed[] = { 0149 0x05, 0x0D, /* Usage Page (Digitizer), */ 0150 0x09, 0x02, /* Usage (Pen), */ 0151 0xA1, 0x01, /* Collection (Application), */ 0152 0x85, 0x10, /* Report ID (16), */ 0153 0x09, 0x20, /* Usage (Stylus), */ 0154 0xA0, /* Collection (Physical), */ 0155 0x09, 0x42, /* Usage (Tip Switch), */ 0156 0x09, 0x44, /* Usage (Barrel Switch), */ 0157 0x09, 0x46, /* Usage (Tablet Pick), */ 0158 0x15, 0x01, /* Logical Minimum (1), */ 0159 0x25, 0x03, /* Logical Maximum (3), */ 0160 0x75, 0x04, /* Report Size (4), */ 0161 0x95, 0x01, /* Report Count (1), */ 0162 0x80, /* Input, */ 0163 0x09, 0x32, /* Usage (In Range), */ 0164 0x14, /* Logical Minimum (0), */ 0165 0x25, 0x01, /* Logical Maximum (1), */ 0166 0x75, 0x01, /* Report Size (1), */ 0167 0x95, 0x01, /* Report Count (1), */ 0168 0x81, 0x02, /* Input (Variable), */ 0169 0x95, 0x03, /* Report Count (3), */ 0170 0x81, 0x03, /* Input (Constant, Variable), */ 0171 0x75, 0x10, /* Report Size (16), */ 0172 0x95, 0x01, /* Report Count (1), */ 0173 0x14, /* Logical Minimum (0), */ 0174 0xA4, /* Push, */ 0175 0x05, 0x01, /* Usage Page (Desktop), */ 0176 0x65, 0x13, /* Unit (Inch), */ 0177 0x55, 0xFD, /* Unit Exponent (-3), */ 0178 0x34, /* Physical Minimum (0), */ 0179 0x09, 0x30, /* Usage (X), */ 0180 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 0181 0x26, 0x00, 0x30, /* Logical Maximum (12288), */ 0182 0x81, 0x02, /* Input (Variable), */ 0183 0x09, 0x31, /* Usage (Y), */ 0184 0x46, 0x94, 0x11, /* Physical Maximum (4500), */ 0185 0x26, 0x00, 0x24, /* Logical Maximum (9216), */ 0186 0x81, 0x02, /* Input (Variable), */ 0187 0xB4, /* Pop, */ 0188 0x09, 0x30, /* Usage (Tip Pressure), */ 0189 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0190 0x81, 0x02, /* Input (Variable), */ 0191 0xC0, /* End Collection, */ 0192 0xC0 /* End Collection */ 0193 }; 0194 0195 /* Size of the original report descriptor of tablet with PID 0038 */ 0196 #define PID_0038_RDESC_ORIG_SIZE 241 0197 0198 /* 0199 * Fixed report descriptor for tablet with PID 0038. 0200 */ 0201 static __u8 pid_0038_rdesc_fixed[] = { 0202 0x05, 0x0D, /* Usage Page (Digitizer), */ 0203 0x09, 0x02, /* Usage (Pen), */ 0204 0xA1, 0x01, /* Collection (Application), */ 0205 0x85, 0x10, /* Report ID (16), */ 0206 0x09, 0x20, /* Usage (Stylus), */ 0207 0xA0, /* Collection (Physical), */ 0208 0x09, 0x42, /* Usage (Tip Switch), */ 0209 0x09, 0x44, /* Usage (Barrel Switch), */ 0210 0x09, 0x46, /* Usage (Tablet Pick), */ 0211 0x15, 0x01, /* Logical Minimum (1), */ 0212 0x25, 0x03, /* Logical Maximum (3), */ 0213 0x75, 0x04, /* Report Size (4), */ 0214 0x95, 0x01, /* Report Count (1), */ 0215 0x80, /* Input, */ 0216 0x09, 0x32, /* Usage (In Range), */ 0217 0x14, /* Logical Minimum (0), */ 0218 0x25, 0x01, /* Logical Maximum (1), */ 0219 0x75, 0x01, /* Report Size (1), */ 0220 0x95, 0x01, /* Report Count (1), */ 0221 0x81, 0x02, /* Input (Variable), */ 0222 0x95, 0x03, /* Report Count (3), */ 0223 0x81, 0x03, /* Input (Constant, Variable), */ 0224 0x75, 0x10, /* Report Size (16), */ 0225 0x95, 0x01, /* Report Count (1), */ 0226 0x14, /* Logical Minimum (0), */ 0227 0xA4, /* Push, */ 0228 0x05, 0x01, /* Usage Page (Desktop), */ 0229 0x65, 0x13, /* Unit (Inch), */ 0230 0x55, 0xFD, /* Unit Exponent (-3), */ 0231 0x34, /* Physical Minimum (0), */ 0232 0x09, 0x30, /* Usage (X), */ 0233 0x46, 0x2E, 0x22, /* Physical Maximum (8750), */ 0234 0x26, 0x00, 0x46, /* Logical Maximum (17920), */ 0235 0x81, 0x02, /* Input (Variable), */ 0236 0x09, 0x31, /* Usage (Y), */ 0237 0x46, 0x82, 0x14, /* Physical Maximum (5250), */ 0238 0x26, 0x00, 0x2A, /* Logical Maximum (10752), */ 0239 0x81, 0x02, /* Input (Variable), */ 0240 0xB4, /* Pop, */ 0241 0x09, 0x30, /* Usage (Tip Pressure), */ 0242 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0243 0x81, 0x02, /* Input (Variable), */ 0244 0xC0, /* End Collection, */ 0245 0xC0 /* End Collection */ 0246 }; 0247 0248 /* Size of the original report descriptor of Media Tablet 10.6 inch */ 0249 #define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300 0250 0251 /* Fixed Media Tablet 10.6 inch descriptor */ 0252 static __u8 media_tablet_10_6_inch_rdesc_fixed[] = { 0253 0x05, 0x0D, /* Usage Page (Digitizer), */ 0254 0x09, 0x02, /* Usage (Pen), */ 0255 0xA1, 0x01, /* Collection (Application), */ 0256 0x85, 0x10, /* Report ID (16), */ 0257 0x09, 0x20, /* Usage (Stylus), */ 0258 0xA0, /* Collection (Physical), */ 0259 0x09, 0x42, /* Usage (Tip Switch), */ 0260 0x09, 0x44, /* Usage (Barrel Switch), */ 0261 0x09, 0x46, /* Usage (Tablet Pick), */ 0262 0x15, 0x01, /* Logical Minimum (1), */ 0263 0x25, 0x03, /* Logical Maximum (3), */ 0264 0x75, 0x04, /* Report Size (4), */ 0265 0x95, 0x01, /* Report Count (1), */ 0266 0x80, /* Input, */ 0267 0x75, 0x01, /* Report Size (1), */ 0268 0x09, 0x32, /* Usage (In Range), */ 0269 0x14, /* Logical Minimum (0), */ 0270 0x25, 0x01, /* Logical Maximum (1), */ 0271 0x95, 0x01, /* Report Count (1), */ 0272 0x81, 0x02, /* Input (Variable), */ 0273 0x95, 0x03, /* Report Count (3), */ 0274 0x81, 0x03, /* Input (Constant, Variable), */ 0275 0x75, 0x10, /* Report Size (16), */ 0276 0x95, 0x01, /* Report Count (1), */ 0277 0x14, /* Logical Minimum (0), */ 0278 0xA4, /* Push, */ 0279 0x05, 0x01, /* Usage Page (Desktop), */ 0280 0x65, 0x13, /* Unit (Inch), */ 0281 0x55, 0xFD, /* Unit Exponent (-3), */ 0282 0x34, /* Physical Minimum (0), */ 0283 0x09, 0x30, /* Usage (X), */ 0284 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 0285 0x26, 0x50, 0x46, /* Logical Maximum (18000), */ 0286 0x81, 0x02, /* Input (Variable), */ 0287 0x09, 0x31, /* Usage (Y), */ 0288 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ 0289 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */ 0290 0x81, 0x02, /* Input (Variable), */ 0291 0xB4, /* Pop, */ 0292 0x09, 0x30, /* Usage (Tip Pressure), */ 0293 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0294 0x81, 0x02, /* Input (Variable), */ 0295 0xC0, /* End Collection, */ 0296 0xC0, /* End Collection, */ 0297 0x05, 0x01, /* Usage Page (Desktop), */ 0298 0x09, 0x02, /* Usage (Mouse), */ 0299 0xA1, 0x01, /* Collection (Application), */ 0300 0x85, 0x01, /* Report ID (1), */ 0301 0x09, 0x01, /* Usage (Pointer), */ 0302 0xA0, /* Collection (Physical), */ 0303 0x75, 0x08, /* Report Size (8), */ 0304 0x95, 0x03, /* Report Count (3), */ 0305 0x81, 0x03, /* Input (Constant, Variable), */ 0306 0x95, 0x02, /* Report Count (2), */ 0307 0x15, 0xFF, /* Logical Minimum (-1), */ 0308 0x25, 0x01, /* Logical Maximum (1), */ 0309 0x09, 0x38, /* Usage (Wheel), */ 0310 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */ 0311 0x0C, 0x00, 0312 0x81, 0x06, /* Input (Variable, Relative), */ 0313 0x95, 0x02, /* Report Count (2), */ 0314 0x81, 0x03, /* Input (Constant, Variable), */ 0315 0xC0, /* End Collection, */ 0316 0xC0, /* End Collection, */ 0317 0x05, 0x0C, /* Usage Page (Consumer), */ 0318 0x09, 0x01, /* Usage (Consumer Control), */ 0319 0xA1, 0x01, /* Collection (Application), */ 0320 0x85, 0x0D, /* Report ID (13), */ 0321 0x95, 0x01, /* Report Count (1), */ 0322 0x75, 0x10, /* Report Size (16), */ 0323 0x81, 0x03, /* Input (Constant, Variable), */ 0324 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 0325 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 0326 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 0327 0x09, 0xB6, /* Usage (Scan Previous Track), */ 0328 0x09, 0xB5, /* Usage (Scan Next Track), */ 0329 0x08, /* Usage (00h), */ 0330 0x08, /* Usage (00h), */ 0331 0x08, /* Usage (00h), */ 0332 0x08, /* Usage (00h), */ 0333 0x08, /* Usage (00h), */ 0334 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 0335 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 0336 0x15, 0x0C, /* Logical Minimum (12), */ 0337 0x25, 0x17, /* Logical Maximum (23), */ 0338 0x75, 0x05, /* Report Size (5), */ 0339 0x80, /* Input, */ 0340 0x75, 0x03, /* Report Size (3), */ 0341 0x81, 0x03, /* Input (Constant, Variable), */ 0342 0x75, 0x20, /* Report Size (32), */ 0343 0x81, 0x03, /* Input (Constant, Variable), */ 0344 0xC0, /* End Collection, */ 0345 0x09, 0x01, /* Usage (Consumer Control), */ 0346 0xA1, 0x01, /* Collection (Application), */ 0347 0x85, 0x0C, /* Report ID (12), */ 0348 0x75, 0x01, /* Report Size (1), */ 0349 0x09, 0xE9, /* Usage (Volume Inc), */ 0350 0x09, 0xEA, /* Usage (Volume Dec), */ 0351 0x09, 0xE2, /* Usage (Mute), */ 0352 0x14, /* Logical Minimum (0), */ 0353 0x25, 0x01, /* Logical Maximum (1), */ 0354 0x95, 0x03, /* Report Count (3), */ 0355 0x81, 0x06, /* Input (Variable, Relative), */ 0356 0x95, 0x35, /* Report Count (53), */ 0357 0x81, 0x03, /* Input (Constant, Variable), */ 0358 0xC0 /* End Collection */ 0359 }; 0360 0361 /* Size of the original report descriptor of Media Tablet 14.1 inch */ 0362 #define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE 309 0363 0364 /* Fixed Media Tablet 14.1 inch descriptor */ 0365 static __u8 media_tablet_14_1_inch_rdesc_fixed[] = { 0366 0x05, 0x0D, /* Usage Page (Digitizer), */ 0367 0x09, 0x02, /* Usage (Pen), */ 0368 0xA1, 0x01, /* Collection (Application), */ 0369 0x85, 0x10, /* Report ID (16), */ 0370 0x09, 0x20, /* Usage (Stylus), */ 0371 0xA0, /* Collection (Physical), */ 0372 0x09, 0x42, /* Usage (Tip Switch), */ 0373 0x09, 0x44, /* Usage (Barrel Switch), */ 0374 0x09, 0x46, /* Usage (Tablet Pick), */ 0375 0x15, 0x01, /* Logical Minimum (1), */ 0376 0x25, 0x03, /* Logical Maximum (3), */ 0377 0x75, 0x04, /* Report Size (4), */ 0378 0x95, 0x01, /* Report Count (1), */ 0379 0x80, /* Input, */ 0380 0x75, 0x01, /* Report Size (1), */ 0381 0x09, 0x32, /* Usage (In Range), */ 0382 0x14, /* Logical Minimum (0), */ 0383 0x25, 0x01, /* Logical Maximum (1), */ 0384 0x95, 0x01, /* Report Count (1), */ 0385 0x81, 0x02, /* Input (Variable), */ 0386 0x95, 0x03, /* Report Count (3), */ 0387 0x81, 0x03, /* Input (Constant, Variable), */ 0388 0x75, 0x10, /* Report Size (16), */ 0389 0x95, 0x01, /* Report Count (1), */ 0390 0x14, /* Logical Minimum (0), */ 0391 0xA4, /* Push, */ 0392 0x05, 0x01, /* Usage Page (Desktop), */ 0393 0x65, 0x13, /* Unit (Inch), */ 0394 0x55, 0xFD, /* Unit Exponent (-3), */ 0395 0x34, /* Physical Minimum (0), */ 0396 0x09, 0x30, /* Usage (X), */ 0397 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 0398 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */ 0399 0x81, 0x02, /* Input (Variable), */ 0400 0x09, 0x31, /* Usage (Y), */ 0401 0x46, 0x52, 0x1C, /* Physical Maximum (7250), */ 0402 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */ 0403 0x81, 0x02, /* Input (Variable), */ 0404 0xB4, /* Pop, */ 0405 0x09, 0x30, /* Usage (Tip Pressure), */ 0406 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0407 0x81, 0x02, /* Input (Variable), */ 0408 0xC0, /* End Collection, */ 0409 0xC0, /* End Collection, */ 0410 0x05, 0x01, /* Usage Page (Desktop), */ 0411 0x09, 0x02, /* Usage (Mouse), */ 0412 0xA1, 0x01, /* Collection (Application), */ 0413 0x85, 0x01, /* Report ID (1), */ 0414 0x09, 0x01, /* Usage (Pointer), */ 0415 0xA0, /* Collection (Physical), */ 0416 0x75, 0x08, /* Report Size (8), */ 0417 0x95, 0x03, /* Report Count (3), */ 0418 0x81, 0x03, /* Input (Constant, Variable), */ 0419 0x95, 0x02, /* Report Count (2), */ 0420 0x15, 0xFF, /* Logical Minimum (-1), */ 0421 0x25, 0x01, /* Logical Maximum (1), */ 0422 0x09, 0x38, /* Usage (Wheel), */ 0423 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */ 0424 0x0C, 0x00, 0425 0x81, 0x06, /* Input (Variable, Relative), */ 0426 0xC0, /* End Collection, */ 0427 0xC0, /* End Collection, */ 0428 0x05, 0x0C, /* Usage Page (Consumer), */ 0429 0x09, 0x01, /* Usage (Consumer Control), */ 0430 0xA1, 0x01, /* Collection (Application), */ 0431 0x85, 0x0D, /* Report ID (13), */ 0432 0x95, 0x01, /* Report Count (1), */ 0433 0x75, 0x10, /* Report Size (16), */ 0434 0x81, 0x03, /* Input (Constant, Variable), */ 0435 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 0436 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 0437 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 0438 0x09, 0xB6, /* Usage (Scan Previous Track), */ 0439 0x09, 0xB5, /* Usage (Scan Next Track), */ 0440 0x08, /* Usage (00h), */ 0441 0x08, /* Usage (00h), */ 0442 0x08, /* Usage (00h), */ 0443 0x08, /* Usage (00h), */ 0444 0x08, /* Usage (00h), */ 0445 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 0446 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 0447 0x15, 0x0C, /* Logical Minimum (12), */ 0448 0x25, 0x17, /* Logical Maximum (23), */ 0449 0x75, 0x05, /* Report Size (5), */ 0450 0x80, /* Input, */ 0451 0x75, 0x03, /* Report Size (3), */ 0452 0x81, 0x03, /* Input (Constant, Variable), */ 0453 0x75, 0x20, /* Report Size (32), */ 0454 0x81, 0x03, /* Input (Constant, Variable), */ 0455 0xC0, /* End Collection, */ 0456 0x09, 0x01, /* Usage (Consumer Control), */ 0457 0xA1, 0x01, /* Collection (Application), */ 0458 0x85, 0x0C, /* Report ID (12), */ 0459 0x75, 0x01, /* Report Size (1), */ 0460 0x09, 0xE9, /* Usage (Volume Inc), */ 0461 0x09, 0xEA, /* Usage (Volume Dec), */ 0462 0x09, 0xE2, /* Usage (Mute), */ 0463 0x14, /* Logical Minimum (0), */ 0464 0x25, 0x01, /* Logical Maximum (1), */ 0465 0x95, 0x03, /* Report Count (3), */ 0466 0x81, 0x06, /* Input (Variable, Relative), */ 0467 0x75, 0x05, /* Report Size (5), */ 0468 0x81, 0x03, /* Input (Constant, Variable), */ 0469 0xC0 /* End Collection */ 0470 }; 0471 0472 /* Size of the original report descriptor of Sirius Battery Free Tablet */ 0473 #define SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE 335 0474 0475 /* Fixed Sirius Battery Free Tablet descriptor */ 0476 static __u8 sirius_battery_free_tablet_rdesc_fixed[] = { 0477 0x05, 0x0D, /* Usage Page (Digitizer), */ 0478 0x09, 0x02, /* Usage (Pen), */ 0479 0xA1, 0x01, /* Collection (Application), */ 0480 0x85, 0x10, /* Report ID (16), */ 0481 0x09, 0x20, /* Usage (Stylus), */ 0482 0xA0, /* Collection (Physical), */ 0483 0x95, 0x01, /* Report Count (1), */ 0484 0x15, 0x01, /* Logical Minimum (1), */ 0485 0x25, 0x03, /* Logical Maximum (3), */ 0486 0x75, 0x02, /* Report Size (2), */ 0487 0x09, 0x42, /* Usage (Tip Switch), */ 0488 0x09, 0x44, /* Usage (Barrel Switch), */ 0489 0x09, 0x46, /* Usage (Tablet Pick), */ 0490 0x80, /* Input, */ 0491 0x14, /* Logical Minimum (0), */ 0492 0x25, 0x01, /* Logical Maximum (1), */ 0493 0x75, 0x01, /* Report Size (1), */ 0494 0x09, 0x3C, /* Usage (Invert), */ 0495 0x81, 0x02, /* Input (Variable), */ 0496 0x81, 0x03, /* Input (Constant, Variable), */ 0497 0x09, 0x32, /* Usage (In Range), */ 0498 0x81, 0x02, /* Input (Variable), */ 0499 0x95, 0x03, /* Report Count (3), */ 0500 0x81, 0x03, /* Input (Constant, Variable), */ 0501 0xA4, /* Push, */ 0502 0x05, 0x01, /* Usage Page (Desktop), */ 0503 0x55, 0xFD, /* Unit Exponent (-3), */ 0504 0x65, 0x13, /* Unit (Inch), */ 0505 0x34, /* Physical Minimum (0), */ 0506 0x14, /* Logical Minimum (0), */ 0507 0x75, 0x10, /* Report Size (16), */ 0508 0x95, 0x01, /* Report Count (1), */ 0509 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ 0510 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 0511 0x09, 0x30, /* Usage (X), */ 0512 0x81, 0x02, /* Input (Variable), */ 0513 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ 0514 0x26, 0xE0, 0x2E, /* Logical Maximum (12000), */ 0515 0x09, 0x31, /* Usage (Y), */ 0516 0x81, 0x02, /* Input (Variable), */ 0517 0xB4, /* Pop, */ 0518 0x75, 0x10, /* Report Size (16), */ 0519 0x95, 0x01, /* Report Count (1), */ 0520 0x14, /* Logical Minimum (0), */ 0521 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 0522 0x09, 0x30, /* Usage (Tip Pressure), */ 0523 0x81, 0x02, /* Input (Variable), */ 0524 0xA4, /* Push, */ 0525 0x55, 0xFE, /* Unit Exponent (-2), */ 0526 0x65, 0x12, /* Unit (Radians), */ 0527 0x35, 0x97, /* Physical Minimum (-105), */ 0528 0x45, 0x69, /* Physical Maximum (105), */ 0529 0x15, 0x97, /* Logical Minimum (-105), */ 0530 0x25, 0x69, /* Logical Maximum (105), */ 0531 0x75, 0x08, /* Report Size (8), */ 0532 0x95, 0x02, /* Report Count (2), */ 0533 0x09, 0x3D, /* Usage (X Tilt), */ 0534 0x09, 0x3E, /* Usage (Y Tilt), */ 0535 0x81, 0x02, /* Input (Variable), */ 0536 0xB4, /* Pop, */ 0537 0xC0, /* End Collection, */ 0538 0xC0, /* End Collection, */ 0539 0x05, 0x01, /* Usage Page (Desktop), */ 0540 0x09, 0x02, /* Usage (Mouse), */ 0541 0xA1, 0x01, /* Collection (Application), */ 0542 0x85, 0x01, /* Report ID (1), */ 0543 0x09, 0x01, /* Usage (Pointer), */ 0544 0xA0, /* Collection (Physical), */ 0545 0x75, 0x08, /* Report Size (8), */ 0546 0x95, 0x03, /* Report Count (3), */ 0547 0x81, 0x03, /* Input (Constant, Variable), */ 0548 0x09, 0x38, /* Usage (Wheel), */ 0549 0x15, 0xFF, /* Logical Minimum (-1), */ 0550 0x25, 0x01, /* Logical Maximum (1), */ 0551 0x75, 0x08, /* Report Size (8), */ 0552 0x95, 0x01, /* Report Count (1), */ 0553 0x81, 0x06, /* Input (Variable, Relative), */ 0554 0x75, 0x08, /* Report Size (8), */ 0555 0x95, 0x03, /* Report Count (3), */ 0556 0x81, 0x03, /* Input (Constant, Variable), */ 0557 0xC0, /* End Collection, */ 0558 0xC0, /* End Collection, */ 0559 0x05, 0x01, /* Usage Page (Desktop), */ 0560 0x09, 0x06, /* Usage (Keyboard), */ 0561 0xA1, 0x01, /* Collection (Application), */ 0562 0x85, 0x0D, /* Report ID (13), */ 0563 0x05, 0x07, /* Usage Page (Keyboard), */ 0564 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ 0565 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ 0566 0x14, /* Logical Minimum (0), */ 0567 0x25, 0x01, /* Logical Maximum (1), */ 0568 0x75, 0x01, /* Report Size (1), */ 0569 0x95, 0x08, /* Report Count (8), */ 0570 0x81, 0x02, /* Input (Variable), */ 0571 0x75, 0x08, /* Report Size (8), */ 0572 0x95, 0x01, /* Report Count (1), */ 0573 0x81, 0x01, /* Input (Constant), */ 0574 0x18, /* Usage Minimum (None), */ 0575 0x29, 0x65, /* Usage Maximum (KB Application), */ 0576 0x14, /* Logical Minimum (0), */ 0577 0x25, 0x65, /* Logical Maximum (101), */ 0578 0x75, 0x08, /* Report Size (8), */ 0579 0x95, 0x05, /* Report Count (5), */ 0580 0x80, /* Input, */ 0581 0xC0, /* End Collection, */ 0582 0x05, 0x0C, /* Usage Page (Consumer), */ 0583 0x09, 0x01, /* Usage (Consumer Control), */ 0584 0xA1, 0x01, /* Collection (Application), */ 0585 0x85, 0x0C, /* Report ID (12), */ 0586 0x09, 0xE9, /* Usage (Volume Inc), */ 0587 0x09, 0xEA, /* Usage (Volume Dec), */ 0588 0x14, /* Logical Minimum (0), */ 0589 0x25, 0x01, /* Logical Maximum (1), */ 0590 0x75, 0x01, /* Report Size (1), */ 0591 0x95, 0x02, /* Report Count (2), */ 0592 0x81, 0x02, /* Input (Variable), */ 0593 0x75, 0x06, /* Report Size (6), */ 0594 0x95, 0x01, /* Report Count (1), */ 0595 0x81, 0x03, /* Input (Constant, Variable), */ 0596 0x75, 0x10, /* Report Size (16), */ 0597 0x95, 0x03, /* Report Count (3), */ 0598 0x81, 0x03, /* Input (Constant, Variable), */ 0599 0xC0 /* End Collection */ 0600 }; 0601 0602 static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, 0603 unsigned int *rsize) 0604 { 0605 switch (hdev->product) { 0606 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH: 0607 if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) { 0608 rdesc = slim_tablet_5_8_inch_rdesc_fixed; 0609 *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed); 0610 } 0611 break; 0612 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH: 0613 if (*rsize == SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE) { 0614 rdesc = slim_tablet_12_1_inch_rdesc_fixed; 0615 *rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed); 0616 } 0617 break; 0618 case USB_DEVICE_ID_WALTOP_Q_PAD: 0619 if (*rsize == Q_PAD_RDESC_ORIG_SIZE) { 0620 rdesc = q_pad_rdesc_fixed; 0621 *rsize = sizeof(q_pad_rdesc_fixed); 0622 } 0623 break; 0624 case USB_DEVICE_ID_WALTOP_PID_0038: 0625 if (*rsize == PID_0038_RDESC_ORIG_SIZE) { 0626 rdesc = pid_0038_rdesc_fixed; 0627 *rsize = sizeof(pid_0038_rdesc_fixed); 0628 } 0629 break; 0630 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH: 0631 if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) { 0632 rdesc = media_tablet_10_6_inch_rdesc_fixed; 0633 *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed); 0634 } 0635 break; 0636 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH: 0637 if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) { 0638 rdesc = media_tablet_14_1_inch_rdesc_fixed; 0639 *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed); 0640 } 0641 break; 0642 case USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET: 0643 if (*rsize == SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE) { 0644 rdesc = sirius_battery_free_tablet_rdesc_fixed; 0645 *rsize = sizeof(sirius_battery_free_tablet_rdesc_fixed); 0646 } 0647 break; 0648 } 0649 return rdesc; 0650 } 0651 0652 static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, 0653 u8 *data, int size) 0654 { 0655 /* If this is a pen input report */ 0656 if (report->type == HID_INPUT_REPORT && report->id == 16 && size >= 8) { 0657 /* 0658 * Ignore reported pressure when a barrel button is pressed, 0659 * because it is rarely correct. 0660 */ 0661 0662 /* If a barrel button is pressed */ 0663 if ((data[1] & 0xF) > 1) { 0664 /* Report zero pressure */ 0665 data[6] = 0; 0666 data[7] = 0; 0667 } 0668 } 0669 0670 /* If this is a pen input report of Sirius Battery Free Tablet */ 0671 if (hdev->product == USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET && 0672 report->type == HID_INPUT_REPORT && 0673 report->id == 16 && 0674 size == 10) { 0675 /* 0676 * The tablet reports tilt as roughly sin(a)*21 (18 means 60 0677 * degrees). 0678 * 0679 * This array stores angles as radians * 100, corresponding to 0680 * reported values up to 60 degrees, as expected by userspace. 0681 */ 0682 static const s8 tilt_to_radians[] = { 0683 0, 5, 10, 14, 19, 24, 29, 34, 40, 45, 0684 50, 56, 62, 68, 74, 81, 88, 96, 105 0685 }; 0686 0687 s8 tilt_x = (s8)data[8]; 0688 s8 tilt_y = (s8)data[9]; 0689 s8 sign_x = tilt_x >= 0 ? 1 : -1; 0690 s8 sign_y = tilt_y >= 0 ? 1 : -1; 0691 0692 tilt_x *= sign_x; 0693 tilt_y *= sign_y; 0694 0695 /* 0696 * Reverse the Y Tilt direction to match the HID standard and 0697 * userspace expectations. See HID Usage Tables v1.12 16.3.2 0698 * Tilt Orientation. 0699 */ 0700 sign_y *= -1; 0701 0702 /* 0703 * This effectively clamps reported tilt to 60 degrees - the 0704 * range expected by userspace 0705 */ 0706 if (tilt_x > ARRAY_SIZE(tilt_to_radians) - 1) 0707 tilt_x = ARRAY_SIZE(tilt_to_radians) - 1; 0708 if (tilt_y > ARRAY_SIZE(tilt_to_radians) - 1) 0709 tilt_y = ARRAY_SIZE(tilt_to_radians) - 1; 0710 0711 data[8] = tilt_to_radians[tilt_x] * sign_x; 0712 data[9] = tilt_to_radians[tilt_y] * sign_y; 0713 } 0714 0715 return 0; 0716 } 0717 0718 static const struct hid_device_id waltop_devices[] = { 0719 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0720 USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, 0721 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0722 USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, 0723 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0724 USB_DEVICE_ID_WALTOP_Q_PAD) }, 0725 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0726 USB_DEVICE_ID_WALTOP_PID_0038) }, 0727 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0728 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, 0729 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0730 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, 0731 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, 0732 USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, 0733 { } 0734 }; 0735 MODULE_DEVICE_TABLE(hid, waltop_devices); 0736 0737 static struct hid_driver waltop_driver = { 0738 .name = "waltop", 0739 .id_table = waltop_devices, 0740 .report_fixup = waltop_report_fixup, 0741 .raw_event = waltop_raw_event, 0742 }; 0743 module_hid_driver(waltop_driver); 0744 0745 MODULE_LICENSE("GPL");
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |