Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-linus-2022052401' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID updates from Jiri Kosina:

- support for pens with 3 buttons with Wacom driver (Joshua Dickens)

- support for HID_DG_SCANTIME to report the timestamp for pen and touch
events in Wacom driver (Joshua Dickens)

- support for sensor discovery in amd-sfh driver (Basavaraj Natikar)

- support for wider variety of Huion tablets ported from DIGImend
project (José Expósito, Nikolai Kondrashov)

- new device IDs and other assorted small code cleanups

* tag 'for-linus-2022052401' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (44 commits)
HID: apple: Properly handle function keys on Keychron keyboards
HID: uclogic: Switch to Digitizer usage for styluses
HID: uclogic: Add pen support for XP-PEN Star 06
HID: uclogic: Differentiate touch ring and touch strip
HID: uclogic: Always shift touch reports to zero
HID: uclogic: Do not focus on touch ring only
HID: uclogic: Return raw parameters from v2 pen init
HID: uclogic: Move param printing to a function
HID: core: Display "SENSOR HUB" for sensor hub bus string in hid_info
HID: amd_sfh: Move bus declaration outside of amd-sfh
HID: amd_sfh: Add physical location to HID device
HID: amd_sfh: Modify the hid name
HID: amd_sfh: Modify the bus name
HID: amd_sfh: Add sensor name by index for debug info
HID: amd_sfh: Add support for sensor discovery
HID: bigben: fix slab-out-of-bounds Write in bigben_probe
Hid: wacom: Fix kernel test robot warning
HID: uclogic: Disable pen usage for Huion keyboard interfaces
HID: uclogic: Support disabling pen usage
HID: uclogic: Pass keyboard reports as is
...

