162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * HID driver for Kye/Genius devices not fully compliant with HID standard 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2009 Jiri Kosina 662306a36Sopenharmony_ci * Copyright (c) 2009 Tomas Hanak 762306a36Sopenharmony_ci * Copyright (c) 2012 Nikolai Kondrashov 862306a36Sopenharmony_ci * Copyright (c) 2023 David Yang 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm-generic/unaligned.h> 1262306a36Sopenharmony_ci#include <linux/device.h> 1362306a36Sopenharmony_ci#include <linux/hid.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "hid-ids.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Data gathered from Database/VID0458_PID????/Vista/TBoard/default.xml in ioTablet driver 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * TODO: 2162306a36Sopenharmony_ci * - Add battery and sleep support for EasyPen M406W and MousePen M508WX 2262306a36Sopenharmony_ci * - Investigate ScrollZ.MiceFMT buttons of EasyPen M406 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic const __u8 easypen_m406_control_rdesc[] = { 2662306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 2762306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 2862306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 2962306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 3062306a36Sopenharmony_ci 0x0A, 0x45, 0x02, /* Usage (AC Rotate), */ 3162306a36Sopenharmony_ci 0x09, 0x40, /* Usage (Menu), */ 3262306a36Sopenharmony_ci 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 3362306a36Sopenharmony_ci 0x0A, 0x46, 0x02, /* Usage (AC Resize), */ 3462306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 3562306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 3662306a36Sopenharmony_ci 0x0A, 0x24, 0x02, /* Usage (AC Back), */ 3762306a36Sopenharmony_ci 0x0A, 0x25, 0x02, /* Usage (AC Forward), */ 3862306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 3962306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 4062306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 4162306a36Sopenharmony_ci 0x95, 0x08, /* Report Count (8), */ 4262306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 4362306a36Sopenharmony_ci 0x95, 0x30, /* Report Count (48), */ 4462306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 4562306a36Sopenharmony_ci 0xC0 /* End Collection */ 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic const __u8 easypen_m506_control_rdesc[] = { 4962306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 5062306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 5162306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 5262306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 5362306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 5462306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 5562306a36Sopenharmony_ci 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 5662306a36Sopenharmony_ci 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 5762306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 5862306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 5962306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 6062306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 6162306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 6262306a36Sopenharmony_ci 0x95, 0x34, /* Report Count (52), */ 6362306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 6462306a36Sopenharmony_ci 0xC0 /* End Collection */ 6562306a36Sopenharmony_ci}; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic const __u8 easypen_m406w_control_rdesc[] = { 6862306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 6962306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 7062306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 7162306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 7262306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 7362306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 7462306a36Sopenharmony_ci 0x0A, 0x01, 0x02, /* Usage (AC New), */ 7562306a36Sopenharmony_ci 0x09, 0x40, /* Usage (Menu), */ 7662306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 7762306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 7862306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 7962306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 8062306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 8162306a36Sopenharmony_ci 0x95, 0x34, /* Report Count (52), */ 8262306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 8362306a36Sopenharmony_ci 0xC0 /* End Collection */ 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic const __u8 easypen_m610x_control_rdesc[] = { 8762306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 8862306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 8962306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 9062306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 9162306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 9262306a36Sopenharmony_ci 0x0A, 0x79, 0x02, /* Usage (AC Redo Or Repeat), */ 9362306a36Sopenharmony_ci 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 9462306a36Sopenharmony_ci 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 9562306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 9662306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 9762306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 9862306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 9962306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 10062306a36Sopenharmony_ci 0x95, 0x34, /* Report Count (52), */ 10162306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 10262306a36Sopenharmony_ci 0xC0 /* End Collection */ 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic const __u8 pensketch_m912_control_rdesc[] = { 10662306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 10762306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 10862306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 10962306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 11062306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 11162306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 11262306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 11362306a36Sopenharmony_ci 0x95, 0x08, /* Report Count (8), */ 11462306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 11562306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 11662306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 11762306a36Sopenharmony_ci 0x0A, 0x01, 0x02, /* Usage (AC New), */ 11862306a36Sopenharmony_ci 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 11962306a36Sopenharmony_ci 0x0A, 0x25, 0x02, /* Usage (AC Forward), */ 12062306a36Sopenharmony_ci 0x0A, 0x24, 0x02, /* Usage (AC Back), */ 12162306a36Sopenharmony_ci 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 12262306a36Sopenharmony_ci 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 12362306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 12462306a36Sopenharmony_ci 0x95, 0x30, /* Report Count (48), */ 12562306a36Sopenharmony_ci 0x81, 0x03, /* Input (Constant, Variable), */ 12662306a36Sopenharmony_ci 0xC0 /* End Collection */ 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic const __u8 mousepen_m508wx_control_rdesc[] = { 13062306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 13162306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 13262306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 13362306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 13462306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 13562306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 13662306a36Sopenharmony_ci 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 13762306a36Sopenharmony_ci 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 13862306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 13962306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 14062306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 14162306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 14262306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 14362306a36Sopenharmony_ci 0x95, 0x34, /* Report Count (52), */ 14462306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 14562306a36Sopenharmony_ci 0xC0 /* End Collection */ 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic const __u8 mousepen_m508x_control_rdesc[] = { 14962306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 15062306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 15162306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 15262306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 15362306a36Sopenharmony_ci 0x0A, 0x01, 0x02, /* Usage (AC New), */ 15462306a36Sopenharmony_ci 0x09, 0x40, /* Usage (Menu), */ 15562306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 15662306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 15762306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 15862306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 15962306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 16062306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 16162306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 16262306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 16362306a36Sopenharmony_ci 0x15, 0xFF, /* Logical Minimum (-1), */ 16462306a36Sopenharmony_ci 0x95, 0x10, /* Report Count (16), */ 16562306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 16662306a36Sopenharmony_ci 0x0A, 0x35, 0x02, /* Usage (AC Scroll), */ 16762306a36Sopenharmony_ci 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 16862306a36Sopenharmony_ci 0x0A, 0x38, 0x02, /* Usage (AC Pan), */ 16962306a36Sopenharmony_ci 0x75, 0x08, /* Report Size (8), */ 17062306a36Sopenharmony_ci 0x95, 0x03, /* Report Count (3), */ 17162306a36Sopenharmony_ci 0x81, 0x06, /* Input (Variable, Relative), */ 17262306a36Sopenharmony_ci 0x95, 0x01, /* Report Count (1), */ 17362306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 17462306a36Sopenharmony_ci 0xC0 /* End Collection */ 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic const __u8 easypen_m406xe_control_rdesc[] = { 17862306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 17962306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 18062306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 18162306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 18262306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 18362306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 18462306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 18562306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 18662306a36Sopenharmony_ci 0x0A, 0x79, 0x02, /* Usage (AC Redo Or Repeat), */ 18762306a36Sopenharmony_ci 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 18862306a36Sopenharmony_ci 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 18962306a36Sopenharmony_ci 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 19062306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 19162306a36Sopenharmony_ci 0x95, 0x34, /* Report Count (52), */ 19262306a36Sopenharmony_ci 0x81, 0x03, /* Input (Constant, Variable), */ 19362306a36Sopenharmony_ci 0xC0 /* End Collection */ 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic const __u8 pensketch_t609a_control_rdesc[] = { 19762306a36Sopenharmony_ci 0x05, 0x0C, /* Usage Page (Consumer), */ 19862306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Consumer Control), */ 19962306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 20062306a36Sopenharmony_ci 0x85, 0x12, /* Report ID (18), */ 20162306a36Sopenharmony_ci 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 20262306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 20362306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 20462306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 20562306a36Sopenharmony_ci 0x95, 0x08, /* Report Count (8), */ 20662306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 20762306a36Sopenharmony_ci 0x95, 0x37, /* Report Count (55), */ 20862306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 20962306a36Sopenharmony_ci 0xC0 /* End Collection */ 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* Fix indexes in kye_tablet_fixup if you change this */ 21362306a36Sopenharmony_cistatic const __u8 kye_tablet_rdesc[] = { 21462306a36Sopenharmony_ci 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 21562306a36Sopenharmony_ci 0x09, 0x01, /* Usage (01h), */ 21662306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 21762306a36Sopenharmony_ci 0x85, 0x05, /* Report ID (5), */ 21862306a36Sopenharmony_ci 0x09, 0x01, /* Usage (01h), */ 21962306a36Sopenharmony_ci 0x15, 0x81, /* Logical Minimum (-127), */ 22062306a36Sopenharmony_ci 0x25, 0x7F, /* Logical Maximum (127), */ 22162306a36Sopenharmony_ci 0x75, 0x08, /* Report Size (8), */ 22262306a36Sopenharmony_ci 0x95, 0x07, /* Report Count (7), */ 22362306a36Sopenharmony_ci 0xB1, 0x02, /* Feature (Variable), */ 22462306a36Sopenharmony_ci 0xC0, /* End Collection, */ 22562306a36Sopenharmony_ci 0x05, 0x0D, /* Usage Page (Digitizer), */ 22662306a36Sopenharmony_ci 0x09, 0x01, /* Usage (Digitizer), */ 22762306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 22862306a36Sopenharmony_ci 0x85, 0x10, /* Report ID (16), */ 22962306a36Sopenharmony_ci 0x09, 0x20, /* Usage (Stylus), */ 23062306a36Sopenharmony_ci 0xA0, /* Collection (Physical), */ 23162306a36Sopenharmony_ci 0x09, 0x42, /* Usage (Tip Switch), */ 23262306a36Sopenharmony_ci 0x09, 0x44, /* Usage (Barrel Switch), */ 23362306a36Sopenharmony_ci 0x09, 0x46, /* Usage (Tablet Pick), */ 23462306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 23562306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 23662306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 23762306a36Sopenharmony_ci 0x95, 0x03, /* Report Count (3), */ 23862306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 23962306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 24062306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 24162306a36Sopenharmony_ci 0x09, 0x32, /* Usage (In Range), */ 24262306a36Sopenharmony_ci 0x95, 0x01, /* Report Count (1), */ 24362306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 24462306a36Sopenharmony_ci 0x75, 0x10, /* Report Size (16), */ 24562306a36Sopenharmony_ci 0xA4, /* Push, */ 24662306a36Sopenharmony_ci 0x05, 0x01, /* Usage Page (Desktop), */ 24762306a36Sopenharmony_ci 0x09, 0x30, /* Usage (X), */ 24862306a36Sopenharmony_ci 0x27, 0xFF, 0x7F, 0x00, 0x00, /* Logical Maximum (32767), */ 24962306a36Sopenharmony_ci 0x34, /* Physical Minimum (0), */ 25062306a36Sopenharmony_ci 0x47, 0x00, 0x00, 0x00, 0x00, /* Physical Maximum (0), */ 25162306a36Sopenharmony_ci 0x65, 0x11, /* Unit (Centimeter), */ 25262306a36Sopenharmony_ci 0x55, 0x00, /* Unit Exponent (0), */ 25362306a36Sopenharmony_ci 0x75, 0x10, /* Report Size (16), */ 25462306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 25562306a36Sopenharmony_ci 0x09, 0x31, /* Usage (Y), */ 25662306a36Sopenharmony_ci 0x27, 0xFF, 0x7F, 0x00, 0x00, /* Logical Maximum (32767), */ 25762306a36Sopenharmony_ci 0x47, 0x00, 0x00, 0x00, 0x00, /* Physical Maximum (0), */ 25862306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 25962306a36Sopenharmony_ci 0xB4, /* Pop, */ 26062306a36Sopenharmony_ci 0x05, 0x0D, /* Usage Page (Digitizer), */ 26162306a36Sopenharmony_ci 0x09, 0x30, /* Usage (Tip Pressure), */ 26262306a36Sopenharmony_ci 0x27, 0xFF, 0x07, 0x00, 0x00, /* Logical Maximum (2047), */ 26362306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 26462306a36Sopenharmony_ci 0xC0, /* End Collection, */ 26562306a36Sopenharmony_ci 0xC0, /* End Collection, */ 26662306a36Sopenharmony_ci 0x05, 0x0D, /* Usage Page (Digitizer), */ 26762306a36Sopenharmony_ci 0x09, 0x21, /* Usage (Puck), */ 26862306a36Sopenharmony_ci 0xA1, 0x01, /* Collection (Application), */ 26962306a36Sopenharmony_ci 0x85, 0x11, /* Report ID (17), */ 27062306a36Sopenharmony_ci 0x09, 0x21, /* Usage (Puck), */ 27162306a36Sopenharmony_ci 0xA0, /* Collection (Physical), */ 27262306a36Sopenharmony_ci 0x05, 0x09, /* Usage Page (Button), */ 27362306a36Sopenharmony_ci 0x19, 0x01, /* Usage Minimum (01h), */ 27462306a36Sopenharmony_ci 0x29, 0x03, /* Usage Maximum (03h), */ 27562306a36Sopenharmony_ci 0x14, /* Logical Minimum (0), */ 27662306a36Sopenharmony_ci 0x25, 0x01, /* Logical Maximum (1), */ 27762306a36Sopenharmony_ci 0x75, 0x01, /* Report Size (1), */ 27862306a36Sopenharmony_ci 0x95, 0x03, /* Report Count (3), */ 27962306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 28062306a36Sopenharmony_ci 0x95, 0x04, /* Report Count (4), */ 28162306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 28262306a36Sopenharmony_ci 0x05, 0x0D, /* Usage Page (Digitizer), */ 28362306a36Sopenharmony_ci 0x09, 0x32, /* Usage (In Range), */ 28462306a36Sopenharmony_ci 0x95, 0x01, /* Report Count (1), */ 28562306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 28662306a36Sopenharmony_ci 0x05, 0x01, /* Usage Page (Desktop), */ 28762306a36Sopenharmony_ci 0xA4, /* Push, */ 28862306a36Sopenharmony_ci 0x09, 0x30, /* Usage (X), */ 28962306a36Sopenharmony_ci 0x27, 0xFF, 0x7F, 0x00, 0x00, /* Logical Maximum (32767), */ 29062306a36Sopenharmony_ci 0x34, /* Physical Minimum (0), */ 29162306a36Sopenharmony_ci 0x47, 0x00, 0x00, 0x00, 0x00, /* Physical Maximum (0), */ 29262306a36Sopenharmony_ci 0x65, 0x11, /* Unit (Centimeter), */ 29362306a36Sopenharmony_ci 0x55, 0x00, /* Unit Exponent (0), */ 29462306a36Sopenharmony_ci 0x75, 0x10, /* Report Size (16), */ 29562306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 29662306a36Sopenharmony_ci 0x09, 0x31, /* Usage (Y), */ 29762306a36Sopenharmony_ci 0x27, 0xFF, 0x7F, 0x00, 0x00, /* Logical Maximum (32767), */ 29862306a36Sopenharmony_ci 0x47, 0x00, 0x00, 0x00, 0x00, /* Physical Maximum (0), */ 29962306a36Sopenharmony_ci 0x81, 0x02, /* Input (Variable), */ 30062306a36Sopenharmony_ci 0xB4, /* Pop, */ 30162306a36Sopenharmony_ci 0x09, 0x38, /* Usage (Wheel), */ 30262306a36Sopenharmony_ci 0x15, 0xFF, /* Logical Minimum (-1), */ 30362306a36Sopenharmony_ci 0x75, 0x08, /* Report Size (8), */ 30462306a36Sopenharmony_ci 0x95, 0x01, /* Report Count (1), */ 30562306a36Sopenharmony_ci 0x81, 0x06, /* Input (Variable, Relative), */ 30662306a36Sopenharmony_ci 0x81, 0x01, /* Input (Constant), */ 30762306a36Sopenharmony_ci 0xC0, /* End Collection, */ 30862306a36Sopenharmony_ci 0xC0 /* End Collection */ 30962306a36Sopenharmony_ci}; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic const struct kye_tablet_info { 31262306a36Sopenharmony_ci __u32 product; 31362306a36Sopenharmony_ci __s32 x_logical_maximum; 31462306a36Sopenharmony_ci __s32 y_logical_maximum; 31562306a36Sopenharmony_ci __s32 pressure_logical_maximum; 31662306a36Sopenharmony_ci __s32 x_physical_maximum; 31762306a36Sopenharmony_ci __s32 y_physical_maximum; 31862306a36Sopenharmony_ci __s8 unit_exponent; 31962306a36Sopenharmony_ci __s8 unit; 32062306a36Sopenharmony_ci bool has_punk; 32162306a36Sopenharmony_ci unsigned int control_rsize; 32262306a36Sopenharmony_ci const __u8 *control_rdesc; 32362306a36Sopenharmony_ci} kye_tablets_info[] = { 32462306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_M406, /* 0x5005 */ 32562306a36Sopenharmony_ci 15360, 10240, 1023, 6, 4, 0, 0x13, false, 32662306a36Sopenharmony_ci sizeof(easypen_m406_control_rdesc), easypen_m406_control_rdesc}, 32762306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_M506, /* 0x500F */ 32862306a36Sopenharmony_ci 24576, 20480, 1023, 6, 5, 0, 0x13, false, 32962306a36Sopenharmony_ci sizeof(easypen_m506_control_rdesc), easypen_m506_control_rdesc}, 33062306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_I405X, /* 0x5010 */ 33162306a36Sopenharmony_ci 14080, 10240, 1023, 55, 40, -1, 0x13, false}, 33262306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_MOUSEPEN_I608X, /* 0x5011 */ 33362306a36Sopenharmony_ci 20480, 15360, 2047, 8, 6, 0, 0x13, true}, 33462306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_M406W, /* 0x5012 */ 33562306a36Sopenharmony_ci 15360, 10240, 1023, 6, 4, 0, 0x13, false, 33662306a36Sopenharmony_ci sizeof(easypen_m406w_control_rdesc), easypen_m406w_control_rdesc}, 33762306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_M610X, /* 0x5013 */ 33862306a36Sopenharmony_ci 40960, 25600, 1023, 1000, 625, -2, 0x13, false, 33962306a36Sopenharmony_ci sizeof(easypen_m610x_control_rdesc), easypen_m610x_control_rdesc}, 34062306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_340, /* 0x5014 */ 34162306a36Sopenharmony_ci 10240, 7680, 1023, 4, 3, 0, 0x13, false}, 34262306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_PENSKETCH_M912, /* 0x5015 */ 34362306a36Sopenharmony_ci 61440, 46080, 2047, 12, 9, 0, 0x13, true, 34462306a36Sopenharmony_ci sizeof(pensketch_m912_control_rdesc), pensketch_m912_control_rdesc}, 34562306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_MOUSEPEN_M508WX, /* 0x5016 */ 34662306a36Sopenharmony_ci 40960, 25600, 2047, 8, 5, 0, 0x13, true, 34762306a36Sopenharmony_ci sizeof(mousepen_m508wx_control_rdesc), mousepen_m508wx_control_rdesc}, 34862306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_MOUSEPEN_M508X, /* 0x5017 */ 34962306a36Sopenharmony_ci 40960, 25600, 2047, 8, 5, 0, 0x13, true, 35062306a36Sopenharmony_ci sizeof(mousepen_m508x_control_rdesc), mousepen_m508x_control_rdesc}, 35162306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_EASYPEN_M406XE, /* 0x5019 */ 35262306a36Sopenharmony_ci 15360, 10240, 1023, 6, 4, 0, 0x13, false, 35362306a36Sopenharmony_ci sizeof(easypen_m406xe_control_rdesc), easypen_m406xe_control_rdesc}, 35462306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2, /* 0x501A */ 35562306a36Sopenharmony_ci 40960, 30720, 2047, 8, 6, 0, 0x13, true}, 35662306a36Sopenharmony_ci {USB_DEVICE_ID_KYE_PENSKETCH_T609A, /* 0x501B */ 35762306a36Sopenharmony_ci 43520, 28160, 1023, 85, 55, -1, 0x13, false, 35862306a36Sopenharmony_ci sizeof(pensketch_t609a_control_rdesc), pensketch_t609a_control_rdesc}, 35962306a36Sopenharmony_ci {} 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic __u8 *kye_consumer_control_fixup(struct hid_device *hdev, __u8 *rdesc, 36362306a36Sopenharmony_ci unsigned int *rsize, int offset, const char *device_name) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci /* 36662306a36Sopenharmony_ci * the fixup that need to be done: 36762306a36Sopenharmony_ci * - change Usage Maximum in the Consumer Control 36862306a36Sopenharmony_ci * (report ID 3) to a reasonable value 36962306a36Sopenharmony_ci */ 37062306a36Sopenharmony_ci if (*rsize >= offset + 31 && 37162306a36Sopenharmony_ci /* Usage Page (Consumer Devices) */ 37262306a36Sopenharmony_ci rdesc[offset] == 0x05 && rdesc[offset + 1] == 0x0c && 37362306a36Sopenharmony_ci /* Usage (Consumer Control) */ 37462306a36Sopenharmony_ci rdesc[offset + 2] == 0x09 && rdesc[offset + 3] == 0x01 && 37562306a36Sopenharmony_ci /* Usage Maximum > 12287 */ 37662306a36Sopenharmony_ci rdesc[offset + 10] == 0x2a && rdesc[offset + 12] > 0x2f) { 37762306a36Sopenharmony_ci hid_info(hdev, "fixing up %s report descriptor\n", device_name); 37862306a36Sopenharmony_ci rdesc[offset + 12] = 0x2f; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci return rdesc; 38162306a36Sopenharmony_ci} 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci/* 38462306a36Sopenharmony_ci * Fix tablet descriptor of so-called "DataFormat 2". 38562306a36Sopenharmony_ci * 38662306a36Sopenharmony_ci * Though we may achieve a usable descriptor from original vendor-defined one, 38762306a36Sopenharmony_ci * some problems exist: 38862306a36Sopenharmony_ci * - Their Logical Maximum never exceed 32767 (7F FF), though device do report 38962306a36Sopenharmony_ci * values greater than that; 39062306a36Sopenharmony_ci * - Physical Maximums are arbitrarily filled (always equal to Logical 39162306a36Sopenharmony_ci * Maximum); 39262306a36Sopenharmony_ci * - Detail for control buttons are not provided (a vendor-defined Usage Page 39362306a36Sopenharmony_ci * with fixed content). 39462306a36Sopenharmony_ci * 39562306a36Sopenharmony_ci * Thus we use a pre-defined parameter table rather than digging it from 39662306a36Sopenharmony_ci * original descriptor. 39762306a36Sopenharmony_ci * 39862306a36Sopenharmony_ci * We may as well write a fallback routine for unrecognized kye tablet, but it's 39962306a36Sopenharmony_ci * clear kye are unlikely to produce new models in the foreseeable future, so we 40062306a36Sopenharmony_ci * simply enumerate all possible models. 40162306a36Sopenharmony_ci */ 40262306a36Sopenharmony_cistatic __u8 *kye_tablet_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci const struct kye_tablet_info *info; 40562306a36Sopenharmony_ci unsigned int newsize; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci if (*rsize < sizeof(kye_tablet_rdesc)) { 40862306a36Sopenharmony_ci hid_warn(hdev, 40962306a36Sopenharmony_ci "tablet report size too small, or kye_tablet_rdesc unexpectedly large\n"); 41062306a36Sopenharmony_ci return rdesc; 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci for (info = kye_tablets_info; info->product; info++) { 41462306a36Sopenharmony_ci if (hdev->product == info->product) 41562306a36Sopenharmony_ci break; 41662306a36Sopenharmony_ci } 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci if (!info->product) { 41962306a36Sopenharmony_ci hid_err(hdev, "tablet unknown, someone forget to add kye_tablet_info entry?\n"); 42062306a36Sopenharmony_ci return rdesc; 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci newsize = info->has_punk ? sizeof(kye_tablet_rdesc) : 112; 42462306a36Sopenharmony_ci memcpy(rdesc, kye_tablet_rdesc, newsize); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci put_unaligned_le32(info->x_logical_maximum, rdesc + 66); 42762306a36Sopenharmony_ci put_unaligned_le32(info->x_physical_maximum, rdesc + 72); 42862306a36Sopenharmony_ci rdesc[77] = info->unit; 42962306a36Sopenharmony_ci rdesc[79] = info->unit_exponent; 43062306a36Sopenharmony_ci put_unaligned_le32(info->y_logical_maximum, rdesc + 87); 43162306a36Sopenharmony_ci put_unaligned_le32(info->y_physical_maximum, rdesc + 92); 43262306a36Sopenharmony_ci put_unaligned_le32(info->pressure_logical_maximum, rdesc + 104); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci if (info->has_punk) { 43562306a36Sopenharmony_ci put_unaligned_le32(info->x_logical_maximum, rdesc + 156); 43662306a36Sopenharmony_ci put_unaligned_le32(info->x_physical_maximum, rdesc + 162); 43762306a36Sopenharmony_ci rdesc[167] = info->unit; 43862306a36Sopenharmony_ci rdesc[169] = info->unit_exponent; 43962306a36Sopenharmony_ci put_unaligned_le32(info->y_logical_maximum, rdesc + 177); 44062306a36Sopenharmony_ci put_unaligned_le32(info->y_physical_maximum, rdesc + 182); 44162306a36Sopenharmony_ci } 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci if (info->control_rsize) { 44462306a36Sopenharmony_ci if (newsize + info->control_rsize > *rsize) 44562306a36Sopenharmony_ci hid_err(hdev, "control rdesc unexpectedly large"); 44662306a36Sopenharmony_ci else { 44762306a36Sopenharmony_ci memcpy(rdesc + newsize, info->control_rdesc, info->control_rsize); 44862306a36Sopenharmony_ci newsize += info->control_rsize; 44962306a36Sopenharmony_ci } 45062306a36Sopenharmony_ci } 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci *rsize = newsize; 45362306a36Sopenharmony_ci return rdesc; 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, 45762306a36Sopenharmony_ci unsigned int *rsize) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci switch (hdev->product) { 46062306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_ERGO_525V: 46162306a36Sopenharmony_ci /* the fixups that need to be done: 46262306a36Sopenharmony_ci * - change led usage page to button for extra buttons 46362306a36Sopenharmony_ci * - report size 8 count 1 must be size 1 count 8 for button 46462306a36Sopenharmony_ci * bitfield 46562306a36Sopenharmony_ci * - change the button usage range to 4-7 for the extra 46662306a36Sopenharmony_ci * buttons 46762306a36Sopenharmony_ci */ 46862306a36Sopenharmony_ci if (*rsize >= 75 && 46962306a36Sopenharmony_ci rdesc[61] == 0x05 && rdesc[62] == 0x08 && 47062306a36Sopenharmony_ci rdesc[63] == 0x19 && rdesc[64] == 0x08 && 47162306a36Sopenharmony_ci rdesc[65] == 0x29 && rdesc[66] == 0x0f && 47262306a36Sopenharmony_ci rdesc[71] == 0x75 && rdesc[72] == 0x08 && 47362306a36Sopenharmony_ci rdesc[73] == 0x95 && rdesc[74] == 0x01) { 47462306a36Sopenharmony_ci hid_info(hdev, 47562306a36Sopenharmony_ci "fixing up Kye/Genius Ergo Mouse " 47662306a36Sopenharmony_ci "report descriptor\n"); 47762306a36Sopenharmony_ci rdesc[62] = 0x09; 47862306a36Sopenharmony_ci rdesc[64] = 0x04; 47962306a36Sopenharmony_ci rdesc[66] = 0x07; 48062306a36Sopenharmony_ci rdesc[72] = 0x01; 48162306a36Sopenharmony_ci rdesc[74] = 0x08; 48262306a36Sopenharmony_ci } 48362306a36Sopenharmony_ci break; 48462306a36Sopenharmony_ci case USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE: 48562306a36Sopenharmony_ci rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104, 48662306a36Sopenharmony_ci "Genius Gila Gaming Mouse"); 48762306a36Sopenharmony_ci break; 48862306a36Sopenharmony_ci case USB_DEVICE_ID_GENIUS_MANTICORE: 48962306a36Sopenharmony_ci rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104, 49062306a36Sopenharmony_ci "Genius Manticore Keyboard"); 49162306a36Sopenharmony_ci break; 49262306a36Sopenharmony_ci case USB_DEVICE_ID_GENIUS_GX_IMPERATOR: 49362306a36Sopenharmony_ci rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 83, 49462306a36Sopenharmony_ci "Genius Gx Imperator Keyboard"); 49562306a36Sopenharmony_ci break; 49662306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406: 49762306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M506: 49862306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_I405X: 49962306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: 50062306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406W: 50162306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M610X: 50262306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_340: 50362306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_PENSKETCH_M912: 50462306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_M508WX: 50562306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_M508X: 50662306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406XE: 50762306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2: 50862306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_PENSKETCH_T609A: 50962306a36Sopenharmony_ci rdesc = kye_tablet_fixup(hdev, rdesc, rsize); 51062306a36Sopenharmony_ci break; 51162306a36Sopenharmony_ci } 51262306a36Sopenharmony_ci return rdesc; 51362306a36Sopenharmony_ci} 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_cistatic int kye_tablet_enable(struct hid_device *hdev) 51662306a36Sopenharmony_ci{ 51762306a36Sopenharmony_ci struct list_head *list; 51862306a36Sopenharmony_ci struct list_head *head; 51962306a36Sopenharmony_ci struct hid_report *report; 52062306a36Sopenharmony_ci __s32 *value; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci list = &hdev->report_enum[HID_FEATURE_REPORT].report_list; 52362306a36Sopenharmony_ci list_for_each(head, list) { 52462306a36Sopenharmony_ci report = list_entry(head, struct hid_report, list); 52562306a36Sopenharmony_ci if (report->id == 5) 52662306a36Sopenharmony_ci break; 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci if (head == list) { 53062306a36Sopenharmony_ci hid_err(hdev, "tablet-enabling feature report not found\n"); 53162306a36Sopenharmony_ci return -ENODEV; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci if (report->maxfield < 1 || report->field[0]->report_count < 7) { 53562306a36Sopenharmony_ci hid_err(hdev, "invalid tablet-enabling feature report\n"); 53662306a36Sopenharmony_ci return -ENODEV; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci value = report->field[0]->value; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci /* 54262306a36Sopenharmony_ci * The code is for DataFormat 2 of config xml. They have no obvious 54362306a36Sopenharmony_ci * meaning (at least not configurable in Windows driver) except enabling 54462306a36Sopenharmony_ci * fully-functional tablet mode (absolute positioning). Otherwise, the 54562306a36Sopenharmony_ci * tablet acts like a relative mouse. 54662306a36Sopenharmony_ci * 54762306a36Sopenharmony_ci * Though there're magic codes for DataFormat 3 and 4, no devices use 54862306a36Sopenharmony_ci * these DataFormats. 54962306a36Sopenharmony_ci */ 55062306a36Sopenharmony_ci value[0] = 0x12; 55162306a36Sopenharmony_ci value[1] = 0x10; 55262306a36Sopenharmony_ci value[2] = 0x11; 55362306a36Sopenharmony_ci value[3] = 0x12; 55462306a36Sopenharmony_ci value[4] = 0x00; 55562306a36Sopenharmony_ci value[5] = 0x00; 55662306a36Sopenharmony_ci value[6] = 0x00; 55762306a36Sopenharmony_ci hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci return 0; 56062306a36Sopenharmony_ci} 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_cistatic int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci int ret; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci ret = hid_parse(hdev); 56762306a36Sopenharmony_ci if (ret) { 56862306a36Sopenharmony_ci hid_err(hdev, "parse failed\n"); 56962306a36Sopenharmony_ci goto err; 57062306a36Sopenharmony_ci } 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 57362306a36Sopenharmony_ci if (ret) { 57462306a36Sopenharmony_ci hid_err(hdev, "hw start failed\n"); 57562306a36Sopenharmony_ci goto err; 57662306a36Sopenharmony_ci } 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci switch (id->product) { 57962306a36Sopenharmony_ci case USB_DEVICE_ID_GENIUS_MANTICORE: 58062306a36Sopenharmony_ci /* 58162306a36Sopenharmony_ci * The manticore keyboard needs to have all the interfaces 58262306a36Sopenharmony_ci * opened at least once to be fully functional. 58362306a36Sopenharmony_ci */ 58462306a36Sopenharmony_ci if (hid_hw_open(hdev)) 58562306a36Sopenharmony_ci hid_hw_close(hdev); 58662306a36Sopenharmony_ci break; 58762306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406: 58862306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M506: 58962306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_I405X: 59062306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: 59162306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406W: 59262306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M610X: 59362306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_340: 59462306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_PENSKETCH_M912: 59562306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_M508WX: 59662306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_M508X: 59762306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_EASYPEN_M406XE: 59862306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2: 59962306a36Sopenharmony_ci case USB_DEVICE_ID_KYE_PENSKETCH_T609A: 60062306a36Sopenharmony_ci ret = kye_tablet_enable(hdev); 60162306a36Sopenharmony_ci if (ret) { 60262306a36Sopenharmony_ci hid_err(hdev, "tablet enabling failed\n"); 60362306a36Sopenharmony_ci goto enabling_err; 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci } 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci return 0; 60962306a36Sopenharmony_cienabling_err: 61062306a36Sopenharmony_ci hid_hw_stop(hdev); 61162306a36Sopenharmony_cierr: 61262306a36Sopenharmony_ci return ret; 61362306a36Sopenharmony_ci} 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_cistatic const struct hid_device_id kye_devices[] = { 61662306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, 61762306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 61862306a36Sopenharmony_ci USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, 61962306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 62062306a36Sopenharmony_ci USB_DEVICE_ID_GENIUS_MANTICORE) }, 62162306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 62262306a36Sopenharmony_ci USB_DEVICE_ID_GENIUS_GX_IMPERATOR) }, 62362306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 62462306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_M406) }, 62562306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 62662306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_M506) }, 62762306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 62862306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_I405X) }, 62962306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 63062306a36Sopenharmony_ci USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, 63162306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 63262306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_M406W) }, 63362306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 63462306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_M610X) }, 63562306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 63662306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_340) }, 63762306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 63862306a36Sopenharmony_ci USB_DEVICE_ID_KYE_PENSKETCH_M912) }, 63962306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 64062306a36Sopenharmony_ci USB_DEVICE_ID_KYE_MOUSEPEN_M508WX) }, 64162306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 64262306a36Sopenharmony_ci USB_DEVICE_ID_KYE_MOUSEPEN_M508X) }, 64362306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 64462306a36Sopenharmony_ci USB_DEVICE_ID_KYE_EASYPEN_M406XE) }, 64562306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 64662306a36Sopenharmony_ci USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2) }, 64762306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 64862306a36Sopenharmony_ci USB_DEVICE_ID_KYE_PENSKETCH_T609A) }, 64962306a36Sopenharmony_ci { } 65062306a36Sopenharmony_ci}; 65162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(hid, kye_devices); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_cistatic struct hid_driver kye_driver = { 65462306a36Sopenharmony_ci .name = "kye", 65562306a36Sopenharmony_ci .id_table = kye_devices, 65662306a36Sopenharmony_ci .probe = kye_probe, 65762306a36Sopenharmony_ci .report_fixup = kye_report_fixup, 65862306a36Sopenharmony_ci}; 65962306a36Sopenharmony_cimodule_hid_driver(kye_driver); 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 662