brintos

brintos / linux-shallow public Read only

0
0
Text · 38.7 KiB · be34be2 Raw
747 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *  HID driver for Waltop devices not fully compliant with HID standard4 *5 *  Copyright (c) 2010 Nikolai Kondrashov6 */7 8/*9 */10 11#include <linux/device.h>12#include <linux/hid.h>13#include <linux/module.h>14 15#include "hid-ids.h"16 17/*18 * There exists an official driver on the manufacturer's website, which19 * wasn't submitted to the kernel, for some reason. The official driver20 * doesn't seem to support extra features of some tablets, like wheels.21 *22 * It shows that the feature report ID 2 could be used to control any waltop23 * tablet input mode, switching it between "default", "tablet" and "ink".24 *25 * This driver only uses "default" mode for all the supported tablets. This26 * mode tries to be HID-compatible (not very successfully), but cripples the27 * resolution of some tablets.28 *29 * The "tablet" mode uses some proprietary, yet decipherable protocol, which30 * represents the correct resolution, but is possibly HID-incompatible (i.e.31 * indescribable by a report descriptor).32 *33 * The purpose of the "ink" mode is unknown.34 *35 * The feature reports needed for switching to each mode are these:36 *37 * 02 16 00     default38 * 02 16 01     tablet39 * 02 16 02     ink40 */41 42/* Size of the original report descriptor of Slim Tablet 5.8 inch */43#define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE	22244 45/* Fixed Slim Tablet 5.8 inch descriptor */46static const __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {47	0x05, 0x0D,         /*  Usage Page (Digitizer),             */48	0x09, 0x02,         /*  Usage (Pen),                        */49	0xA1, 0x01,         /*  Collection (Application),           */50	0x85, 0x10,         /*      Report ID (16),                 */51	0x09, 0x20,         /*      Usage (Stylus),                 */52	0xA0,               /*      Collection (Physical),          */53	0x09, 0x42,         /*          Usage (Tip Switch),         */54	0x09, 0x44,         /*          Usage (Barrel Switch),      */55	0x09, 0x46,         /*          Usage (Tablet Pick),        */56	0x15, 0x01,         /*          Logical Minimum (1),        */57	0x25, 0x03,         /*          Logical Maximum (3),        */58	0x75, 0x04,         /*          Report Size (4),            */59	0x95, 0x01,         /*          Report Count (1),           */60	0x80,               /*          Input,                      */61	0x09, 0x32,         /*          Usage (In Range),           */62	0x14,               /*          Logical Minimum (0),        */63	0x25, 0x01,         /*          Logical Maximum (1),        */64	0x75, 0x01,         /*          Report Size (1),            */65	0x95, 0x01,         /*          Report Count (1),           */66	0x81, 0x02,         /*          Input (Variable),           */67	0x95, 0x03,         /*          Report Count (3),           */68	0x81, 0x03,         /*          Input (Constant, Variable), */69	0x75, 0x10,         /*          Report Size (16),           */70	0x95, 0x01,         /*          Report Count (1),           */71	0x14,               /*          Logical Minimum (0),        */72	0xA4,               /*          Push,                       */73	0x05, 0x01,         /*          Usage Page (Desktop),       */74	0x65, 0x13,         /*          Unit (Inch),                */75	0x55, 0xFD,         /*          Unit Exponent (-3),         */76	0x34,               /*          Physical Minimum (0),       */77	0x09, 0x30,         /*          Usage (X),                  */78	0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */79	0x26, 0x10, 0x27,   /*          Logical Maximum (10000),    */80	0x81, 0x02,         /*          Input (Variable),           */81	0x09, 0x31,         /*          Usage (Y),                  */82	0x46, 0xB8, 0x0B,   /*          Physical Maximum (3000),    */83	0x26, 0x70, 0x17,   /*          Logical Maximum (6000),     */84	0x81, 0x02,         /*          Input (Variable),           */85	0xB4,               /*          Pop,                        */86	0x09, 0x30,         /*          Usage (Tip Pressure),       */87	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */88	0x81, 0x02,         /*          Input (Variable),           */89	0xC0,               /*      End Collection,                 */90	0xC0                /*  End Collection                      */91};92 93/* Size of the original report descriptor of Slim Tablet 12.1 inch */94#define SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE	26995 96/* Fixed Slim Tablet 12.1 inch descriptor */97static const __u8 slim_tablet_12_1_inch_rdesc_fixed[] = {98	0x05, 0x0D,         /*  Usage Page (Digitizer),             */99	0x09, 0x02,         /*  Usage (Pen),                        */100	0xA1, 0x01,         /*  Collection (Application),           */101	0x85, 0x10,         /*      Report ID (16),                 */102	0x09, 0x20,         /*      Usage (Stylus),                 */103	0xA0,               /*      Collection (Physical),          */104	0x09, 0x42,         /*          Usage (Tip Switch),         */105	0x09, 0x44,         /*          Usage (Barrel Switch),      */106	0x09, 0x46,         /*          Usage (Tablet Pick),        */107	0x15, 0x01,         /*          Logical Minimum (1),        */108	0x25, 0x03,         /*          Logical Maximum (3),        */109	0x75, 0x04,         /*          Report Size (4),            */110	0x95, 0x01,         /*          Report Count (1),           */111	0x80,               /*          Input,                      */112	0x09, 0x32,         /*          Usage (In Range),           */113	0x14,               /*          Logical Minimum (0),        */114	0x25, 0x01,         /*          Logical Maximum (1),        */115	0x75, 0x01,         /*          Report Size (1),            */116	0x95, 0x01,         /*          Report Count (1),           */117	0x81, 0x02,         /*          Input (Variable),           */118	0x95, 0x03,         /*          Report Count (3),           */119	0x81, 0x03,         /*          Input (Constant, Variable), */120	0x75, 0x10,         /*          Report Size (16),           */121	0x95, 0x01,         /*          Report Count (1),           */122	0x14,               /*          Logical Minimum (0),        */123	0xA4,               /*          Push,                       */124	0x05, 0x01,         /*          Usage Page (Desktop),       */125	0x65, 0x13,         /*          Unit (Inch),                */126	0x55, 0xFD,         /*          Unit Exponent (-3),         */127	0x34,               /*          Physical Minimum (0),       */128	0x09, 0x30,         /*          Usage (X),                  */129	0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */130	0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */131	0x81, 0x02,         /*          Input (Variable),           */132	0x09, 0x31,         /*          Usage (Y),                  */133	0x46, 0x6A, 0x18,   /*          Physical Maximum (6250),    */134	0x26, 0xD4, 0x30,   /*          Logical Maximum (12500),    */135	0x81, 0x02,         /*          Input (Variable),           */136	0xB4,               /*          Pop,                        */137	0x09, 0x30,         /*          Usage (Tip Pressure),       */138	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */139	0x81, 0x02,         /*          Input (Variable),           */140	0xC0,               /*      End Collection,                 */141	0xC0                /*  End Collection                      */142};143 144/* Size of the original report descriptor of Q Pad */145#define Q_PAD_RDESC_ORIG_SIZE	241146 147/* Fixed Q Pad descriptor */148static const __u8 q_pad_rdesc_fixed[] = {149	0x05, 0x0D,         /*  Usage Page (Digitizer),             */150	0x09, 0x02,         /*  Usage (Pen),                        */151	0xA1, 0x01,         /*  Collection (Application),           */152	0x85, 0x10,         /*      Report ID (16),                 */153	0x09, 0x20,         /*      Usage (Stylus),                 */154	0xA0,               /*      Collection (Physical),          */155	0x09, 0x42,         /*          Usage (Tip Switch),         */156	0x09, 0x44,         /*          Usage (Barrel Switch),      */157	0x09, 0x46,         /*          Usage (Tablet Pick),        */158	0x15, 0x01,         /*          Logical Minimum (1),        */159	0x25, 0x03,         /*          Logical Maximum (3),        */160	0x75, 0x04,         /*          Report Size (4),            */161	0x95, 0x01,         /*          Report Count (1),           */162	0x80,               /*          Input,                      */163	0x09, 0x32,         /*          Usage (In Range),           */164	0x14,               /*          Logical Minimum (0),        */165	0x25, 0x01,         /*          Logical Maximum (1),        */166	0x75, 0x01,         /*          Report Size (1),            */167	0x95, 0x01,         /*          Report Count (1),           */168	0x81, 0x02,         /*          Input (Variable),           */169	0x95, 0x03,         /*          Report Count (3),           */170	0x81, 0x03,         /*          Input (Constant, Variable), */171	0x75, 0x10,         /*          Report Size (16),           */172	0x95, 0x01,         /*          Report Count (1),           */173	0x14,               /*          Logical Minimum (0),        */174	0xA4,               /*          Push,                       */175	0x05, 0x01,         /*          Usage Page (Desktop),       */176	0x65, 0x13,         /*          Unit (Inch),                */177	0x55, 0xFD,         /*          Unit Exponent (-3),         */178	0x34,               /*          Physical Minimum (0),       */179	0x09, 0x30,         /*          Usage (X),                  */180	0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */181	0x26, 0x00, 0x30,   /*          Logical Maximum (12288),    */182	0x81, 0x02,         /*          Input (Variable),           */183	0x09, 0x31,         /*          Usage (Y),                  */184	0x46, 0x94, 0x11,   /*          Physical Maximum (4500),    */185	0x26, 0x00, 0x24,   /*          Logical Maximum (9216),     */186	0x81, 0x02,         /*          Input (Variable),           */187	0xB4,               /*          Pop,                        */188	0x09, 0x30,         /*          Usage (Tip Pressure),       */189	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */190	0x81, 0x02,         /*          Input (Variable),           */191	0xC0,               /*      End Collection,                 */192	0xC0                /*  End Collection                      */193};194 195/* Size of the original report descriptor of tablet with PID 0038 */196#define PID_0038_RDESC_ORIG_SIZE	241197 198/*199 * Fixed report descriptor for tablet with PID 0038.200 */201static const __u8 pid_0038_rdesc_fixed[] = {202	0x05, 0x0D,         /*  Usage Page (Digitizer),             */203	0x09, 0x02,         /*  Usage (Pen),                        */204	0xA1, 0x01,         /*  Collection (Application),           */205	0x85, 0x10,         /*      Report ID (16),                 */206	0x09, 0x20,         /*      Usage (Stylus),                 */207	0xA0,               /*      Collection (Physical),          */208	0x09, 0x42,         /*          Usage (Tip Switch),         */209	0x09, 0x44,         /*          Usage (Barrel Switch),      */210	0x09, 0x46,         /*          Usage (Tablet Pick),        */211	0x15, 0x01,         /*          Logical Minimum (1),        */212	0x25, 0x03,         /*          Logical Maximum (3),        */213	0x75, 0x04,         /*          Report Size (4),            */214	0x95, 0x01,         /*          Report Count (1),           */215	0x80,               /*          Input,                      */216	0x09, 0x32,         /*          Usage (In Range),           */217	0x14,               /*          Logical Minimum (0),        */218	0x25, 0x01,         /*          Logical Maximum (1),        */219	0x75, 0x01,         /*          Report Size (1),            */220	0x95, 0x01,         /*          Report Count (1),           */221	0x81, 0x02,         /*          Input (Variable),           */222	0x95, 0x03,         /*          Report Count (3),           */223	0x81, 0x03,         /*          Input (Constant, Variable), */224	0x75, 0x10,         /*          Report Size (16),           */225	0x95, 0x01,         /*          Report Count (1),           */226	0x14,               /*          Logical Minimum (0),        */227	0xA4,               /*          Push,                       */228	0x05, 0x01,         /*          Usage Page (Desktop),       */229	0x65, 0x13,         /*          Unit (Inch),                */230	0x55, 0xFD,         /*          Unit Exponent (-3),         */231	0x34,               /*          Physical Minimum (0),       */232	0x09, 0x30,         /*          Usage (X),                  */233	0x46, 0x2E, 0x22,   /*          Physical Maximum (8750),    */234	0x26, 0x00, 0x46,   /*          Logical Maximum (17920),    */235	0x81, 0x02,         /*          Input (Variable),           */236	0x09, 0x31,         /*          Usage (Y),                  */237	0x46, 0x82, 0x14,   /*          Physical Maximum (5250),    */238	0x26, 0x00, 0x2A,   /*          Logical Maximum (10752),    */239	0x81, 0x02,         /*          Input (Variable),           */240	0xB4,               /*          Pop,                        */241	0x09, 0x30,         /*          Usage (Tip Pressure),       */242	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */243	0x81, 0x02,         /*          Input (Variable),           */244	0xC0,               /*      End Collection,                 */245	0xC0                /*  End Collection                      */246};247 248/* Size of the original report descriptor of Media Tablet 10.6 inch */249#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE	300250 251/* Fixed Media Tablet 10.6 inch descriptor */252static const __u8 media_tablet_10_6_inch_rdesc_fixed[] = {253	0x05, 0x0D,         /*  Usage Page (Digitizer),             */254	0x09, 0x02,         /*  Usage (Pen),                        */255	0xA1, 0x01,         /*  Collection (Application),           */256	0x85, 0x10,         /*      Report ID (16),                 */257	0x09, 0x20,         /*      Usage (Stylus),                 */258	0xA0,               /*      Collection (Physical),          */259	0x09, 0x42,         /*          Usage (Tip Switch),         */260	0x09, 0x44,         /*          Usage (Barrel Switch),      */261	0x09, 0x46,         /*          Usage (Tablet Pick),        */262	0x15, 0x01,         /*          Logical Minimum (1),        */263	0x25, 0x03,         /*          Logical Maximum (3),        */264	0x75, 0x04,         /*          Report Size (4),            */265	0x95, 0x01,         /*          Report Count (1),           */266	0x80,               /*          Input,                      */267	0x75, 0x01,         /*          Report Size (1),            */268	0x09, 0x32,         /*          Usage (In Range),           */269	0x14,               /*          Logical Minimum (0),        */270	0x25, 0x01,         /*          Logical Maximum (1),        */271	0x95, 0x01,         /*          Report Count (1),           */272	0x81, 0x02,         /*          Input (Variable),           */273	0x95, 0x03,         /*          Report Count (3),           */274	0x81, 0x03,         /*          Input (Constant, Variable), */275	0x75, 0x10,         /*          Report Size (16),           */276	0x95, 0x01,         /*          Report Count (1),           */277	0x14,               /*          Logical Minimum (0),        */278	0xA4,               /*          Push,                       */279	0x05, 0x01,         /*          Usage Page (Desktop),       */280	0x65, 0x13,         /*          Unit (Inch),                */281	0x55, 0xFD,         /*          Unit Exponent (-3),         */282	0x34,               /*          Physical Minimum (0),       */283	0x09, 0x30,         /*          Usage (X),                  */284	0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */285	0x26, 0x50, 0x46,   /*          Logical Maximum (18000),    */286	0x81, 0x02,         /*          Input (Variable),           */287	0x09, 0x31,         /*          Usage (Y),                  */288	0x46, 0x7C, 0x15,   /*          Physical Maximum (5500),    */289	0x26, 0xF8, 0x2A,   /*          Logical Maximum (11000),    */290	0x81, 0x02,         /*          Input (Variable),           */291	0xB4,               /*          Pop,                        */292	0x09, 0x30,         /*          Usage (Tip Pressure),       */293	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */294	0x81, 0x02,         /*          Input (Variable),           */295	0xC0,               /*      End Collection,                 */296	0xC0,               /*  End Collection,                     */297	0x05, 0x01,         /*  Usage Page (Desktop),               */298	0x09, 0x02,         /*  Usage (Mouse),                      */299	0xA1, 0x01,         /*  Collection (Application),           */300	0x85, 0x01,         /*      Report ID (1),                  */301	0x09, 0x01,         /*      Usage (Pointer),                */302	0xA0,               /*      Collection (Physical),          */303	0x75, 0x08,         /*          Report Size (8),            */304	0x95, 0x03,         /*          Report Count (3),           */305	0x81, 0x03,         /*          Input (Constant, Variable), */306	0x95, 0x02,         /*          Report Count (2),           */307	0x15, 0xFF,         /*          Logical Minimum (-1),       */308	0x25, 0x01,         /*          Logical Maximum (1),        */309	0x09, 0x38,         /*          Usage (Wheel),              */310	0x0B, 0x38, 0x02,   /*          Usage (Consumer AC Pan),    */311		0x0C, 0x00,312	0x81, 0x06,         /*          Input (Variable, Relative), */313	0x95, 0x02,         /*          Report Count (2),           */314	0x81, 0x03,         /*          Input (Constant, Variable), */315	0xC0,               /*      End Collection,                 */316	0xC0,               /*  End Collection,                     */317	0x05, 0x0C,         /*  Usage Page (Consumer),              */318	0x09, 0x01,         /*  Usage (Consumer Control),           */319	0xA1, 0x01,         /*  Collection (Application),           */320	0x85, 0x0D,         /*      Report ID (13),                 */321	0x95, 0x01,         /*      Report Count (1),               */322	0x75, 0x10,         /*      Report Size (16),               */323	0x81, 0x03,         /*      Input (Constant, Variable),     */324	0x0A, 0x2F, 0x02,   /*      Usage (AC Zoom),                */325	0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */326	0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */327	0x09, 0xB6,         /*      Usage (Scan Previous Track),    */328	0x09, 0xB5,         /*      Usage (Scan Next Track),        */329	0x08,               /*      Usage (00h),                    */330	0x08,               /*      Usage (00h),                    */331	0x08,               /*      Usage (00h),                    */332	0x08,               /*      Usage (00h),                    */333	0x08,               /*      Usage (00h),                    */334	0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */335	0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */336	0x15, 0x0C,         /*      Logical Minimum (12),           */337	0x25, 0x17,         /*      Logical Maximum (23),           */338	0x75, 0x05,         /*      Report Size (5),                */339	0x80,               /*      Input,                          */340	0x75, 0x03,         /*      Report Size (3),                */341	0x81, 0x03,         /*      Input (Constant, Variable),     */342	0x75, 0x20,         /*      Report Size (32),               */343	0x81, 0x03,         /*      Input (Constant, Variable),     */344	0xC0,               /*  End Collection,                     */345	0x09, 0x01,         /*  Usage (Consumer Control),           */346	0xA1, 0x01,         /*  Collection (Application),           */347	0x85, 0x0C,         /*      Report ID (12),                 */348	0x75, 0x01,         /*      Report Size (1),                */349	0x09, 0xE9,         /*      Usage (Volume Inc),             */350	0x09, 0xEA,         /*      Usage (Volume Dec),             */351	0x09, 0xE2,         /*      Usage (Mute),                   */352	0x14,               /*      Logical Minimum (0),            */353	0x25, 0x01,         /*      Logical Maximum (1),            */354	0x95, 0x03,         /*      Report Count (3),               */355	0x81, 0x06,         /*      Input (Variable, Relative),     */356	0x95, 0x35,         /*      Report Count (53),              */357	0x81, 0x03,         /*      Input (Constant, Variable),     */358	0xC0                /*  End Collection                      */359};360 361/* Size of the original report descriptor of Media Tablet 14.1 inch */362#define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE	309363 364/* Fixed Media Tablet 14.1 inch descriptor */365static const __u8 media_tablet_14_1_inch_rdesc_fixed[] = {366	0x05, 0x0D,         /*  Usage Page (Digitizer),             */367	0x09, 0x02,         /*  Usage (Pen),                        */368	0xA1, 0x01,         /*  Collection (Application),           */369	0x85, 0x10,         /*      Report ID (16),                 */370	0x09, 0x20,         /*      Usage (Stylus),                 */371	0xA0,               /*      Collection (Physical),          */372	0x09, 0x42,         /*          Usage (Tip Switch),         */373	0x09, 0x44,         /*          Usage (Barrel Switch),      */374	0x09, 0x46,         /*          Usage (Tablet Pick),        */375	0x15, 0x01,         /*          Logical Minimum (1),        */376	0x25, 0x03,         /*          Logical Maximum (3),        */377	0x75, 0x04,         /*          Report Size (4),            */378	0x95, 0x01,         /*          Report Count (1),           */379	0x80,               /*          Input,                      */380	0x75, 0x01,         /*          Report Size (1),            */381	0x09, 0x32,         /*          Usage (In Range),           */382	0x14,               /*          Logical Minimum (0),        */383	0x25, 0x01,         /*          Logical Maximum (1),        */384	0x95, 0x01,         /*          Report Count (1),           */385	0x81, 0x02,         /*          Input (Variable),           */386	0x95, 0x03,         /*          Report Count (3),           */387	0x81, 0x03,         /*          Input (Constant, Variable), */388	0x75, 0x10,         /*          Report Size (16),           */389	0x95, 0x01,         /*          Report Count (1),           */390	0x14,               /*          Logical Minimum (0),        */391	0xA4,               /*          Push,                       */392	0x05, 0x01,         /*          Usage Page (Desktop),       */393	0x65, 0x13,         /*          Unit (Inch),                */394	0x55, 0xFD,         /*          Unit Exponent (-3),         */395	0x34,               /*          Physical Minimum (0),       */396	0x09, 0x30,         /*          Usage (X),                  */397	0x46, 0xE0, 0x2E,   /*          Physical Maximum (12000),   */398	0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),    */399	0x81, 0x02,         /*          Input (Variable),           */400	0x09, 0x31,         /*          Usage (Y),                  */401	0x46, 0x52, 0x1C,   /*          Physical Maximum (7250),    */402	0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),    */403	0x81, 0x02,         /*          Input (Variable),           */404	0xB4,               /*          Pop,                        */405	0x09, 0x30,         /*          Usage (Tip Pressure),       */406	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */407	0x81, 0x02,         /*          Input (Variable),           */408	0xC0,               /*      End Collection,                 */409	0xC0,               /*  End Collection,                     */410	0x05, 0x01,         /*  Usage Page (Desktop),               */411	0x09, 0x02,         /*  Usage (Mouse),                      */412	0xA1, 0x01,         /*  Collection (Application),           */413	0x85, 0x01,         /*      Report ID (1),                  */414	0x09, 0x01,         /*      Usage (Pointer),                */415	0xA0,               /*      Collection (Physical),          */416	0x75, 0x08,         /*          Report Size (8),            */417	0x95, 0x03,         /*          Report Count (3),           */418	0x81, 0x03,         /*          Input (Constant, Variable), */419	0x95, 0x02,         /*          Report Count (2),           */420	0x15, 0xFF,         /*          Logical Minimum (-1),       */421	0x25, 0x01,         /*          Logical Maximum (1),        */422	0x09, 0x38,         /*          Usage (Wheel),              */423	0x0B, 0x38, 0x02,   /*          Usage (Consumer AC Pan),    */424		0x0C, 0x00,425	0x81, 0x06,         /*          Input (Variable, Relative), */426	0xC0,               /*      End Collection,                 */427	0xC0,               /*  End Collection,                     */428	0x05, 0x0C,         /*  Usage Page (Consumer),              */429	0x09, 0x01,         /*  Usage (Consumer Control),           */430	0xA1, 0x01,         /*  Collection (Application),           */431	0x85, 0x0D,         /*      Report ID (13),                 */432	0x95, 0x01,         /*      Report Count (1),               */433	0x75, 0x10,         /*      Report Size (16),               */434	0x81, 0x03,         /*      Input (Constant, Variable),     */435	0x0A, 0x2F, 0x02,   /*      Usage (AC Zoom),                */436	0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */437	0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */438	0x09, 0xB6,         /*      Usage (Scan Previous Track),    */439	0x09, 0xB5,         /*      Usage (Scan Next Track),        */440	0x08,               /*      Usage (00h),                    */441	0x08,               /*      Usage (00h),                    */442	0x08,               /*      Usage (00h),                    */443	0x08,               /*      Usage (00h),                    */444	0x08,               /*      Usage (00h),                    */445	0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */446	0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */447	0x15, 0x0C,         /*      Logical Minimum (12),           */448	0x25, 0x17,         /*      Logical Maximum (23),           */449	0x75, 0x05,         /*      Report Size (5),                */450	0x80,               /*      Input,                          */451	0x75, 0x03,         /*      Report Size (3),                */452	0x81, 0x03,         /*      Input (Constant, Variable),     */453	0x75, 0x20,         /*      Report Size (32),               */454	0x81, 0x03,         /*      Input (Constant, Variable),     */455	0xC0,               /*  End Collection,                     */456	0x09, 0x01,         /*  Usage (Consumer Control),           */457	0xA1, 0x01,         /*  Collection (Application),           */458	0x85, 0x0C,         /*      Report ID (12),                 */459	0x75, 0x01,         /*      Report Size (1),                */460	0x09, 0xE9,         /*      Usage (Volume Inc),             */461	0x09, 0xEA,         /*      Usage (Volume Dec),             */462	0x09, 0xE2,         /*      Usage (Mute),                   */463	0x14,               /*      Logical Minimum (0),            */464	0x25, 0x01,         /*      Logical Maximum (1),            */465	0x95, 0x03,         /*      Report Count (3),               */466	0x81, 0x06,         /*      Input (Variable, Relative),     */467	0x75, 0x05,         /*      Report Size (5),                */468	0x81, 0x03,         /*      Input (Constant, Variable),     */469	0xC0                /*  End Collection                      */470};471 472/* Size of the original report descriptor of Sirius Battery Free Tablet */473#define SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE	335474 475/* Fixed Sirius Battery Free Tablet descriptor */476static const __u8 sirius_battery_free_tablet_rdesc_fixed[] = {477	0x05, 0x0D,         /*  Usage Page (Digitizer),             */478	0x09, 0x02,         /*  Usage (Pen),                        */479	0xA1, 0x01,         /*  Collection (Application),           */480	0x85, 0x10,         /*      Report ID (16),                 */481	0x09, 0x20,         /*      Usage (Stylus),                 */482	0xA0,               /*      Collection (Physical),          */483	0x95, 0x01,         /*          Report Count (1),           */484	0x15, 0x01,         /*          Logical Minimum (1),        */485	0x25, 0x03,         /*          Logical Maximum (3),        */486	0x75, 0x02,         /*          Report Size (2),            */487	0x09, 0x42,         /*          Usage (Tip Switch),         */488	0x09, 0x44,         /*          Usage (Barrel Switch),      */489	0x09, 0x46,         /*          Usage (Tablet Pick),        */490	0x80,               /*          Input,                      */491	0x14,               /*          Logical Minimum (0),        */492	0x25, 0x01,         /*          Logical Maximum (1),        */493	0x75, 0x01,         /*          Report Size (1),            */494	0x09, 0x3C,         /*          Usage (Invert),             */495	0x81, 0x02,         /*          Input (Variable),           */496	0x81, 0x03,         /*          Input (Constant, Variable), */497	0x09, 0x32,         /*          Usage (In Range),           */498	0x81, 0x02,         /*          Input (Variable),           */499	0x95, 0x03,         /*          Report Count (3),           */500	0x81, 0x03,         /*          Input (Constant, Variable), */501	0xA4,               /*          Push,                       */502	0x05, 0x01,         /*          Usage Page (Desktop),       */503	0x55, 0xFD,         /*          Unit Exponent (-3),         */504	0x65, 0x13,         /*          Unit (Inch),                */505	0x34,               /*          Physical Minimum (0),       */506	0x14,               /*          Logical Minimum (0),        */507	0x75, 0x10,         /*          Report Size (16),           */508	0x95, 0x01,         /*          Report Count (1),           */509	0x46, 0x10, 0x27,   /*          Physical Maximum (10000),   */510	0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */511	0x09, 0x30,         /*          Usage (X),                  */512	0x81, 0x02,         /*          Input (Variable),           */513	0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */514	0x26, 0xE0, 0x2E,   /*          Logical Maximum (12000),    */515	0x09, 0x31,         /*          Usage (Y),                  */516	0x81, 0x02,         /*          Input (Variable),           */517	0xB4,               /*          Pop,                        */518	0x75, 0x10,         /*          Report Size (16),           */519	0x95, 0x01,         /*          Report Count (1),           */520	0x14,               /*          Logical Minimum (0),        */521	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */522	0x09, 0x30,         /*          Usage (Tip Pressure),       */523	0x81, 0x02,         /*          Input (Variable),           */524	0xA4,               /*          Push,                       */525	0x55, 0xFE,         /*          Unit Exponent (-2),         */526	0x65, 0x12,         /*          Unit (Radians),             */527	0x35, 0x97,         /*          Physical Minimum (-105),    */528	0x45, 0x69,         /*          Physical Maximum (105),     */529	0x15, 0x97,         /*          Logical Minimum (-105),     */530	0x25, 0x69,         /*          Logical Maximum (105),      */531	0x75, 0x08,         /*          Report Size (8),            */532	0x95, 0x02,         /*          Report Count (2),           */533	0x09, 0x3D,         /*          Usage (X Tilt),             */534	0x09, 0x3E,         /*          Usage (Y Tilt),             */535	0x81, 0x02,         /*          Input (Variable),           */536	0xB4,               /*          Pop,                        */537	0xC0,               /*      End Collection,                 */538	0xC0,               /*  End Collection,                     */539	0x05, 0x01,         /*  Usage Page (Desktop),               */540	0x09, 0x02,         /*  Usage (Mouse),                      */541	0xA1, 0x01,         /*  Collection (Application),           */542	0x85, 0x01,         /*      Report ID (1),                  */543	0x09, 0x01,         /*      Usage (Pointer),                */544	0xA0,               /*      Collection (Physical),          */545	0x75, 0x08,         /*          Report Size (8),            */546	0x95, 0x03,         /*          Report Count (3),           */547	0x81, 0x03,         /*          Input (Constant, Variable), */548	0x09, 0x38,         /*          Usage (Wheel),              */549	0x15, 0xFF,         /*          Logical Minimum (-1),       */550	0x25, 0x01,         /*          Logical Maximum (1),        */551	0x75, 0x08,         /*          Report Size (8),            */552	0x95, 0x01,         /*          Report Count (1),           */553	0x81, 0x06,         /*          Input (Variable, Relative), */554	0x75, 0x08,         /*          Report Size (8),            */555	0x95, 0x03,         /*          Report Count (3),           */556	0x81, 0x03,         /*          Input (Constant, Variable), */557	0xC0,               /*      End Collection,                 */558	0xC0,               /*  End Collection,                     */559	0x05, 0x01,         /*  Usage Page (Desktop),               */560	0x09, 0x06,         /*  Usage (Keyboard),                   */561	0xA1, 0x01,         /*  Collection (Application),           */562	0x85, 0x0D,         /*      Report ID (13),                 */563	0x05, 0x07,         /*      Usage Page (Keyboard),          */564	0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */565	0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */566	0x14,               /*      Logical Minimum (0),            */567	0x25, 0x01,         /*      Logical Maximum (1),            */568	0x75, 0x01,         /*      Report Size (1),                */569	0x95, 0x08,         /*      Report Count (8),               */570	0x81, 0x02,         /*      Input (Variable),               */571	0x75, 0x08,         /*      Report Size (8),                */572	0x95, 0x01,         /*      Report Count (1),               */573	0x81, 0x01,         /*      Input (Constant),               */574	0x18,               /*      Usage Minimum (None),           */575	0x29, 0x65,         /*      Usage Maximum (KB Application), */576	0x14,               /*      Logical Minimum (0),            */577	0x25, 0x65,         /*      Logical Maximum (101),          */578	0x75, 0x08,         /*      Report Size (8),                */579	0x95, 0x05,         /*      Report Count (5),               */580	0x80,               /*      Input,                          */581	0xC0,               /*  End Collection,                     */582	0x05, 0x0C,         /*  Usage Page (Consumer),              */583	0x09, 0x01,         /*  Usage (Consumer Control),           */584	0xA1, 0x01,         /*  Collection (Application),           */585	0x85, 0x0C,         /*      Report ID (12),                 */586	0x09, 0xE9,         /*      Usage (Volume Inc),             */587	0x09, 0xEA,         /*      Usage (Volume Dec),             */588	0x14,               /*      Logical Minimum (0),            */589	0x25, 0x01,         /*      Logical Maximum (1),            */590	0x75, 0x01,         /*      Report Size (1),                */591	0x95, 0x02,         /*      Report Count (2),               */592	0x81, 0x02,         /*      Input (Variable),               */593	0x75, 0x06,         /*      Report Size (6),                */594	0x95, 0x01,         /*      Report Count (1),               */595	0x81, 0x03,         /*      Input (Constant, Variable),     */596	0x75, 0x10,         /*      Report Size (16),               */597	0x95, 0x03,         /*      Report Count (3),               */598	0x81, 0x03,         /*      Input (Constant, Variable),     */599	0xC0                /*  End Collection                      */600};601 602static const __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,603		unsigned int *rsize)604{605	switch (hdev->product) {606	case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:607		if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {608			*rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);609			return slim_tablet_5_8_inch_rdesc_fixed;610		}611		break;612	case USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH:613		if (*rsize == SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE) {614			*rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed);615			return slim_tablet_12_1_inch_rdesc_fixed;616		}617		break;618	case USB_DEVICE_ID_WALTOP_Q_PAD:619		if (*rsize == Q_PAD_RDESC_ORIG_SIZE) {620			*rsize = sizeof(q_pad_rdesc_fixed);621			return q_pad_rdesc_fixed;622		}623		break;624	case USB_DEVICE_ID_WALTOP_PID_0038:625		if (*rsize == PID_0038_RDESC_ORIG_SIZE) {626			*rsize = sizeof(pid_0038_rdesc_fixed);627			return pid_0038_rdesc_fixed;628		}629		break;630	case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:631		if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {632			*rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);633			return media_tablet_10_6_inch_rdesc_fixed;634		}635		break;636	case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:637		if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {638			*rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);639			return media_tablet_14_1_inch_rdesc_fixed;640		}641		break;642	case USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET:643		if (*rsize == SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE) {644			*rsize = sizeof(sirius_battery_free_tablet_rdesc_fixed);645			return sirius_battery_free_tablet_rdesc_fixed;646		}647		break;648	}649	return rdesc;650}651 652static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report,653		     u8 *data, int size)654{655	/* If this is a pen input report */656	if (report->type == HID_INPUT_REPORT && report->id == 16 && size >= 8) {657		/*658		 * Ignore reported pressure when a barrel button is pressed,659		 * because it is rarely correct.660		 */661 662		/* If a barrel button is pressed */663		if ((data[1] & 0xF) > 1) {664			/* Report zero pressure */665			data[6] = 0;666			data[7] = 0;667		}668	}669 670	/* If this is a pen input report of Sirius Battery Free Tablet */671	if (hdev->product == USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET &&672	    report->type == HID_INPUT_REPORT &&673	    report->id == 16 &&674	    size == 10) {675		/*676		 * The tablet reports tilt as roughly sin(a)*21 (18 means 60677		 * degrees).678		 *679		 * This array stores angles as radians * 100, corresponding to680		 * reported values up to 60 degrees, as expected by userspace.681		 */682		static const s8 tilt_to_radians[] = {683			0, 5, 10, 14, 19, 24, 29, 34, 40, 45,684			50, 56, 62, 68, 74, 81, 88, 96, 105685		};686 687		s8 tilt_x = (s8)data[8];688		s8 tilt_y = (s8)data[9];689		s8 sign_x = tilt_x >= 0 ? 1 : -1;690		s8 sign_y = tilt_y >= 0 ? 1 : -1;691 692		tilt_x *= sign_x;693		tilt_y *= sign_y;694 695		/*696		 * Reverse the Y Tilt direction to match the HID standard and697		 * userspace expectations. See HID Usage Tables v1.12 16.3.2698		 * Tilt Orientation.699		 */700		sign_y *= -1;701 702		/*703		 * This effectively clamps reported tilt to 60 degrees - the704		 * range expected by userspace705		 */706		if (tilt_x > ARRAY_SIZE(tilt_to_radians) - 1)707			tilt_x = ARRAY_SIZE(tilt_to_radians) - 1;708		if (tilt_y > ARRAY_SIZE(tilt_to_radians) - 1)709			tilt_y = ARRAY_SIZE(tilt_to_radians) - 1;710 711		data[8] = tilt_to_radians[tilt_x] * sign_x;712		data[9] = tilt_to_radians[tilt_y] * sign_y;713	}714 715	return 0;716}717 718static const struct hid_device_id waltop_devices[] = {719	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,720				USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },721	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,722				USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },723	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,724				USB_DEVICE_ID_WALTOP_Q_PAD) },725	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,726				USB_DEVICE_ID_WALTOP_PID_0038) },727	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,728				USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },729	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,730				USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },731	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,732			 USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },733	{ }734};735MODULE_DEVICE_TABLE(hid, waltop_devices);736 737static struct hid_driver waltop_driver = {738	.name = "waltop",739	.id_table = waltop_devices,740	.report_fixup = waltop_report_fixup,741	.raw_event = waltop_raw_event,742};743module_hid_driver(waltop_driver);744 745MODULE_DESCRIPTION("HID driver for Waltop devices not fully compliant with HID standard");746MODULE_LICENSE("GPL");747