+1054 -188
+8 -1
MAINTAINERS
··· 1044 1044 F: drivers/net/ethernet/amd/xgbe/ 1045 1045 1046 1046 AMD SENSOR FUSION HUB DRIVER 1047 - M: Nehal Shah <nehal-bakulchandra.shah@amd.com> 1048 1047 M: Basavaraj Natikar <basavaraj.natikar@amd.com> 1049 1048 L: linux-input@vger.kernel.org 1050 1049 S: Maintained ··· 8764 8765 F: drivers/hid/hid-sensor-* 8765 8766 F: drivers/iio/*/hid-* 8766 8767 F: include/linux/hid-sensor-* 8768 + 8769 + HID WACOM DRIVER 8770 + M: Ping Cheng <ping.cheng@wacom.com> 8771 + M: Jason Gerecke <jason.gerecke@wacom.com> 8772 + L: linux-input@vger.kernel.org 8773 + S: Maintained 8774 + F: drivers/hid/wacom.h 8775 + F: drivers/hid/wacom_* 8767 8776 8768 8777 HIGH-RESOLUTION TIMERS, CLOCKEVENTS 8769 8778 M: Thomas Gleixner <tglx@linutronix.de>
+8
drivers/hid/Kconfig
··· 697 697 Say Y here if you have HJZ Mayflash PS3 game controller adapters 698 698 and want to enable force feedback support. 699 699 700 + config HID_MEGAWORLD_FF 701 + tristate "Mega World based game controller force feedback support" 702 + depends on USB_HID 703 + select INPUT_FF_MEMLESS 704 + help 705 + Say Y here if you have a Mega World based game controller and want 706 + to have force feedback support for it. 707 + 700 708 config HID_REDRAGON 701 709 tristate "Redragon keyboards" 702 710 depends on HID
+1
drivers/hid/Makefile
··· 77 77 obj-$(CONFIG_HID_MALTRON) += hid-maltron.o 78 78 obj-$(CONFIG_HID_MCP2221) += hid-mcp2221.o 79 79 obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o 80 + obj-$(CONFIG_HID_MEGAWORLD_FF) += hid-megaworld.o 80 81 obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o 81 82 obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o 82 83 obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
+39 -6
drivers/hid/amd-sfh-hid/amd_sfh_client.c
··· 141 141 return sensor_sts; 142 142 } 143 143 144 + const char *get_sensor_name(int idx) 145 + { 146 + switch (idx) { 147 + case accel_idx: 148 + return "accelerometer"; 149 + case gyro_idx: 150 + return "gyroscope"; 151 + case mag_idx: 152 + return "magnetometer"; 153 + case als_idx: 154 + return "ALS"; 155 + case HPD_IDX: 156 + return "HPD"; 157 + default: 158 + return "unknown sensor type"; 159 + } 160 + } 161 + 144 162 int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) 145 163 { 146 164 struct amd_input_data *in_data = &privdata->in_data; ··· 237 219 (privdata, cl_data->sensor_idx[i], SENSOR_DISABLED); 238 220 if (status != SENSOR_ENABLED) 239 221 cl_data->sensor_sts[i] = SENSOR_DISABLED; 240 - dev_dbg(dev, "sid 0x%x status 0x%x\n", 241 - cl_data->sensor_idx[i], cl_data->sensor_sts[i]); 222 + dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 223 + cl_data->sensor_idx[i], 224 + get_sensor_name(cl_data->sensor_idx[i]), 225 + cl_data->sensor_sts[i]); 242 226 goto cleanup; 243 227 } 244 228 } 245 - dev_dbg(dev, "sid 0x%x status 0x%x\n", 246 - cl_data->sensor_idx[i], cl_data->sensor_sts[i]); 229 + dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 230 + cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), 231 + cl_data->sensor_sts[i]); 232 + } 233 + if (privdata->mp2_ops->discovery_status && 234 + privdata->mp2_ops->discovery_status(privdata) == 0) { 235 + amd_sfh_hid_client_deinit(privdata); 236 + for (i = 0; i < cl_data->num_hid_devices; i++) { 237 + devm_kfree(dev, cl_data->feature_report[i]); 238 + devm_kfree(dev, in_data->input_report[i]); 239 + devm_kfree(dev, cl_data->report_descr[i]); 240 + } 241 + dev_warn(dev, "Failed to discover, sensors not enabled\n"); 242 + return -EOPNOTSUPP; 247 243 } 248 244 schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP)); 249 245 return 0; ··· 289 257 (privdata, cl_data->sensor_idx[i], SENSOR_DISABLED); 290 258 if (status != SENSOR_ENABLED) 291 259 cl_data->sensor_sts[i] = SENSOR_DISABLED; 292 - dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x status 0x%x\n", 293 - cl_data->sensor_idx[i], cl_data->sensor_sts[i]); 260 + dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x (%s) status 0x%x\n", 261 + cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), 262 + cl_data->sensor_sts[i]); 294 263 } 295 264 } 296 265
+7 -2
drivers/hid/amd-sfh-hid/amd_sfh_hid.c
··· 12 12 #include <linux/sched.h> 13 13 14 14 #include "amd_sfh_hid.h" 15 + #include "amd_sfh_pcie.h" 15 16 16 17 #define AMD_SFH_RESPONSE_TIMEOUT 1500 17 18 ··· 121 120 122 121 int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data) 123 122 { 123 + struct amd_mp2_dev *mp2 = container_of(cli_data->in_data, struct amd_mp2_dev, in_data); 124 + struct device *dev = &mp2->pdev->dev; 124 125 struct hid_device *hid; 125 126 struct amdtp_hid_data *hid_data; 126 127 int rc; ··· 144 141 145 142 hid->driver_data = hid_data; 146 143 cli_data->hid_sensor_hubs[cur_hid_dev] = hid; 147 - hid->bus = BUS_AMD_AMDTP; 144 + strscpy(hid->phys, dev->driver ? dev->driver->name : dev_name(dev), 145 + sizeof(hid->phys)); 146 + hid->bus = BUS_AMD_SFH; 148 147 hid->vendor = AMD_SFH_HID_VENDOR; 149 148 hid->product = AMD_SFH_HID_PRODUCT; 150 - snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp", 149 + snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdsfh", 151 150 hid->vendor, hid->product); 152 151 153 152 rc = hid_add_device(hid);
-1
drivers/hid/amd-sfh-hid/amd_sfh_hid.h
··· 12 12 #define AMDSFH_HID_H 13 13 14 14 #define MAX_HID_DEVICES 5 15 - #define BUS_AMD_AMDTP 0x20 16 15 #define AMD_SFH_HID_VENDOR 0x1022 17 16 #define AMD_SFH_HID_PRODUCT 0x0001 18 17
+13 -4
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
··· 130 130 return 0; 131 131 } 132 132 133 + static int amd_sfh_dis_sts_v2(struct amd_mp2_dev *privdata) 134 + { 135 + return (readl(privdata->mmio + AMD_P2C_MSG(1)) & 136 + SENSOR_DISCOVERY_STATUS_MASK) >> SENSOR_DISCOVERY_STATUS_SHIFT; 137 + } 138 + 133 139 void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info) 134 140 { 135 141 union sfh_cmd_param cmd_param; ··· 251 245 .response = amd_sfh_wait_response_v2, 252 246 .clear_intr = amd_sfh_clear_intr_v2, 253 247 .init_intr = amd_sfh_irq_init_v2, 248 + .discovery_status = amd_sfh_dis_sts_v2, 254 249 }; 255 250 256 251 static const struct amd_mp2_ops amd_sfh_ops = { ··· 353 346 (mp2, cl_data->sensor_idx[i], SENSOR_ENABLED); 354 347 if (status == SENSOR_ENABLED) 355 348 cl_data->sensor_sts[i] = SENSOR_ENABLED; 356 - dev_dbg(dev, "resume sid 0x%x status 0x%x\n", 357 - cl_data->sensor_idx[i], cl_data->sensor_sts[i]); 349 + dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n", 350 + cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), 351 + cl_data->sensor_sts[i]); 358 352 } 359 353 } 360 354 ··· 379 371 (mp2, cl_data->sensor_idx[i], SENSOR_DISABLED); 380 372 if (status != SENSOR_ENABLED) 381 373 cl_data->sensor_sts[i] = SENSOR_DISABLED; 382 - dev_dbg(dev, "suspend sid 0x%x status 0x%x\n", 383 - cl_data->sensor_idx[i], cl_data->sensor_sts[i]); 374 + dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n", 375 + cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), 376 + cl_data->sensor_sts[i]); 384 377 } 385 378 } 386 379
+5
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
··· 39 39 40 40 #define AMD_SFH_IDLE_LOOP 200 41 41 42 + #define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3) 43 + #define SENSOR_DISCOVERY_STATUS_SHIFT 3 44 + 42 45 /* SFH Command register */ 43 46 union sfh_cmd_base { 44 47 u32 ul; ··· 138 135 u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts); 139 136 void amd_mp2_suspend(struct amd_mp2_dev *mp2); 140 137 void amd_mp2_resume(struct amd_mp2_dev *mp2); 138 + const char *get_sensor_name(int idx); 141 139 142 140 struct amd_mp2_ops { 143 141 void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); ··· 147 143 int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts); 148 144 void (*clear_intr)(struct amd_mp2_dev *privdata); 149 145 int (*init_intr)(struct amd_mp2_dev *privdata); 146 + int (*discovery_status)(struct amd_mp2_dev *privdata); 150 147 }; 151 148 #endif
+3 -3
drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
··· 179 179 0xC0 /* HID end collection */ 180 180 }; 181 181 182 - const u8 gyro3_report_descriptor[] = { 182 + static const u8 gyro3_report_descriptor[] = { 183 183 0x05, 0x20, /* Usage page */ 184 184 0x09, 0x76, /* Motion type Gyro3D */ 185 185 0xA1, 0x00, /* HID Collection (Physical) */ ··· 340 340 0xC0, /* HID end collection */ 341 341 }; 342 342 343 - const u8 comp3_report_descriptor[] = { 343 + static const u8 comp3_report_descriptor[] = { 344 344 0x05, 0x20, /* Usage page */ 345 345 0x09, 0x83, /* Motion type Orientation compass 3D */ 346 346 0xA1, 0x00, /* HID Collection (Physical) */ ··· 512 512 0xC0 /* HID end collection */ 513 513 }; 514 514 515 - const u8 als_report_descriptor[] = { 515 + static const u8 als_report_descriptor[] = { 516 516 0x05, 0x20, /* HID usage page sensor */ 517 517 0x09, 0x41, /* HID usage sensor type Ambientlight */ 518 518 0xA1, 0x00, /* HID Collection (Physical) */
+18 -4
drivers/hid/hid-apple.c
··· 21 21 #include <linux/module.h> 22 22 #include <linux/slab.h> 23 23 #include <linux/timer.h> 24 + #include <linux/string.h> 24 25 25 26 #include "hid-ids.h" 26 27 ··· 36 35 #define APPLE_NUMLOCK_EMULATION BIT(8) 37 36 #define APPLE_RDESC_BATTERY BIT(9) 38 37 #define APPLE_BACKLIGHT_CTL BIT(10) 38 + #define APPLE_IS_KEYCHRON BIT(11) 39 39 40 40 #define APPLE_FLAG_FKEY 0x01 41 41 42 42 #define HID_COUNTRY_INTERNATIONAL_ISO 13 43 43 #define APPLE_BATTERY_TIMEOUT_MS 60000 44 44 45 - static unsigned int fnmode = 1; 45 + static unsigned int fnmode = 3; 46 46 module_param(fnmode, uint, 0644); 47 47 MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " 48 - "[1] = fkeyslast, 2 = fkeysfirst)"); 48 + "1 = fkeyslast, 2 = fkeysfirst, [3] = auto)"); 49 49 50 50 static int iso_layout = -1; 51 51 module_param(iso_layout, int, 0644); ··· 351 349 const struct apple_key_translation *trans, *table; 352 350 bool do_translate; 353 351 u16 code = 0; 352 + unsigned int real_fnmode; 354 353 355 354 u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); 356 355 ··· 362 359 return 1; 363 360 } 364 361 365 - if (fnmode) { 362 + if (fnmode == 3) { 363 + real_fnmode = (asc->quirks & APPLE_IS_KEYCHRON) ? 2 : 1; 364 + } else { 365 + real_fnmode = fnmode; 366 + } 367 + 368 + if (real_fnmode) { 366 369 if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI || 367 370 hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO || 368 371 hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS || ··· 415 406 416 407 if (!code) { 417 408 if (trans->flags & APPLE_FLAG_FKEY) { 418 - switch (fnmode) { 409 + switch (real_fnmode) { 419 410 case 1: 420 411 do_translate = !asc->fn_on; 421 412 break; ··· 667 658 if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { 668 659 hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n"); 669 660 asc->quirks &= ~APPLE_HAS_FN; 661 + } 662 + 663 + if (strncmp(hdev->name, "Keychron", 8) == 0) { 664 + hid_info(hdev, "Keychron keyboard detected; function keys will default to fnmode=2 behavior\n"); 665 + asc->quirks |= APPLE_IS_KEYCHRON; 670 666 } 671 667 672 668 return 0;
+6
drivers/hid/hid-bigbenff.c
··· 347 347 bigben->report = list_entry(report_list->next, 348 348 struct hid_report, list); 349 349 350 + if (list_empty(&hid->inputs)) { 351 + hid_err(hid, "no inputs found\n"); 352 + error = -ENODEV; 353 + goto error_hw_stop; 354 + } 355 + 350 356 hidinput = list_first_entry(&hid->inputs, struct hid_input, list); 351 357 set_bit(FF_RUMBLE, hidinput->input->ffbit); 352 358
+4
drivers/hid/hid-core.c
··· 2222 2222 case BUS_VIRTUAL: 2223 2223 bus = "VIRTUAL"; 2224 2224 break; 2225 + case BUS_INTEL_ISHTP: 2226 + case BUS_AMD_SFH: 2227 + bus = "SENSOR HUB"; 2228 + break; 2225 2229 default: 2226 2230 bus = "<UNKNOWN>"; 2227 2231 }
-2
drivers/hid/hid-elan.c
··· 188 188 ret = input_mt_init_slots(input, ELAN_MAX_FINGERS, INPUT_MT_POINTER); 189 189 if (ret) { 190 190 hid_err(hdev, "Failed to init elan MT slots: %d\n", ret); 191 - input_free_device(input); 192 191 return ret; 193 192 } 194 193 ··· 199 200 hid_err(hdev, "Failed to register elan input device: %d\n", 200 201 ret); 201 202 input_mt_destroy_slots(input); 202 - input_free_device(input); 203 203 return ret; 204 204 } 205 205
+7
drivers/hid/hid-ids.h
··· 761 761 #define USB_VENDOR_ID_LENOVO 0x17ef 762 762 #define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 763 763 #define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047 764 + #define USB_DEVICE_ID_LENOVO_TPIIUSBKBD 0x60ee 764 765 #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 766 + #define USB_DEVICE_ID_LENOVO_TPIIBTKBD 0x60e1 765 767 #define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049 766 768 #define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062 767 769 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 768 770 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 769 771 #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 770 772 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 773 + #define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe 771 774 #define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e 772 775 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d 773 776 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 ··· 870 867 871 868 #define USB_VENDOR_ID_MCS 0x16d0 872 869 #define USB_DEVICE_ID_MCS_GAMEPADBLOCK 0x0bcc 870 + 871 + #define USB_VENDOR_MEGAWORLD 0x07b5 872 + #define USB_DEVICE_ID_MEGAWORLD_GAMEPAD 0x0312 873 873 874 874 #define USB_VENDOR_ID_MGE 0x0463 875 875 #define USB_DEVICE_ID_MGE_UPS 0xffff ··· 1278 1272 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075 1279 1273 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094 1280 1274 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042 1275 + #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078 1281 1276 #define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074 1282 1277 #define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071 1283 1278 #define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
+6 -6
drivers/hid/hid-kye.c
··· 33 33 0xB1, 0x02, /* Feature (Variable), */ 34 34 0xC0, /* End Collection, */ 35 35 0x05, 0x0D, /* Usage Page (Digitizer), */ 36 - 0x09, 0x02, /* Usage (Pen), */ 36 + 0x09, 0x01, /* Usage (Digitizer), */ 37 37 0xA1, 0x01, /* Collection (Application), */ 38 38 0x85, 0x10, /* Report ID (16), */ 39 39 0x09, 0x20, /* Usage (Stylus), */ ··· 91 91 0xB1, 0x02, /* Feature (Variable), */ 92 92 0xC0, /* End Collection, */ 93 93 0x05, 0x0D, /* Usage Page (Digitizer), */ 94 - 0x09, 0x02, /* Usage (Pen), */ 94 + 0x09, 0x01, /* Usage (Digitizer), */ 95 95 0xA1, 0x01, /* Collection (Application), */ 96 96 0x85, 0x10, /* Report ID (16), */ 97 97 0x09, 0x20, /* Usage (Stylus), */ ··· 190 190 0xB1, 0x02, /* Feature (Variable), */ 191 191 0xC0, /* End Collection, */ 192 192 0x05, 0x0D, /* Usage Page (Digitizer), */ 193 - 0x09, 0x02, /* Usage (Pen), */ 193 + 0x09, 0x01, /* Usage (Digitizer), */ 194 194 0xA1, 0x01, /* Collection (Application), */ 195 195 0x85, 0x10, /* Report ID (16), */ 196 196 0x09, 0x20, /* Usage (Stylus), */ ··· 289 289 0xB1, 0x02, /* Feature (Variable), */ 290 290 0xC0, /* End Collection, */ 291 291 0x05, 0x0D, /* Usage Page (Digitizer), */ 292 - 0x09, 0x02, /* Usage (Pen), */ 292 + 0x09, 0x01, /* Usage (Digitizer), */ 293 293 0xA1, 0x01, /* Collection (Application), */ 294 294 0x85, 0x10, /* Report ID (16), */ 295 295 0x09, 0x20, /* Usage (Stylus), */ ··· 368 368 0xB1, 0x02, /* Feature (Variable), */ 369 369 0xC0, /* End Collection, */ 370 370 0x05, 0x0D, /* Usage Page (Digitizer), */ 371 - 0x09, 0x02, /* Usage (Pen), */ 371 + 0x09, 0x01, /* Usage (Digitizer), */ 372 372 0xA1, 0x01, /* Collection (Application), */ 373 373 0x85, 0x10, /* Report ID (16), */ 374 374 0x09, 0x20, /* Usage (Stylus), */ ··· 497 497 0xB1, 0x02, /* Feature (Variable), */ 498 498 0xC0, /* End Collection, */ 499 499 0x05, 0x0D, /* Usage Page (Digitizer), */ 500 - 0x09, 0x02, /* Usage (Pen), */ 500 + 0x09, 0x01, /* Usage (Digitizer), */ 501 501 0xA1, 0x01, /* Collection (Application), */ 502 502 0x85, 0x10, /* Report ID (16), */ 503 503 0x09, 0x20, /* Usage (Stylus), */
+1 -1
drivers/hid/hid-led.c
··· 366 366 .type = DREAM_CHEEKY, 367 367 .name = "Dream Cheeky Webmail Notifier", 368 368 .short_name = "dream_cheeky", 369 - .max_brightness = 31, 369 + .max_brightness = 63, 370 370 .num_leds = 1, 371 371 .report_size = 9, 372 372 .report_type = RAW_REQUEST,
+168 -6
drivers/hid/hid-lenovo.c
··· 4 4 * - ThinkPad USB Keyboard with TrackPoint (tpkbd) 5 5 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd) 6 6 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd) 7 + * - ThinkPad TrackPoint Keyboard II USB/Bluetooth (cptkbd/tpIIkbd) 7 8 * 8 9 * Copyright (c) 2012 Bernhard Seibold 9 10 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> ··· 111 110 0x2a, 0xff, 0xff, /* Usage Maximum (65535) */ 112 111 }; 113 112 113 + /* Broken ThinkPad TrackPoint II collection (Bluetooth mode) */ 114 + static const __u8 lenovo_tpIIbtkbd_need_fixup_collection[] = { 115 + 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */ 116 + 0x09, 0x01, /* Usage (0x01) */ 117 + 0xA1, 0x01, /* Collection (Application) */ 118 + 0x85, 0x05, /* Report ID (5) */ 119 + 0x1A, 0xF1, 0x00, /* Usage Minimum (0xF1) */ 120 + 0x2A, 0xFC, 0x00, /* Usage Maximum (0xFC) */ 121 + 0x15, 0x00, /* Logical Minimum (0) */ 122 + 0x25, 0x01, /* Logical Maximum (1) */ 123 + 0x75, 0x01, /* Report Size (1) */ 124 + 0x95, 0x0D, /* Report Count (13) */ 125 + 0x81, 0x02, /* Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */ 126 + 0x95, 0x03, /* Report Count (3) */ 127 + 0x81, 0x01, /* Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */ 128 + }; 129 + 114 130 static __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc, 115 131 unsigned int *rsize) 116 132 { ··· 142 124 sizeof(lenovo_pro_dock_need_fixup_collection)) == 0) { 143 125 rdesc[151] = 0x01; 144 126 rdesc[152] = 0x00; 127 + } 128 + break; 129 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 130 + if (*rsize >= 263 && 131 + memcmp(&rdesc[234], lenovo_tpIIbtkbd_need_fixup_collection, 132 + sizeof(lenovo_tpIIbtkbd_need_fixup_collection)) == 0) { 133 + rdesc[244] = 0x00; /* usage minimum = 0x00 */ 134 + rdesc[247] = 0xff; /* usage maximum = 0xff */ 135 + rdesc[252] = 0xff; /* logical maximum = 0xff */ 136 + rdesc[254] = 0x08; /* report size = 0x08 */ 137 + rdesc[256] = 0x01; /* report count = 0x01 */ 138 + rdesc[258] = 0x00; /* input = 0x00 */ 139 + rdesc[260] = 0x01; /* report count (2) = 0x01 */ 145 140 } 146 141 break; 147 142 } ··· 229 198 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */ 230 199 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 || 231 200 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) { 201 + field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; 202 + field->logical_minimum = -127; 203 + field->logical_maximum = 127; 204 + 205 + switch (usage->hid & HID_USAGE) { 206 + case 0x0000: 207 + hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); 208 + return 1; 209 + case 0x0001: 210 + hid_map_usage(hi, usage, bit, max, EV_REL, REL_WHEEL); 211 + return 1; 212 + default: 213 + return -1; 214 + } 215 + } 216 + 217 + return 0; 218 + } 219 + 220 + static int lenovo_input_mapping_tpIIkbd(struct hid_device *hdev, 221 + struct hid_input *hi, struct hid_field *field, 222 + struct hid_usage *usage, unsigned long **bit, int *max) 223 + { 224 + /* 225 + * 0xff0a0000 = USB, HID_UP_MSVENDOR = BT. 226 + * 227 + * In BT mode, there are two HID_UP_MSVENDOR pages. 228 + * Use only the page that contains report ID == 5. 229 + */ 230 + if (((usage->hid & HID_USAGE_PAGE) == 0xff0a0000 || 231 + (usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) && 232 + field->report->id == 5) { 233 + switch (usage->hid & HID_USAGE) { 234 + case 0x00bb: /* Fn-F4: Mic mute */ 235 + map_key_clear(LENOVO_KEY_MICMUTE); 236 + return 1; 237 + case 0x00c3: /* Fn-F5: Brightness down */ 238 + map_key_clear(KEY_BRIGHTNESSDOWN); 239 + return 1; 240 + case 0x00c4: /* Fn-F6: Brightness up */ 241 + map_key_clear(KEY_BRIGHTNESSUP); 242 + return 1; 243 + case 0x00c1: /* Fn-F8: Notification center */ 244 + map_key_clear(KEY_NOTIFICATION_CENTER); 245 + return 1; 246 + case 0x00bc: /* Fn-F9: Control panel */ 247 + map_key_clear(KEY_CONFIG); 248 + return 1; 249 + case 0x00b6: /* Fn-F10: Bluetooth */ 250 + map_key_clear(KEY_BLUETOOTH); 251 + return 1; 252 + case 0x00b7: /* Fn-F11: Keyboard config */ 253 + map_key_clear(KEY_KEYBOARD); 254 + return 1; 255 + case 0x00b8: /* Fn-F12: User function */ 256 + map_key_clear(KEY_PROG1); 257 + return 1; 258 + case 0x00b9: /* Fn-PrtSc: Snipping tool */ 259 + map_key_clear(KEY_SELECTIVE_SCREENSHOT); 260 + return 1; 261 + case 0x00b5: /* Fn-Esc: Fn-lock toggle */ 262 + map_key_clear(KEY_FN_ESC); 263 + return 1; 264 + } 265 + } 266 + 267 + if ((usage->hid & HID_USAGE_PAGE) == 0xffa00000) { 268 + switch (usage->hid & HID_USAGE) { 269 + case 0x00fb: /* Middle mouse (in native USB mode) */ 270 + map_key_clear(BTN_MIDDLE); 271 + return 1; 272 + } 273 + } 274 + 275 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR && 276 + field->report->id == 21) { 277 + switch (usage->hid & HID_USAGE) { 278 + case 0x0004: /* Middle mouse (in native Bluetooth mode) */ 279 + map_key_clear(BTN_MIDDLE); 280 + return 1; 281 + } 282 + } 283 + 284 + /* Compatibility middle/wheel mappings should be ignored */ 285 + if (usage->hid == HID_GD_WHEEL) 286 + return -1; 287 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON && 288 + (usage->hid & HID_USAGE) == 0x003) 289 + return -1; 290 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER && 291 + (usage->hid & HID_USAGE) == 0x238) 292 + return -1; 293 + 294 + /* Map wheel emulation reports: 0xff10 */ 295 + if ((usage->hid & HID_USAGE_PAGE) == 0xff100000) { 232 296 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; 233 297 field->logical_minimum = -127; 234 298 field->logical_maximum = 127; ··· 452 326 case USB_DEVICE_ID_LENOVO_CBTKBD: 453 327 return lenovo_input_mapping_cptkbd(hdev, hi, field, 454 328 usage, bit, max); 329 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 330 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 331 + return lenovo_input_mapping_tpIIkbd(hdev, hi, field, 332 + usage, bit, max); 455 333 case USB_DEVICE_ID_IBM_SCROLLPOINT_III: 456 334 case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO: 457 335 case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL: ··· 487 357 if (!buf) 488 358 return -ENOMEM; 489 359 360 + /* 361 + * Feature report 0x13 is used for USB, 362 + * output report 0x18 is used for Bluetooth. 363 + * buf[0] is ignored by hid_hw_raw_request. 364 + */ 490 365 buf[0] = 0x18; 491 366 buf[1] = byte2; 492 367 buf[2] = byte3; 493 368 494 369 switch (hdev->product) { 495 370 case USB_DEVICE_ID_LENOVO_CUSBKBD: 371 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 496 372 ret = hid_hw_raw_request(hdev, 0x13, buf, 3, 497 373 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 498 374 break; 499 375 case USB_DEVICE_ID_LENOVO_CBTKBD: 376 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 500 377 ret = hid_hw_output_report(hdev, buf, 3); 501 378 break; 502 379 default: ··· 559 422 switch (hdev->product) { 560 423 case USB_DEVICE_ID_LENOVO_CUSBKBD: 561 424 case USB_DEVICE_ID_LENOVO_CBTKBD: 425 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 426 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 562 427 lenovo_features_set_cptkbd(hdev); 563 428 break; 564 429 case USB_DEVICE_ID_LENOVO_TP10UBKBD: ··· 695 556 return 1; 696 557 } 697 558 559 + if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { 560 + /* 561 + * The user has toggled the Fn-lock state. Toggle our own 562 + * cached value of it and sync our value to the keyboard to 563 + * ensure things are in sync (the syncing should be a no-op). 564 + */ 565 + cptkbd_data->fn_lock = !cptkbd_data->fn_lock; 566 + } 567 + 698 568 return 0; 699 569 } 700 570 ··· 716 568 switch (hdev->product) { 717 569 case USB_DEVICE_ID_LENOVO_CUSBKBD: 718 570 case USB_DEVICE_ID_LENOVO_CBTKBD: 571 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 572 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 719 573 return lenovo_event_cptkbd(hdev, field, usage, value); 720 574 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 721 575 case USB_DEVICE_ID_LENOVO_X1_TAB: ··· 1110 960 struct lenovo_drvdata *cptkbd_data; 1111 961 1112 962 /* All the custom action happens on the USBMOUSE device for USB */ 1113 - if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 1114 - && hdev->type != HID_TYPE_USBMOUSE) { 963 + if (((hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD) || 964 + (hdev->product == USB_DEVICE_ID_LENOVO_TPIIUSBKBD)) && 965 + hdev->type != HID_TYPE_USBMOUSE) { 1115 966 hid_dbg(hdev, "Ignoring keyboard half of device\n"); 1116 967 return 0; 1117 968 } ··· 1128 977 1129 978 /* 1130 979 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 1131 - * regular keys 980 + * regular keys (Compact only) 1132 981 */ 1133 - ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 1134 - if (ret) 1135 - hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 982 + if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD || 983 + hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) { 984 + ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 985 + if (ret) 986 + hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 987 + } 1136 988 1137 989 /* Switch middle button to native mode */ 1138 990 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); ··· 1242 1088 break; 1243 1089 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1244 1090 case USB_DEVICE_ID_LENOVO_CBTKBD: 1091 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 1092 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 1245 1093 ret = lenovo_probe_cptkbd(hdev); 1246 1094 break; 1247 1095 case USB_DEVICE_ID_LENOVO_TP10UBKBD: ··· 1310 1154 break; 1311 1155 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1312 1156 case USB_DEVICE_ID_LENOVO_CBTKBD: 1157 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 1158 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 1313 1159 lenovo_remove_cptkbd(hdev); 1314 1160 break; 1315 1161 case USB_DEVICE_ID_LENOVO_TP10UBKBD: ··· 1330 1172 case USB_DEVICE_ID_LENOVO_TPKBD: 1331 1173 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1332 1174 case USB_DEVICE_ID_LENOVO_CBTKBD: 1175 + case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: 1176 + case USB_DEVICE_ID_LENOVO_TPIIBTKBD: 1333 1177 if (test_bit(EV_REL, hi->input->evbit)) { 1334 1178 /* set only for trackpoint device */ 1335 1179 __set_bit(INPUT_PROP_POINTER, hi->input->propbit); ··· 1348 1188 static const struct hid_device_id lenovo_devices[] = { 1349 1189 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 1350 1190 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, 1191 + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPIIUSBKBD) }, 1351 1192 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, 1193 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPIIBTKBD) }, 1352 1194 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, 1353 1195 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) }, 1354 1196 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) },
+125
drivers/hid/hid-megaworld.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Vibration support for Mega World controllers 4 + * 5 + * Copyright 2022 Frank Zago 6 + * 7 + * Derived from hid-zpff.c: 8 + * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com> 9 + */ 10 + 11 + #include <linux/hid.h> 12 + #include <linux/input.h> 13 + #include <linux/module.h> 14 + #include <linux/slab.h> 15 + 16 + #include "hid-ids.h" 17 + 18 + struct mwctrl_device { 19 + struct hid_report *report; 20 + s32 *weak; 21 + s32 *strong; 22 + }; 23 + 24 + static int mwctrl_play(struct input_dev *dev, void *data, 25 + struct ff_effect *effect) 26 + { 27 + struct hid_device *hid = input_get_drvdata(dev); 28 + struct mwctrl_device *mwctrl = data; 29 + 30 + *mwctrl->strong = effect->u.rumble.strong_magnitude >> 8; 31 + *mwctrl->weak = effect->u.rumble.weak_magnitude >> 8; 32 + 33 + hid_hw_request(hid, mwctrl->report, HID_REQ_SET_REPORT); 34 + 35 + return 0; 36 + } 37 + 38 + static int mwctrl_init(struct hid_device *hid) 39 + { 40 + struct mwctrl_device *mwctrl; 41 + struct hid_report *report; 42 + struct hid_input *hidinput; 43 + struct input_dev *dev; 44 + int error; 45 + int i; 46 + 47 + if (list_empty(&hid->inputs)) { 48 + hid_err(hid, "no inputs found\n"); 49 + return -ENODEV; 50 + } 51 + hidinput = list_entry(hid->inputs.next, struct hid_input, list); 52 + dev = hidinput->input; 53 + 54 + for (i = 0; i < 4; i++) { 55 + report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); 56 + if (!report) 57 + return -ENODEV; 58 + } 59 + 60 + mwctrl = kzalloc(sizeof(struct mwctrl_device), GFP_KERNEL); 61 + if (!mwctrl) 62 + return -ENOMEM; 63 + 64 + set_bit(FF_RUMBLE, dev->ffbit); 65 + 66 + error = input_ff_create_memless(dev, mwctrl, mwctrl_play); 67 + if (error) { 68 + kfree(mwctrl); 69 + return error; 70 + } 71 + 72 + mwctrl->report = report; 73 + 74 + /* Field 0 is always 2, and field 1 is always 0. The original 75 + * windows driver has a 5 bytes command, where the 5th byte is 76 + * a repeat of the 3rd byte, however the device has only 4 77 + * fields. It could be a bug in the driver, or there is a 78 + * different device that needs it. 79 + */ 80 + report->field[0]->value[0] = 0x02; 81 + 82 + mwctrl->strong = &report->field[2]->value[0]; 83 + mwctrl->weak = &report->field[3]->value[0]; 84 + 85 + return 0; 86 + } 87 + 88 + static int mwctrl_probe(struct hid_device *hdev, const struct hid_device_id *id) 89 + { 90 + int ret; 91 + 92 + ret = hid_parse(hdev); 93 + if (ret) { 94 + hid_err(hdev, "parse failed\n"); 95 + return ret; 96 + } 97 + 98 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); 99 + if (ret) { 100 + hid_err(hdev, "hw start failed\n"); 101 + return ret; 102 + } 103 + 104 + ret = mwctrl_init(hdev); 105 + if (ret) 106 + hid_hw_stop(hdev); 107 + 108 + return ret; 109 + } 110 + 111 + static const struct hid_device_id mwctrl_devices[] = { 112 + { HID_USB_DEVICE(USB_VENDOR_MEGAWORLD, 113 + USB_DEVICE_ID_MEGAWORLD_GAMEPAD) }, 114 + { } 115 + }; 116 + MODULE_DEVICE_TABLE(hid, mwctrl_devices); 117 + 118 + static struct hid_driver mwctrl_driver = { 119 + .name = "megaworld", 120 + .id_table = mwctrl_devices, 121 + .probe = mwctrl_probe, 122 + }; 123 + module_hid_driver(mwctrl_driver); 124 + 125 + MODULE_LICENSE("GPL");
+9
drivers/hid/hid-multitouch.c
··· 2034 2034 USB_VENDOR_ID_LENOVO, 2035 2035 USB_DEVICE_ID_LENOVO_X1_TAB3) }, 2036 2036 2037 + /* Lenovo X12 TAB Gen 1 */ 2038 + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, 2039 + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, 2040 + USB_VENDOR_ID_LENOVO, 2041 + USB_DEVICE_ID_LENOVO_X12_TAB) }, 2042 + 2037 2043 /* MosArt panels */ 2038 2044 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 2039 2045 MT_USB_DEVICE(USB_VENDOR_ID_ASUS, ··· 2184 2178 { .driver_data = MT_CLS_GOOGLE, 2185 2179 HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, 2186 2180 USB_DEVICE_ID_GOOGLE_TOUCH_ROSE) }, 2181 + { .driver_data = MT_CLS_GOOGLE, 2182 + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_GOOGLE, 2183 + USB_DEVICE_ID_GOOGLE_WHISKERS) }, 2187 2184 2188 2185 /* Generic MT device */ 2189 2186 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
+90 -23
drivers/hid/hid-uclogic-core.c
··· 81 81 return rdesc; 82 82 } 83 83 84 + static int uclogic_input_mapping(struct hid_device *hdev, 85 + struct hid_input *hi, 86 + struct hid_field *field, 87 + struct hid_usage *usage, 88 + unsigned long **bit, 89 + int *max) 90 + { 91 + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 92 + struct uclogic_params *params = &drvdata->params; 93 + 94 + /* Discard invalid pen usages */ 95 + if (params->pen.usage_invalid && (field->application == HID_DG_PEN)) 96 + return -1; 97 + 98 + /* Let hid-core decide what to do */ 99 + return 0; 100 + } 101 + 84 102 static int uclogic_input_configured(struct hid_device *hdev, 85 103 struct hid_input *hi) 86 104 { ··· 108 90 const char *suffix = NULL; 109 91 struct hid_field *field; 110 92 size_t len; 93 + size_t i; 94 + const struct uclogic_params_frame *frame; 111 95 112 96 /* no report associated (HID_QUIRK_MULTI_INPUT not set) */ 113 97 if (!hi->report) ··· 124 104 drvdata->pen_input = hi->input; 125 105 } 126 106 127 - field = hi->report->field[0]; 107 + /* If it's one of the frame devices */ 108 + for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { 109 + frame = &params->frame_list[i]; 110 + if (hi->report->id == frame->id) { 111 + /* Assign custom suffix, if any */ 112 + suffix = frame->suffix; 113 + /* 114 + * Disable EV_MSC reports for touch ring interfaces to 115 + * make the Wacom driver pickup touch ring extents 116 + */ 117 + if (frame->touch_byte > 0) 118 + __clear_bit(EV_MSC, hi->input->evbit); 119 + } 120 + } 128 121 129 - switch (field->application) { 130 - case HID_GD_KEYBOARD: 131 - suffix = "Keyboard"; 132 - break; 133 - case HID_GD_MOUSE: 134 - suffix = "Mouse"; 135 - break; 136 - case HID_GD_KEYPAD: 137 - suffix = "Pad"; 138 - break; 139 - case HID_DG_PEN: 140 - suffix = "Pen"; 141 - break; 142 - case HID_CP_CONSUMER_CONTROL: 143 - suffix = "Consumer Control"; 144 - break; 145 - case HID_GD_SYSTEM_CONTROL: 146 - suffix = "System Control"; 147 - break; 122 + if (!suffix) { 123 + field = hi->report->field[0]; 124 + 125 + switch (field->application) { 126 + case HID_GD_KEYBOARD: 127 + suffix = "Keyboard"; 128 + break; 129 + case HID_GD_MOUSE: 130 + suffix = "Mouse"; 131 + break; 132 + case HID_GD_KEYPAD: 133 + suffix = "Pad"; 134 + break; 135 + case HID_DG_PEN: 136 + suffix = "Pen"; 137 + break; 138 + case HID_CP_CONSUMER_CONTROL: 139 + suffix = "Consumer Control"; 140 + break; 141 + case HID_GD_SYSTEM_CONTROL: 142 + suffix = "System Control"; 143 + break; 144 + } 148 145 } 149 146 150 147 if (suffix) { ··· 209 172 goto failure; 210 173 } 211 174 params_initialized = true; 212 - hid_dbg(hdev, "parameters:\n" UCLOGIC_PARAMS_FMT_STR, 213 - UCLOGIC_PARAMS_FMT_ARGS(&drvdata->params)); 175 + hid_dbg(hdev, "parameters:\n"); 176 + uclogic_params_hid_dbg(hdev, &drvdata->params); 214 177 if (drvdata->params.invalid) { 215 178 hid_info(hdev, "interface is invalid, ignoring\n"); 216 179 rc = -ENODEV; ··· 350 313 351 314 /* If need to, and can, set pad device ID for Wacom drivers */ 352 315 if (frame->dev_id_byte > 0 && frame->dev_id_byte < size) { 353 - data[frame->dev_id_byte] = 0xf; 316 + /* If we also have a touch ring and the finger left it */ 317 + if (frame->touch_byte > 0 && frame->touch_byte < size && 318 + data[frame->touch_byte] == 0) { 319 + data[frame->dev_id_byte] = 0; 320 + } else { 321 + data[frame->dev_id_byte] = 0xf; 322 + } 354 323 } 324 + 355 325 /* If need to, and can, read rotary encoder state change */ 356 326 if (frame->re_lsb > 0 && frame->re_lsb / 8 < size) { 357 327 unsigned int byte = frame->re_lsb / 8; ··· 383 339 (change << bit); 384 340 /* Remember state */ 385 341 drvdata->re_state = state; 342 + } 343 + 344 + /* If need to, and can, transform the touch ring reports */ 345 + if (frame->touch_byte > 0 && frame->touch_byte < size) { 346 + __s8 value = data[frame->touch_byte]; 347 + 348 + if (value != 0) { 349 + if (frame->touch_flip_at != 0) { 350 + value = frame->touch_flip_at - value; 351 + if (value <= 0) 352 + value = frame->touch_max + value; 353 + } 354 + data[frame->touch_byte] = value - 1; 355 + } 356 + } 357 + 358 + /* If need to, and can, transform the bitmap dial reports */ 359 + if (frame->bitmap_dial_byte > 0 && frame->bitmap_dial_byte < size) { 360 + if (data[frame->bitmap_dial_byte] == 2) 361 + data[frame->bitmap_dial_byte] = -1; 386 362 } 387 363 388 364 return 0; ··· 521 457 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640) }, 522 458 { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, 523 459 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) }, 460 + { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, 461 + USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) }, 524 462 { } 525 463 }; 526 464 MODULE_DEVICE_TABLE(hid, uclogic_devices); ··· 534 468 .remove = uclogic_remove, 535 469 .report_fixup = uclogic_report_fixup, 536 470 .raw_event = uclogic_raw_event, 471 + .input_mapping = uclogic_input_mapping, 537 472 .input_configured = uclogic_input_configured, 538 473 #ifdef CONFIG_PM 539 474 .resume = uclogic_resume,
+243 -45
drivers/hid/hid-uclogic-params.c
··· 29 29 * Returns: 30 30 * The string representing the type, or NULL if the type is unknown. 31 31 */ 32 - const char *uclogic_params_pen_inrange_to_str( 33 - enum uclogic_params_pen_inrange inrange) 32 + static const char *uclogic_params_pen_inrange_to_str( 33 + enum uclogic_params_pen_inrange inrange) 34 34 { 35 35 switch (inrange) { 36 36 case UCLOGIC_PARAMS_PEN_INRANGE_NORMAL: ··· 42 42 default: 43 43 return NULL; 44 44 } 45 + } 46 + 47 + /** 48 + * Dump tablet interface pen parameters with hid_dbg(), indented with one tab. 49 + * 50 + * @hdev: The HID device the pen parameters describe. 51 + * @pen: The pen parameters to dump. 52 + */ 53 + static void uclogic_params_pen_hid_dbg(const struct hid_device *hdev, 54 + const struct uclogic_params_pen *pen) 55 + { 56 + size_t i; 57 + 58 + hid_dbg(hdev, "\t.usage_invalid = %s\n", 59 + (pen->usage_invalid ? "true" : "false")); 60 + hid_dbg(hdev, "\t.desc_ptr = %p\n", pen->desc_ptr); 61 + hid_dbg(hdev, "\t.desc_size = %u\n", pen->desc_size); 62 + hid_dbg(hdev, "\t.id = %u\n", pen->id); 63 + hid_dbg(hdev, "\t.subreport_list = {\n"); 64 + for (i = 0; i < ARRAY_SIZE(pen->subreport_list); i++) { 65 + hid_dbg(hdev, "\t\t{0x%02hhx, %hhu}%s\n", 66 + pen->subreport_list[i].value, 67 + pen->subreport_list[i].id, 68 + i < (ARRAY_SIZE(pen->subreport_list) - 1) ? "," : ""); 69 + } 70 + hid_dbg(hdev, "\t}\n"); 71 + hid_dbg(hdev, "\t.inrange = %s\n", 72 + uclogic_params_pen_inrange_to_str(pen->inrange)); 73 + hid_dbg(hdev, "\t.fragmented_hires = %s\n", 74 + (pen->fragmented_hires ? "true" : "false")); 75 + hid_dbg(hdev, "\t.tilt_y_flipped = %s\n", 76 + (pen->tilt_y_flipped ? "true" : "false")); 77 + } 78 + 79 + /** 80 + * Dump tablet interface frame parameters with hid_dbg(), indented with two 81 + * tabs. 82 + * 83 + * @hdev: The HID device the pen parameters describe. 84 + * @frame: The frame parameters to dump. 85 + */ 86 + static void uclogic_params_frame_hid_dbg( 87 + const struct hid_device *hdev, 88 + const struct uclogic_params_frame *frame) 89 + { 90 + hid_dbg(hdev, "\t\t.desc_ptr = %p\n", frame->desc_ptr); 91 + hid_dbg(hdev, "\t\t.desc_size = %u\n", frame->desc_size); 92 + hid_dbg(hdev, "\t\t.id = %u\n", frame->id); 93 + hid_dbg(hdev, "\t\t.suffix = %s\n", frame->suffix); 94 + hid_dbg(hdev, "\t\t.re_lsb = %u\n", frame->re_lsb); 95 + hid_dbg(hdev, "\t\t.dev_id_byte = %u\n", frame->dev_id_byte); 96 + hid_dbg(hdev, "\t\t.touch_byte = %u\n", frame->touch_byte); 97 + hid_dbg(hdev, "\t\t.touch_max = %hhd\n", frame->touch_max); 98 + hid_dbg(hdev, "\t\t.touch_flip_at = %hhd\n", 99 + frame->touch_flip_at); 100 + hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n", 101 + frame->bitmap_dial_byte); 102 + } 103 + 104 + /** 105 + * Dump tablet interface parameters with hid_dbg(). 106 + * 107 + * @hdev: The HID device the parameters describe. 108 + * @params: The parameters to dump. 109 + */ 110 + void uclogic_params_hid_dbg(const struct hid_device *hdev, 111 + const struct uclogic_params *params) 112 + { 113 + size_t i; 114 + 115 + hid_dbg(hdev, ".invalid = %s\n", 116 + params->invalid ? "true" : "false"); 117 + hid_dbg(hdev, ".desc_ptr = %p\n", params->desc_ptr); 118 + hid_dbg(hdev, ".desc_size = %u\n", params->desc_size); 119 + hid_dbg(hdev, ".pen = {\n"); 120 + uclogic_params_pen_hid_dbg(hdev, &params->pen); 121 + hid_dbg(hdev, "\t}\n"); 122 + hid_dbg(hdev, ".frame_list = {\n"); 123 + for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) { 124 + hid_dbg(hdev, "\t{\n"); 125 + uclogic_params_frame_hid_dbg(hdev, &params->frame_list[i]); 126 + hid_dbg(hdev, "\t}%s\n", 127 + i < (ARRAY_SIZE(params->frame_list) - 1) ? "," : ""); 128 + } 129 + hid_dbg(hdev, "}\n"); 45 130 } 46 131 47 132 /** ··· 338 253 * uclogic_params_pen_init_v2() - initialize tablet interface pen 339 254 * input and retrieve its parameters from the device, using v2 protocol. 340 255 * 341 - * @pen: Pointer to the pen parameters to initialize (to be 342 - * cleaned up with uclogic_params_pen_cleanup()). Not modified in 343 - * case of error, or if parameters are not found. Cannot be NULL. 344 - * @pfound: Location for a flag which is set to true if the parameters 345 - * were found, and to false if not (e.g. device was 346 - * incompatible). Not modified in case of error. Cannot be NULL. 347 - * @hdev: The HID device of the tablet interface to initialize and get 348 - * parameters from. Cannot be NULL. 256 + * @pen: Pointer to the pen parameters to initialize (to be 257 + * cleaned up with uclogic_params_pen_cleanup()). Not 258 + * modified in case of error, or if parameters are not 259 + * found. Cannot be NULL. 260 + * @pfound: Location for a flag which is set to true if the 261 + * parameters were found, and to false if not (e.g. 262 + * device was incompatible). Not modified in case of 263 + * error. Cannot be NULL. 264 + * @pparams_ptr: Location for a kmalloc'ed pointer to the retrieved raw 265 + * parameters, which could be used to identify the tablet 266 + * to some extent. Should be freed with kfree after use. 267 + * NULL, if not needed. Not modified in case of error. 268 + * Only set if *pfound is set to true. 269 + * @pparams_len: Location for the length of the retrieved raw 270 + * parameters. NULL, if not needed. Not modified in case 271 + * of error. Only set if *pfound is set to true. 272 + * @hdev: The HID device of the tablet interface to initialize 273 + * and get parameters from. Cannot be NULL. 349 274 * 350 275 * Returns: 351 276 * Zero, if successful. A negative errno code on error. 352 277 */ 353 278 static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen, 354 279 bool *pfound, 280 + __u8 **pparams_ptr, 281 + size_t *pparams_len, 355 282 struct hid_device *hdev) 356 283 { 357 284 int rc; 358 285 bool found = false; 359 - /* Buffer for (part of) the string descriptor */ 286 + /* Buffer for (part of) the parameter string descriptor */ 360 287 __u8 *buf = NULL; 361 - /* Descriptor length required */ 362 - const int len = 18; 288 + /* Parameter string descriptor required length */ 289 + const int params_len_min = 18; 290 + /* Parameter string descriptor accepted length */ 291 + const int params_len_max = 32; 292 + /* Parameter string descriptor received length */ 293 + int params_len; 294 + size_t i; 363 295 s32 resolution; 364 296 /* Pen report descriptor template parameters */ 365 297 s32 desc_params[UCLOGIC_RDESC_PEN_PH_ID_NUM]; ··· 394 292 * the Windows driver traffic. 395 293 * NOTE: This enables fully-functional tablet mode. 396 294 */ 397 - rc = uclogic_params_get_str_desc(&buf, hdev, 200, len); 295 + rc = uclogic_params_get_str_desc(&buf, hdev, 200, params_len_max); 398 296 if (rc == -EPIPE) { 399 297 hid_dbg(hdev, 400 298 "string descriptor with pen parameters not found, assuming not compatible\n"); ··· 402 300 } else if (rc < 0) { 403 301 hid_err(hdev, "failed retrieving pen parameters: %d\n", rc); 404 302 goto cleanup; 405 - } else if (rc != len) { 303 + } else if (rc < params_len_min) { 406 304 hid_dbg(hdev, 407 - "string descriptor with pen parameters has invalid length (got %d, expected %d), assuming not compatible\n", 408 - rc, len); 305 + "string descriptor with pen parameters is too short (got %d, expected at least %d), assuming not compatible\n", 306 + rc, params_len_min); 409 307 goto finish; 410 - } else { 411 - size_t i; 412 - /* 413 - * Check it's not just a catch-all UTF-16LE-encoded ASCII 414 - * string (such as the model name) some tablets put into all 415 - * unknown string descriptors. 416 - */ 417 - for (i = 2; 418 - i < len && 419 - (buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0); 420 - i += 2); 421 - if (i >= len) { 422 - hid_dbg(hdev, 423 - "string descriptor with pen parameters seems to contain only text, assuming not compatible\n"); 424 - goto finish; 425 - } 308 + } 309 + 310 + params_len = rc; 311 + 312 + /* 313 + * Check it's not just a catch-all UTF-16LE-encoded ASCII 314 + * string (such as the model name) some tablets put into all 315 + * unknown string descriptors. 316 + */ 317 + for (i = 2; 318 + i < params_len && 319 + (buf[i] >= 0x20 && buf[i] < 0x7f && buf[i + 1] == 0); 320 + i += 2); 321 + if (i >= params_len) { 322 + hid_dbg(hdev, 323 + "string descriptor with pen parameters seems to contain only text, assuming not compatible\n"); 324 + goto finish; 426 325 } 427 326 428 327 /* ··· 447 344 desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 / 448 345 resolution; 449 346 } 450 - kfree(buf); 451 - buf = NULL; 452 347 453 348 /* 454 349 * Generate pen report descriptor ··· 472 371 pen->fragmented_hires = true; 473 372 pen->tilt_y_flipped = true; 474 373 found = true; 374 + if (pparams_ptr != NULL) { 375 + *pparams_ptr = buf; 376 + buf = NULL; 377 + } 378 + if (pparams_len != NULL) 379 + *pparams_len = params_len; 380 + 475 381 finish: 476 382 *pfound = found; 477 383 rc = 0; ··· 808 700 static const char transition_ver[] = "HUION_T153_160607"; 809 701 char *ver_ptr = NULL; 810 702 const size_t ver_len = sizeof(transition_ver) + 1; 703 + __u8 *params_ptr = NULL; 704 + size_t params_len = 0; 705 + /* Parameters string descriptor of a model with touch ring (HS610) */ 706 + const __u8 touch_ring_model_params_buf[] = { 707 + 0x13, 0x03, 0x70, 0xC6, 0x00, 0x06, 0x7C, 0x00, 708 + 0xFF, 0x1F, 0xD8, 0x13, 0x03, 0x0D, 0x10, 0x01, 709 + 0x04, 0x3C, 0x3E 710 + }; 811 711 812 712 /* Check arguments */ 813 713 if (params == NULL || hdev == NULL) { ··· 827 711 iface = to_usb_interface(hdev->dev.parent); 828 712 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; 829 713 830 - /* If it's not a pen interface */ 831 - if (bInterfaceNumber != 0) { 714 + /* If it's a custom keyboard interface */ 715 + if (bInterfaceNumber == 1) { 716 + /* Keep everything intact, but mark pen usage invalid */ 717 + p.pen.usage_invalid = true; 718 + goto output; 719 + /* Else, if it's not a pen interface */ 720 + } else if (bInterfaceNumber != 0) { 832 721 uclogic_params_init_invalid(&p); 833 722 goto output; 834 723 } ··· 859 738 "transition firmware detected, not probing pen v2 parameters\n"); 860 739 } else { 861 740 /* Try to probe v2 pen parameters */ 862 - rc = uclogic_params_pen_init_v2(&p.pen, &found, hdev); 741 + rc = uclogic_params_pen_init_v2(&p.pen, &found, 742 + &params_ptr, &params_len, 743 + hdev); 863 744 if (rc != 0) { 864 745 hid_err(hdev, 865 746 "failed probing pen v2 parameters: %d\n", rc); 866 747 goto cleanup; 867 748 } else if (found) { 868 749 hid_dbg(hdev, "pen v2 parameters found\n"); 869 - /* Create v2 frame parameters */ 750 + /* Create v2 frame button parameters */ 870 751 rc = uclogic_params_frame_init_with_desc( 871 752 &p.frame_list[0], 872 - uclogic_rdesc_v2_frame_arr, 873 - uclogic_rdesc_v2_frame_size, 874 - UCLOGIC_RDESC_V2_FRAME_ID); 753 + uclogic_rdesc_v2_frame_buttons_arr, 754 + uclogic_rdesc_v2_frame_buttons_size, 755 + UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID); 875 756 if (rc != 0) { 876 757 hid_err(hdev, 877 - "failed creating v2 frame parameters: %d\n", 758 + "failed creating v2 frame button parameters: %d\n", 878 759 rc); 879 760 goto cleanup; 880 761 } 881 - /* Link frame button subreports from pen reports */ 762 + 763 + /* Link from pen sub-report */ 882 764 p.pen.subreport_list[0].value = 0xe0; 883 765 p.pen.subreport_list[0].id = 884 - UCLOGIC_RDESC_V2_FRAME_ID; 766 + UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID; 767 + 768 + /* If this is the model with touch ring */ 769 + if (params_ptr != NULL && 770 + params_len == sizeof(touch_ring_model_params_buf) && 771 + memcmp(params_ptr, touch_ring_model_params_buf, 772 + params_len) == 0) { 773 + /* Create touch ring parameters */ 774 + rc = uclogic_params_frame_init_with_desc( 775 + &p.frame_list[1], 776 + uclogic_rdesc_v2_frame_touch_ring_arr, 777 + uclogic_rdesc_v2_frame_touch_ring_size, 778 + UCLOGIC_RDESC_V2_FRAME_TOUCH_ID); 779 + if (rc != 0) { 780 + hid_err(hdev, 781 + "failed creating v2 frame touch ring parameters: %d\n", 782 + rc); 783 + goto cleanup; 784 + } 785 + p.frame_list[1].suffix = "Touch Ring"; 786 + p.frame_list[1].dev_id_byte = 787 + UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE; 788 + p.frame_list[1].touch_byte = 5; 789 + p.frame_list[1].touch_max = 12; 790 + p.frame_list[1].touch_flip_at = 7; 791 + } else { 792 + /* Create touch strip parameters */ 793 + rc = uclogic_params_frame_init_with_desc( 794 + &p.frame_list[1], 795 + uclogic_rdesc_v2_frame_touch_strip_arr, 796 + uclogic_rdesc_v2_frame_touch_strip_size, 797 + UCLOGIC_RDESC_V2_FRAME_TOUCH_ID); 798 + if (rc != 0) { 799 + hid_err(hdev, 800 + "failed creating v2 frame touch strip parameters: %d\n", 801 + rc); 802 + goto cleanup; 803 + } 804 + p.frame_list[1].suffix = "Touch Strip"; 805 + p.frame_list[1].dev_id_byte = 806 + UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE; 807 + p.frame_list[1].touch_byte = 5; 808 + p.frame_list[1].touch_max = 8; 809 + } 810 + 811 + /* Link from pen sub-report */ 812 + p.pen.subreport_list[1].value = 0xf0; 813 + p.pen.subreport_list[1].id = 814 + UCLOGIC_RDESC_V2_FRAME_TOUCH_ID; 815 + 816 + /* Create v2 frame dial parameters */ 817 + rc = uclogic_params_frame_init_with_desc( 818 + &p.frame_list[2], 819 + uclogic_rdesc_v2_frame_dial_arr, 820 + uclogic_rdesc_v2_frame_dial_size, 821 + UCLOGIC_RDESC_V2_FRAME_DIAL_ID); 822 + if (rc != 0) { 823 + hid_err(hdev, 824 + "failed creating v2 frame dial parameters: %d\n", 825 + rc); 826 + goto cleanup; 827 + } 828 + p.frame_list[2].suffix = "Dial"; 829 + p.frame_list[2].dev_id_byte = 830 + UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE; 831 + p.frame_list[2].bitmap_dial_byte = 5; 832 + 833 + /* Link from pen sub-report */ 834 + p.pen.subreport_list[2].value = 0xf1; 835 + p.pen.subreport_list[2].id = 836 + UCLOGIC_RDESC_V2_FRAME_DIAL_ID; 837 + 885 838 goto output; 886 839 } 887 840 hid_dbg(hdev, "pen v2 parameters not found\n"); ··· 996 801 memset(&p, 0, sizeof(p)); 997 802 rc = 0; 998 803 cleanup: 804 + kfree(params_ptr); 999 805 kfree(ver_ptr); 1000 806 uclogic_params_cleanup(&p); 1001 807 return rc; ··· 1195 999 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): 1196 1000 case VID_PID(USB_VENDOR_ID_UGEE, 1197 1001 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640): 1002 + case VID_PID(USB_VENDOR_ID_UGEE, 1003 + USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06): 1198 1004 case VID_PID(USB_VENDOR_ID_UGEE, 1199 1005 USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720): 1200 1006 /* If this is the pen interface */
+53 -52
drivers/hid/hid-uclogic-params.h
··· 29 29 UCLOGIC_PARAMS_PEN_INRANGE_NONE, 30 30 }; 31 31 32 - /* Convert a pen in-range reporting type to a string */ 33 - extern const char *uclogic_params_pen_inrange_to_str( 34 - enum uclogic_params_pen_inrange inrange); 35 - 36 - 37 32 /* 38 33 * Pen report's subreport data. 39 34 */ ··· 57 62 */ 58 63 struct uclogic_params_pen { 59 64 /* 60 - * Pointer to report descriptor describing the inputs. 61 - * Allocated with kmalloc. 65 + * True if pen usage is invalid for this interface and should be 66 + * ignored, false otherwise. 67 + */ 68 + bool usage_invalid; 69 + /* 70 + * Pointer to report descriptor part describing the pen inputs. 71 + * Allocated with kmalloc. NULL if the part is not specified. 62 72 */ 63 73 __u8 *desc_ptr; 64 74 /* ··· 73 73 unsigned int desc_size; 74 74 /* Report ID, if reports should be tweaked, zero if not */ 75 75 unsigned int id; 76 - /* The list of subreports */ 77 - struct uclogic_params_pen_subreport subreport_list[1]; 76 + /* The list of subreports, only valid if "id" is not zero */ 77 + struct uclogic_params_pen_subreport subreport_list[3]; 78 78 /* Type of in-range reporting, only valid if "id" is not zero */ 79 79 enum uclogic_params_pen_inrange inrange; 80 80 /* ··· 101 101 */ 102 102 struct uclogic_params_frame { 103 103 /* 104 - * Pointer to report descriptor describing the inputs. 105 - * Allocated with kmalloc. 104 + * Pointer to report descriptor part describing the frame inputs. 105 + * Allocated with kmalloc. NULL if the part is not specified. 106 106 */ 107 107 __u8 *desc_ptr; 108 108 /* ··· 115 115 */ 116 116 unsigned int id; 117 117 /* 118 + * The suffix to add to the input device name, if not NULL. 119 + */ 120 + const char *suffix; 121 + /* 118 122 * Number of the least-significant bit of the 2-bit state of a rotary 119 123 * encoder, in the report. Cannot point to a 2-bit field crossing a 120 124 * byte boundary. Zero if not present. Only valid if "id" is not zero. ··· 127 123 /* 128 124 * Offset of the Wacom-style device ID byte in the report, to be set 129 125 * to pad device ID (0xf), for compatibility with Wacom drivers. Zero 130 - * if no changes to the report should be made. Only valid if "id" is 131 - * not zero. 126 + * if no changes to the report should be made. The ID byte will be set 127 + * to zero whenever the byte pointed by "touch_byte" is zero, if 128 + * the latter is valid. Only valid if "id" is not zero. 132 129 */ 133 130 unsigned int dev_id_byte; 131 + /* 132 + * Offset of the touch ring/strip state byte, in the report. 133 + * Zero if not present. If dev_id_byte is also valid and non-zero, 134 + * then the device ID byte will be cleared when the byte pointed to by 135 + * this offset is zero. Only valid if "id" is not zero. 136 + */ 137 + unsigned int touch_byte; 138 + /* 139 + * The value to anchor the reversed touch ring/strip reports at. 140 + * I.e. one, if the reports should be flipped without offset. 141 + * Zero if no reversal should be done. 142 + * Only valid if "touch_byte" is valid and not zero. 143 + */ 144 + __s8 touch_flip_at; 145 + /* 146 + * Maximum value of the touch ring/strip report around which the value 147 + * should be wrapped when flipping according to "touch_flip_at". 148 + * The minimum valid value is considered to be one, with zero being 149 + * out-of-proximity (finger lift) value. 150 + * Only valid if "touch_flip_at" is valid and not zero. 151 + */ 152 + __s8 touch_max; 153 + /* 154 + * Offset of the bitmap dial byte, in the report. Zero if not present. 155 + * Only valid if "id" is not zero. A bitmap dial sends reports with a 156 + * dedicated bit per direction: 1 means clockwise rotation, 2 means 157 + * counterclockwise, as opposed to the normal 1 and -1. 158 + */ 159 + unsigned int bitmap_dial_byte; 134 160 }; 135 161 136 162 /* ··· 190 156 __u8 *desc_ptr; 191 157 /* 192 158 * Size of the common part of the replacement report descriptor. 193 - * Only valid, if "desc_ptr" is not NULL. 159 + * Only valid, if "desc_ptr" is valid and not NULL. 194 160 */ 195 161 unsigned int desc_size; 196 162 /* ··· 202 168 * The list of frame control parameters and optional report descriptor 203 169 * parts. Only valid, if "invalid" is false. 204 170 */ 205 - struct uclogic_params_frame frame_list[1]; 171 + struct uclogic_params_frame frame_list[3]; 206 172 }; 207 173 208 174 /* Initialize a tablet interface and discover its parameters */ 209 175 extern int uclogic_params_init(struct uclogic_params *params, 210 176 struct hid_device *hdev); 211 - 212 - /* Tablet interface parameters *printf format string */ 213 - #define UCLOGIC_PARAMS_FMT_STR \ 214 - ".invalid = %s\n" \ 215 - ".desc_ptr = %p\n" \ 216 - ".desc_size = %u\n" \ 217 - ".pen.desc_ptr = %p\n" \ 218 - ".pen.desc_size = %u\n" \ 219 - ".pen.id = %u\n" \ 220 - ".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \ 221 - ".pen.inrange = %s\n" \ 222 - ".pen.fragmented_hires = %s\n" \ 223 - ".pen.tilt_y_flipped = %s\n" \ 224 - ".frame_list[0].desc_ptr = %p\n" \ 225 - ".frame_list[0].desc_size = %u\n" \ 226 - ".frame_list[0].id = %u\n" \ 227 - ".frame_list[0].re_lsb = %u\n" \ 228 - ".frame_list[0].dev_id_byte = %u\n" 229 - 230 - /* Tablet interface parameters *printf format arguments */ 231 - #define UCLOGIC_PARAMS_FMT_ARGS(_params) \ 232 - ((_params)->invalid ? "true" : "false"), \ 233 - (_params)->desc_ptr, \ 234 - (_params)->desc_size, \ 235 - (_params)->pen.desc_ptr, \ 236 - (_params)->pen.desc_size, \ 237 - (_params)->pen.id, \ 238 - (_params)->pen.subreport_list[0].value, \ 239 - (_params)->pen.subreport_list[0].id, \ 240 - uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \ 241 - ((_params)->pen.fragmented_hires ? "true" : "false"), \ 242 - ((_params)->pen.tilt_y_flipped ? "true" : "false"), \ 243 - (_params)->frame_list[0].desc_ptr, \ 244 - (_params)->frame_list[0].desc_size, \ 245 - (_params)->frame_list[0].id, \ 246 - (_params)->frame_list[0].re_lsb, \ 247 - (_params)->frame_list[0].dev_id_byte 248 177 249 178 /* Get a replacement report descriptor for a tablet's interface. */ 250 179 extern int uclogic_params_get_desc(const struct uclogic_params *params, ··· 216 219 217 220 /* Free resources used by tablet interface's parameters */ 218 221 extern void uclogic_params_cleanup(struct uclogic_params *params); 222 + 223 + /* Dump tablet interface parameters with hid_dbg() */ 224 + extern void uclogic_params_hid_dbg(const struct hid_device *hdev, 225 + const struct uclogic_params *params); 219 226 220 227 #endif /* _HID_UCLOGIC_PARAMS_H */
+164 -17
drivers/hid/hid-uclogic-rdesc.c
··· 21 21 /* Fixed WP4030U report descriptor */ 22 22 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = { 23 23 0x05, 0x0D, /* Usage Page (Digitizer), */ 24 - 0x09, 0x02, /* Usage (Pen), */ 24 + 0x09, 0x01, /* Usage (Digitizer), */ 25 25 0xA1, 0x01, /* Collection (Application), */ 26 26 0x85, 0x09, /* Report ID (9), */ 27 27 0x09, 0x20, /* Usage (Stylus), */ ··· 66 66 /* Fixed WP5540U report descriptor */ 67 67 __u8 uclogic_rdesc_wp5540u_fixed_arr[] = { 68 68 0x05, 0x0D, /* Usage Page (Digitizer), */ 69 - 0x09, 0x02, /* Usage (Pen), */ 69 + 0x09, 0x01, /* Usage (Digitizer), */ 70 70 0xA1, 0x01, /* Collection (Application), */ 71 71 0x85, 0x09, /* Report ID (9), */ 72 72 0x09, 0x20, /* Usage (Stylus), */ ··· 143 143 /* Fixed WP8060U report descriptor */ 144 144 __u8 uclogic_rdesc_wp8060u_fixed_arr[] = { 145 145 0x05, 0x0D, /* Usage Page (Digitizer), */ 146 - 0x09, 0x02, /* Usage (Pen), */ 146 + 0x09, 0x01, /* Usage (Digitizer), */ 147 147 0xA1, 0x01, /* Collection (Application), */ 148 148 0x85, 0x09, /* Report ID (9), */ 149 149 0x09, 0x20, /* Usage (Stylus), */ ··· 220 220 /* Fixed WP1062 report descriptor */ 221 221 __u8 uclogic_rdesc_wp1062_fixed_arr[] = { 222 222 0x05, 0x0D, /* Usage Page (Digitizer), */ 223 - 0x09, 0x02, /* Usage (Pen), */ 223 + 0x09, 0x01, /* Usage (Digitizer), */ 224 224 0xA1, 0x01, /* Collection (Application), */ 225 225 0x85, 0x09, /* Report ID (9), */ 226 226 0x09, 0x20, /* Usage (Stylus), */ ··· 268 268 /* Fixed PF1209 report descriptor */ 269 269 __u8 uclogic_rdesc_pf1209_fixed_arr[] = { 270 270 0x05, 0x0D, /* Usage Page (Digitizer), */ 271 - 0x09, 0x02, /* Usage (Pen), */ 271 + 0x09, 0x01, /* Usage (Digitizer), */ 272 272 0xA1, 0x01, /* Collection (Application), */ 273 273 0x85, 0x09, /* Report ID (9), */ 274 274 0x09, 0x20, /* Usage (Stylus), */ ··· 345 345 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */ 346 346 __u8 uclogic_rdesc_twhl850_fixed0_arr[] = { 347 347 0x05, 0x0D, /* Usage Page (Digitizer), */ 348 - 0x09, 0x02, /* Usage (Pen), */ 348 + 0x09, 0x01, /* Usage (Digitizer), */ 349 349 0xA1, 0x01, /* Collection (Application), */ 350 350 0x85, 0x09, /* Report ID (9), */ 351 351 0x09, 0x20, /* Usage (Stylus), */ ··· 457 457 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */ 458 458 __u8 uclogic_rdesc_twha60_fixed0_arr[] = { 459 459 0x05, 0x0D, /* Usage Page (Digitizer), */ 460 - 0x09, 0x02, /* Usage (Pen), */ 460 + 0x09, 0x01, /* Usage (Digitizer), */ 461 461 0xA1, 0x01, /* Collection (Application), */ 462 462 0x85, 0x09, /* Report ID (9), */ 463 463 0x09, 0x20, /* Usage (Stylus), */ ··· 534 534 /* Fixed report descriptor template for (tweaked) v1 pen reports */ 535 535 const __u8 uclogic_rdesc_v1_pen_template_arr[] = { 536 536 0x05, 0x0D, /* Usage Page (Digitizer), */ 537 - 0x09, 0x02, /* Usage (Pen), */ 537 + 0x09, 0x01, /* Usage (Digitizer), */ 538 538 0xA1, 0x01, /* Collection (Application), */ 539 539 0x85, 0x07, /* Report ID (7), */ 540 540 0x09, 0x20, /* Usage (Stylus), */ ··· 588 588 /* Fixed report descriptor template for (tweaked) v2 pen reports */ 589 589 const __u8 uclogic_rdesc_v2_pen_template_arr[] = { 590 590 0x05, 0x0D, /* Usage Page (Digitizer), */ 591 - 0x09, 0x02, /* Usage (Pen), */ 591 + 0x09, 0x01, /* Usage (Digitizer), */ 592 592 0xA1, 0x01, /* Collection (Application), */ 593 593 0x85, 0x08, /* Report ID (8), */ 594 594 0x09, 0x20, /* Usage (Stylus), */ ··· 652 652 sizeof(uclogic_rdesc_v2_pen_template_arr); 653 653 654 654 /* 655 - * Expand to the contents of a generic frame report descriptor. 655 + * Expand to the contents of a generic frame buttons report descriptor. 656 656 * 657 657 * @_id: The report ID to use. 658 658 * @_size: Size of the report to pad to, including report ID, bytes. 659 659 */ 660 - #define UCLOGIC_RDESC_FRAME_BYTES(_id, _size) \ 660 + #define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \ 661 661 0x05, 0x01, /* Usage Page (Desktop), */ \ 662 662 0x09, 0x07, /* Usage (Keypad), */ \ 663 663 0xA1, 0x01, /* Collection (Application), */ \ ··· 700 700 701 701 /* Fixed report descriptor for (tweaked) v1 frame reports */ 702 702 const __u8 uclogic_rdesc_v1_frame_arr[] = { 703 - UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8) 703 + UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8) 704 704 }; 705 705 const size_t uclogic_rdesc_v1_frame_size = 706 706 sizeof(uclogic_rdesc_v1_frame_arr); 707 707 708 - /* Fixed report descriptor for (tweaked) v2 frame reports */ 709 - const __u8 uclogic_rdesc_v2_frame_arr[] = { 710 - UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V2_FRAME_ID, 12) 708 + /* Fixed report descriptor for (tweaked) v2 frame button reports */ 709 + const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = { 710 + UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID, 711 + 12) 711 712 }; 712 - const size_t uclogic_rdesc_v2_frame_size = 713 - sizeof(uclogic_rdesc_v2_frame_arr); 713 + const size_t uclogic_rdesc_v2_frame_buttons_size = 714 + sizeof(uclogic_rdesc_v2_frame_buttons_arr); 715 + 716 + /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */ 717 + const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = { 718 + 0x05, 0x01, /* Usage Page (Desktop), */ 719 + 0x09, 0x07, /* Usage (Keypad), */ 720 + 0xA1, 0x01, /* Collection (Application), */ 721 + 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 722 + /* Report ID (TOUCH_ID), */ 723 + 0x14, /* Logical Minimum (0), */ 724 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 725 + 0x09, 0x39, /* Usage (Tablet Function Keys), */ 726 + 0xA0, /* Collection (Physical), */ 727 + 0x25, 0x01, /* Logical Maximum (1), */ 728 + 0x75, 0x01, /* Report Size (1), */ 729 + 0x05, 0x09, /* Usage Page (Button), */ 730 + 0x09, 0x01, /* Usage (01h), */ 731 + 0x95, 0x01, /* Report Count (1), */ 732 + 0x81, 0x02, /* Input (Variable), */ 733 + 0x95, 0x07, /* Report Count (7), */ 734 + 0x81, 0x01, /* Input (Constant), */ 735 + 0x75, 0x08, /* Report Size (8), */ 736 + 0x95, 0x02, /* Report Count (2), */ 737 + 0x81, 0x01, /* Input (Constant), */ 738 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 739 + 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 740 + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 741 + 0x95, 0x01, /* Report Count (1), */ 742 + 0x81, 0x02, /* Input (Variable), */ 743 + 0x05, 0x01, /* Usage Page (Desktop), */ 744 + 0x09, 0x38, /* Usage (Wheel), */ 745 + 0x95, 0x01, /* Report Count (1), */ 746 + 0x15, 0x00, /* Logical Minimum (0), */ 747 + 0x25, 0x0B, /* Logical Maximum (11), */ 748 + 0x81, 0x02, /* Input (Variable), */ 749 + 0x09, 0x30, /* Usage (X), */ 750 + 0x09, 0x31, /* Usage (Y), */ 751 + 0x14, /* Logical Minimum (0), */ 752 + 0x25, 0x01, /* Logical Maximum (1), */ 753 + 0x75, 0x01, /* Report Size (1), */ 754 + 0x95, 0x02, /* Report Count (2), */ 755 + 0x81, 0x02, /* Input (Variable), */ 756 + 0x95, 0x2E, /* Report Count (46), */ 757 + 0x81, 0x01, /* Input (Constant), */ 758 + 0xC0, /* End Collection, */ 759 + 0xC0 /* End Collection */ 760 + }; 761 + const size_t uclogic_rdesc_v2_frame_touch_ring_size = 762 + sizeof(uclogic_rdesc_v2_frame_touch_ring_arr); 763 + 764 + /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */ 765 + const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = { 766 + 0x05, 0x01, /* Usage Page (Desktop), */ 767 + 0x09, 0x07, /* Usage (Keypad), */ 768 + 0xA1, 0x01, /* Collection (Application), */ 769 + 0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID, 770 + /* Report ID (TOUCH_ID), */ 771 + 0x14, /* Logical Minimum (0), */ 772 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 773 + 0x09, 0x39, /* Usage (Tablet Function Keys), */ 774 + 0xA0, /* Collection (Physical), */ 775 + 0x25, 0x01, /* Logical Maximum (1), */ 776 + 0x75, 0x01, /* Report Size (1), */ 777 + 0x05, 0x09, /* Usage Page (Button), */ 778 + 0x09, 0x01, /* Usage (01h), */ 779 + 0x95, 0x01, /* Report Count (1), */ 780 + 0x81, 0x02, /* Input (Variable), */ 781 + 0x95, 0x07, /* Report Count (7), */ 782 + 0x81, 0x01, /* Input (Constant), */ 783 + 0x75, 0x08, /* Report Size (8), */ 784 + 0x95, 0x02, /* Report Count (2), */ 785 + 0x81, 0x01, /* Input (Constant), */ 786 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 787 + 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 788 + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 789 + 0x95, 0x01, /* Report Count (1), */ 790 + 0x81, 0x02, /* Input (Variable), */ 791 + 0x05, 0x01, /* Usage Page (Desktop), */ 792 + 0x09, 0x38, /* Usage (Wheel), */ 793 + 0x95, 0x01, /* Report Count (1), */ 794 + 0x15, 0x00, /* Logical Minimum (0), */ 795 + 0x25, 0x07, /* Logical Maximum (7), */ 796 + 0x81, 0x02, /* Input (Variable), */ 797 + 0x09, 0x30, /* Usage (X), */ 798 + 0x09, 0x31, /* Usage (Y), */ 799 + 0x14, /* Logical Minimum (0), */ 800 + 0x25, 0x01, /* Logical Maximum (1), */ 801 + 0x75, 0x01, /* Report Size (1), */ 802 + 0x95, 0x02, /* Report Count (2), */ 803 + 0x81, 0x02, /* Input (Variable), */ 804 + 0x95, 0x2E, /* Report Count (46), */ 805 + 0x81, 0x01, /* Input (Constant), */ 806 + 0xC0, /* End Collection, */ 807 + 0xC0 /* End Collection */ 808 + }; 809 + const size_t uclogic_rdesc_v2_frame_touch_strip_size = 810 + sizeof(uclogic_rdesc_v2_frame_touch_strip_arr); 811 + 812 + /* Fixed report descriptor for (tweaked) v2 frame dial reports */ 813 + const __u8 uclogic_rdesc_v2_frame_dial_arr[] = { 814 + 0x05, 0x01, /* Usage Page (Desktop), */ 815 + 0x09, 0x07, /* Usage (Keypad), */ 816 + 0xA1, 0x01, /* Collection (Application), */ 817 + 0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID, 818 + /* Report ID (DIAL_ID), */ 819 + 0x14, /* Logical Minimum (0), */ 820 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 821 + 0x09, 0x39, /* Usage (Tablet Function Keys), */ 822 + 0xA0, /* Collection (Physical), */ 823 + 0x25, 0x01, /* Logical Maximum (1), */ 824 + 0x75, 0x01, /* Report Size (1), */ 825 + 0x95, 0x01, /* Report Count (1), */ 826 + 0x81, 0x01, /* Input (Constant), */ 827 + 0x05, 0x09, /* Usage Page (Button), */ 828 + 0x09, 0x01, /* Usage (01h), */ 829 + 0x95, 0x01, /* Report Count (1), */ 830 + 0x81, 0x02, /* Input (Variable), */ 831 + 0x95, 0x06, /* Report Count (6), */ 832 + 0x81, 0x01, /* Input (Constant), */ 833 + 0x75, 0x08, /* Report Size (8), */ 834 + 0x95, 0x02, /* Report Count (2), */ 835 + 0x81, 0x01, /* Input (Constant), */ 836 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 837 + 0x0A, 0xFF, 0xFF, /* Usage (FFFFh), */ 838 + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 839 + 0x95, 0x01, /* Report Count (1), */ 840 + 0x81, 0x02, /* Input (Variable), */ 841 + 0x05, 0x01, /* Usage Page (Desktop), */ 842 + 0x09, 0x38, /* Usage (Wheel), */ 843 + 0x95, 0x01, /* Report Count (1), */ 844 + 0x15, 0xFF, /* Logical Minimum (-1), */ 845 + 0x25, 0x01, /* Logical Maximum (1), */ 846 + 0x81, 0x06, /* Input (Variable, Relative), */ 847 + 0x09, 0x30, /* Usage (X), */ 848 + 0x09, 0x31, /* Usage (Y), */ 849 + 0x14, /* Logical Minimum (0), */ 850 + 0x25, 0x01, /* Logical Maximum (1), */ 851 + 0x75, 0x01, /* Report Size (1), */ 852 + 0x95, 0x02, /* Report Count (2), */ 853 + 0x81, 0x02, /* Input (Variable), */ 854 + 0x95, 0x2E, /* Report Count (46), */ 855 + 0x81, 0x01, /* Input (Constant), */ 856 + 0xC0, /* End Collection, */ 857 + 0xC0 /* End Collection */ 858 + }; 859 + const size_t uclogic_rdesc_v2_frame_dial_size = 860 + sizeof(uclogic_rdesc_v2_frame_dial_arr); 714 861 715 862 /* Fixed report descriptor for Ugee EX07 frame */ 716 863 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
+29 -5
drivers/hid/hid-uclogic-rdesc.h
··· 124 124 extern const __u8 uclogic_rdesc_v1_frame_arr[]; 125 125 extern const size_t uclogic_rdesc_v1_frame_size; 126 126 127 - /* Report ID for tweaked v2 frame reports */ 128 - #define UCLOGIC_RDESC_V2_FRAME_ID 0xf7 127 + /* Report ID for tweaked v2 frame button reports */ 128 + #define UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID 0xf7 129 129 130 - /* Fixed report descriptor for (tweaked) v2 frame reports */ 131 - extern const __u8 uclogic_rdesc_v2_frame_arr[]; 132 - extern const size_t uclogic_rdesc_v2_frame_size; 130 + /* Fixed report descriptor for (tweaked) v2 frame button reports */ 131 + extern const __u8 uclogic_rdesc_v2_frame_buttons_arr[]; 132 + extern const size_t uclogic_rdesc_v2_frame_buttons_size; 133 + 134 + /* Report ID for tweaked v2 frame touch ring/strip reports */ 135 + #define UCLOGIC_RDESC_V2_FRAME_TOUCH_ID 0xf8 136 + 137 + /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */ 138 + extern const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[]; 139 + extern const size_t uclogic_rdesc_v2_frame_touch_ring_size; 140 + 141 + /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */ 142 + extern const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[]; 143 + extern const size_t uclogic_rdesc_v2_frame_touch_strip_size; 144 + 145 + /* Device ID byte offset in v2 frame touch ring/strip reports */ 146 + #define UCLOGIC_RDESC_V2_FRAME_TOUCH_DEV_ID_BYTE 0x4 147 + 148 + /* Report ID for tweaked v2 frame dial reports */ 149 + #define UCLOGIC_RDESC_V2_FRAME_DIAL_ID 0xf9 150 + 151 + /* Fixed report descriptor for (tweaked) v2 frame dial reports */ 152 + extern const __u8 uclogic_rdesc_v2_frame_dial_arr[]; 153 + extern const size_t uclogic_rdesc_v2_frame_dial_size; 154 + 155 + /* Device ID byte offset in v2 frame dial reports */ 156 + #define UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE 0x4 133 157 134 158 /* Fixed report descriptor for Ugee EX07 frame */ 135 159 extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
+1 -1
drivers/hid/hid-viewsonic.c
··· 24 24 /* Fixed report descriptor of PD1011 signature pad */ 25 25 static __u8 pd1011_rdesc_fixed[] = { 26 26 0x05, 0x0D, /* Usage Page (Digitizer), */ 27 - 0x09, 0x02, /* Usage (Pen), */ 27 + 0x09, 0x01, /* Usage (Digitizer), */ 28 28 0xA1, 0x01, /* Collection (Application), */ 29 29 0x85, 0x02, /* Report ID (2), */ 30 30 0x09, 0x20, /* Usage (Stylus), */
+2
drivers/hid/intel-ish-hid/ipc/hw-ish.h
··· 30 30 #define TGL_H_DEVICE_ID 0x43FC 31 31 #define ADL_S_DEVICE_ID 0x7AF8 32 32 #define ADL_P_DEVICE_ID 0x51FC 33 + #define ADL_N_DEVICE_ID 0x54FC 34 + #define RPL_S_DEVICE_ID 0x7A78 33 35 34 36 #define REVISION_ID_CHT_A0 0x6 35 37 #define REVISION_ID_CHT_Ax_SI 0x0
+2
drivers/hid/intel-ish-hid/ipc/pci-ish.c
··· 41 41 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_H_DEVICE_ID)}, 42 42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_S_DEVICE_ID)}, 43 43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_P_DEVICE_ID)}, 44 + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_N_DEVICE_ID)}, 45 + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, RPL_S_DEVICE_ID)}, 44 46 {0, } 45 47 }; 46 48 MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
+1 -1
drivers/hid/wacom_sys.c
··· 1777 1777 bat_desc->get_property = wacom_battery_get_property; 1778 1778 sprintf(battery->bat_name, "wacom_battery_%ld", n); 1779 1779 bat_desc->name = battery->bat_name; 1780 - bat_desc->type = POWER_SUPPLY_TYPE_USB; 1780 + bat_desc->type = POWER_SUPPLY_TYPE_BATTERY; 1781 1781 bat_desc->use_for_apm = 0; 1782 1782 1783 1783 ps_bat = devm_power_supply_register(dev, bat_desc, &psy_cfg);
+35 -8
drivers/hid/wacom_wac.c
··· 1811 1811 usage == WACOM_HID_WD_TOUCHSTRIP2 || 1812 1812 usage == WACOM_HID_WD_TOUCHRING || 1813 1813 usage == WACOM_HID_WD_TOUCHRINGSTATUS || 1814 - usage == WACOM_HID_WD_REPORT_VALID) { 1814 + usage == WACOM_HID_WD_REPORT_VALID || 1815 + usage == WACOM_HID_WD_BARRELSWITCH3 || 1816 + usage == WACOM_HID_WD_SEQUENCENUMBER) { 1815 1817 return usage; 1816 1818 } 1817 1819 ··· 2198 2196 if (!(features->quirks & WACOM_QUIRK_AESPEN) && 2199 2197 wacom_wac->hid_data.barrelswitch && 2200 2198 wacom_wac->hid_data.barrelswitch2 && 2201 - wacom_wac->hid_data.serialhi) 2199 + wacom_wac->hid_data.serialhi && 2200 + !wacom_wac->hid_data.barrelswitch3) { 2202 2201 input_set_capability(input, EV_KEY, BTN_STYLUS3); 2202 + features->quirks |= WACOM_QUIRK_PEN_BUTTON3; 2203 + } 2203 2204 } 2204 2205 2205 2206 static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, ··· 2266 2261 features->quirks |= WACOM_QUIRK_TOOLSERIAL; 2267 2262 wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0); 2268 2263 break; 2264 + case HID_DG_SCANTIME: 2265 + wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0); 2266 + break; 2269 2267 case WACOM_HID_WD_SENSE: 2270 2268 features->quirks |= WACOM_QUIRK_SENSE; 2271 2269 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0); ··· 2281 2273 case WACOM_HID_WD_FINGERWHEEL: 2282 2274 input_set_capability(input, EV_KEY, BTN_TOOL_AIRBRUSH); 2283 2275 wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); 2276 + break; 2277 + case WACOM_HID_WD_BARRELSWITCH3: 2278 + wacom_wac->hid_data.barrelswitch3 = true; 2279 + wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0); 2280 + features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3; 2284 2281 break; 2285 2282 } 2286 2283 } ··· 2403 2390 case WACOM_HID_WD_REPORT_VALID: 2404 2391 wacom_wac->is_invalid_bt_frame = !value; 2405 2392 return; 2393 + case WACOM_HID_WD_BARRELSWITCH3: 2394 + wacom_wac->hid_data.barrelswitch3 = value; 2395 + return; 2396 + case WACOM_HID_WD_SEQUENCENUMBER: 2397 + if (wacom_wac->hid_data.sequence_number != value) 2398 + hid_warn(hdev, "Dropped %hu packets", (unsigned short)(value - wacom_wac->hid_data.sequence_number)); 2399 + wacom_wac->hid_data.sequence_number = value + 1; 2400 + return; 2406 2401 } 2407 2402 2408 2403 /* send pen events only when touch is up or forced out ··· 2463 2442 2464 2443 if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) { 2465 2444 int id = wacom_wac->id[0]; 2466 - int sw_state = wacom_wac->hid_data.barrelswitch | 2467 - (wacom_wac->hid_data.barrelswitch2 << 1); 2468 - 2469 - input_report_key(input, BTN_STYLUS, sw_state == 1); 2470 - input_report_key(input, BTN_STYLUS2, sw_state == 2); 2471 - input_report_key(input, BTN_STYLUS3, sw_state == 3); 2445 + if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 && 2446 + wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) { 2447 + wacom_wac->hid_data.barrelswitch = 0; 2448 + wacom_wac->hid_data.barrelswitch2 = 0; 2449 + wacom_wac->hid_data.barrelswitch3 = 1; 2450 + } 2451 + input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch); 2452 + input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2); 2453 + input_report_key(input, BTN_STYLUS3, wacom_wac->hid_data.barrelswitch3); 2472 2454 2473 2455 /* 2474 2456 * Non-USI EMR tools should have their IDs mangled to ··· 2552 2528 */ 2553 2529 field->logical_maximum = 255; 2554 2530 } 2531 + break; 2532 + case HID_DG_SCANTIME: 2533 + wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0); 2555 2534 break; 2556 2535 } 2557 2536 }
+5
drivers/hid/wacom_wac.h
··· 86 86 #define WACOM_QUIRK_AESPEN 0x0004 87 87 #define WACOM_QUIRK_BATTERY 0x0008 88 88 #define WACOM_QUIRK_TOOLSERIAL 0x0010 89 + #define WACOM_QUIRK_PEN_BUTTON3 0x0020 89 90 90 91 /* device types */ 91 92 #define WACOM_DEVICETYPE_NONE 0x0000 ··· 109 108 #define WACOM_HID_WD_DIGITIZERFNKEYS (WACOM_HID_UP_WACOMDIGITIZER | 0x39) 110 109 #define WACOM_HID_WD_SERIALNUMBER (WACOM_HID_UP_WACOMDIGITIZER | 0x5b) 111 110 #define WACOM_HID_WD_SERIALHI (WACOM_HID_UP_WACOMDIGITIZER | 0x5c) 111 + #define WACOM_HID_WD_BARRELSWITCH3 (WACOM_HID_UP_WACOMDIGITIZER | 0x5d) 112 112 #define WACOM_HID_WD_TOOLTYPE (WACOM_HID_UP_WACOMDIGITIZER | 0x77) 113 113 #define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132) 114 114 #define WACOM_HID_WD_TOUCHSTRIP (WACOM_HID_UP_WACOMDIGITIZER | 0x0136) ··· 117 115 #define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138) 118 116 #define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139) 119 117 #define WACOM_HID_WD_REPORT_VALID (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0) 118 + #define WACOM_HID_WD_SEQUENCENUMBER (WACOM_HID_UP_WACOMDIGITIZER | 0x0220) 120 119 #define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401) 121 120 #define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402) 122 121 #define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403) ··· 303 300 bool tipswitch; 304 301 bool barrelswitch; 305 302 bool barrelswitch2; 303 + bool barrelswitch3; 306 304 bool serialhi; 307 305 bool confidence; 308 306 int x; ··· 324 320 int bat_connected; 325 321 int ps_connected; 326 322 bool pad_input_event_flag; 323 + unsigned short sequence_number; 327 324 }; 328 325 329 326 struct wacom_remote_data {
+1
include/uapi/linux/input.h
··· 271 271 #define BUS_RMI 0x1D 272 272 #define BUS_CEC 0x1E 273 273 #define BUS_INTEL_ISHTP 0x1F 274 + #define BUS_AMD_SFH 0x20 274 275 275 276 /* 276 277 * MT_TOOL types