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

Pull HID updates from Jiri Kosina:

 - hardening of HID core parser against conversion to 0 bits in s32ton()
   by buggy/malicious devices (Alan Stern)

 - fix for potential NULL pointer dereference in hid-apple that could be
   caused by malicious device with APPLE_MAGIC_BACKLIGHT quirk present
   triggering overflow in data field (Qasim Ijaz)

 - support for Wake-on-touch in intel-thc (Even Xu)

 - support for "Input max input size control" and "Input interrupt
   delay" I2C features in order to improve compatibility of THC devices
   with legacy HIDI2C touch devices (Even Xu)

 - support for Touch Bars on x86 MacBook Pros (Kerem Karabay)

 - support for XP-PEN Artist 22R Pro (Joshua Goins)

 - third party trackpart support for MacBookPro15,1 (Aditya Garg)

 - Apple Magic Keyboard A311[89] USB-C support (Aditya Garg, Grigorii
   Sokoli)

 - support for operating modes in amd-sfh (Basavaraj Natikar)

 - avoid setting up battery timer for Apple and Magicmouse devices
   without battery (Aditya Garg)

 - fix for behavior of the hid-mcp2221 driver for !CONFIG_IIO cases
   (Heiko Schocher)

 - other assorted fixups and device ID additions

* tag 'hid-for-linus-2025073101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (54 commits)
  HID: core: Harden s32ton() against conversion to 0 bits
  HID: apple: validate feature-report field count to prevent NULL pointer dereference
  HID: core: Improve the kerneldoc for hid_report_len()
  selftests/hid: sync python tests to hid-tools 0.10
  selftests/hid: sync the python tests to hid-tools 0.8
  selftests/hid: run ruff format on the python part
  HID: magicmouse: use secs_to_jiffies() for battery timeout
  HID: apple: use secs_to_jiffies() for battery timeout
  HID: magicmouse: avoid setting up battery timer when not needed
  HID: apple: avoid setting up battery timer for devices without battery
  HID: amd_sfh: Enable operating mode
  HID: uclogic: Add support for XP-PEN Artist 22R Pro
  HID: rate-limit hid_warn to prevent log flooding
  HID: replace scnprintf() with sysfs_emit()
  HID: uclogic: make read-only array reconnect_event static const
  HID: mcp-2221: Replace manual comparison with min() macro
  HID: intel-thc-hid: Separate max input size control conditional list
  HID: mcp2221: set gpio pin mode
  HID: multitouch: add device ID for Apple Touch Bar
  HID: multitouch: specify that Apple Touch Bar is direct
  ...
This commit is contained in:
Linus Torvalds
2025-07-31 21:26:05 -07:00
44 changed files with 1667 additions and 476 deletions
+28
View File
@@ -188,6 +188,34 @@ Control register.
Reset line is controlled by BIOS (or EFI) through ACPI _RST method, driver needs to call this
device ACPI _RST method to reset touch IC during initialization.
2.3 Max input size control
--------------------------
This is a new feature introduced in Panther Lake platform, THC hardware allows driver to set
a max input size for RxDMA. After this max size gets set and enabled, for every input report
packet reading, THC hardware sequencer will first read incoming input packet size, then compare
input packet size with the given max size:
- if input packet size <= max size, THC continues using input packet size to finish the reading
- if input packet size > max size, there is potential input data crash risk during
transferring, THC will use max size instead of input packet size for reading
This feature is used to avoid data corruption which will cause RxDMA buffer overrun issue for
I2C bus, and enhance whole system stability.
2.4 Interrupt delay
-------------------
Because of MCU performance limitation, some touch devices cannot de-assert interrupt pin
immediately after input data is transferred, which cause an interrupt toggle delay. But THC
always detects next interrupt immediately after last input interrupt is handled. In this
case, the delayed interrupt de-assertion will be recognized as a new interrupt signal by THC,
and causes THC to start an input report reading spuriously.
In order to avoid this situation, THC introduced interrupt delay new feature in Panther Lake
platform, where THC allows driver to set an interrupt delay. After this feature is enabled,
THC will delay this given time for next interrupt detection.
3. High level concept
=====================
+1
View File
@@ -771,6 +771,7 @@ config HID_MULTITOUCH
Say Y here if you have one of the following devices:
- 3M PCT touch screens
- ActionStar dual touch panels
- Apple Touch Bar on x86 MacBook Pros
- Atmel panels
- Cando dual touch panels
- Chunghwa panels
+23
View File
@@ -146,6 +146,8 @@ static const char *get_sensor_name(int idx)
return "gyroscope";
case mag_idx:
return "magnetometer";
case op_idx:
return "operating-mode";
case als_idx:
case ACS_IDX: /* ambient color sensor */
return "ALS";
@@ -243,6 +245,20 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
rc = -ENOMEM;
goto cleanup;
}
if (cl_data->sensor_idx[i] == op_idx) {
info.period = AMD_SFH_IDLE_LOOP;
info.sensor_idx = cl_data->sensor_idx[i];
info.dma_address = cl_data->sensor_dma_addr[i];
mp2_ops->start(privdata, info);
cl_data->sensor_sts[i] = amd_sfh_wait_for_response(privdata,
cl_data->sensor_idx[i],
SENSOR_ENABLED);
if (cl_data->sensor_sts[i] == SENSOR_ENABLED)
cl_data->is_any_sensor_enabled = true;
continue;
}
cl_data->sensor_sts[i] = SENSOR_DISABLED;
cl_data->sensor_requested_cnt[i] = 0;
cl_data->cur_hid_dev = i;
@@ -303,6 +319,13 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
for (i = 0; i < cl_data->num_hid_devices; i++) {
cl_data->cur_hid_dev = i;
if (cl_data->sensor_idx[i] == op_idx) {
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
continue;
}
if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
rc = amdtp_hid_probe(i, cl_data);
if (rc)
+1 -1
View File
@@ -11,7 +11,7 @@
#ifndef AMDSFH_HID_H
#define AMDSFH_HID_H
#define MAX_HID_DEVICES 6
#define MAX_HID_DEVICES 7
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001
+4
View File
@@ -29,6 +29,7 @@
#define ACEL_EN BIT(0)
#define GYRO_EN BIT(1)
#define MAGNO_EN BIT(2)
#define OP_EN BIT(15)
#define HPD_EN BIT(16)
#define ALS_EN BIT(19)
#define ACS_EN BIT(22)
@@ -232,6 +233,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
if (MAGNO_EN & activestatus)
sensor_id[num_of_sensors++] = mag_idx;
if (OP_EN & activestatus)
sensor_id[num_of_sensors++] = op_idx;
if (ALS_EN & activestatus)
sensor_id[num_of_sensors++] = als_idx;
+1
View File
@@ -79,6 +79,7 @@ enum sensor_idx {
accel_idx = 0,
gyro_idx = 1,
mag_idx = 2,
op_idx = 15,
als_idx = 19
};
+145 -99
View File
@@ -30,7 +30,7 @@
#include "hid-ids.h"
#define APPLE_RDESC_JIS BIT(0)
#define APPLE_IGNORE_MOUSE BIT(1)
/* BIT(1) reserved, was: APPLE_IGNORE_MOUSE */
#define APPLE_HAS_FN BIT(2)
/* BIT(3) reserved, was: APPLE_HIDDEV */
#define APPLE_ISO_TILDE_QUIRK BIT(4)
@@ -42,11 +42,13 @@
#define APPLE_BACKLIGHT_CTL BIT(10)
#define APPLE_IS_NON_APPLE BIT(11)
#define APPLE_MAGIC_BACKLIGHT BIT(12)
#define APPLE_DISABLE_FKEYS BIT(13)
#define APPLE_FLAG_FKEY 0x01
#define APPLE_FLAG_FKEY BIT(0)
#define APPLE_FLAG_TB_FKEY BIT(1)
#define HID_COUNTRY_INTERNATIONAL_ISO 13
#define APPLE_BATTERY_TIMEOUT_MS 60000
#define APPLE_BATTERY_TIMEOUT_SEC 60
#define HID_USAGE_MAGIC_BL 0xff00000f
#define APPLE_MAGIC_REPORT_ID_POWER 3
@@ -55,7 +57,7 @@
static unsigned int fnmode = 3;
module_param(fnmode, uint, 0644);
MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
"1 = fkeyslast, 2 = fkeysfirst, [3] = auto)");
"1 = fkeyslast, 2 = fkeysfirst, [3] = auto, 4 = fkeysdisabled)");
static int iso_layout = -1;
module_param(iso_layout, int, 0644);
@@ -89,6 +91,19 @@ struct apple_sc_backlight {
struct hid_device *hdev;
};
struct apple_backlight_config_report {
u8 report_id;
u8 version;
u16 backlight_off, backlight_on_min, backlight_on_max;
};
struct apple_backlight_set_report {
u8 report_id;
u8 version;
u16 backlight;
u16 rate;
};
struct apple_magic_backlight {
struct led_classdev cdev;
struct hid_report *brightness;
@@ -108,7 +123,7 @@ struct apple_sc {
struct apple_key_translation {
u16 from;
u16 to;
u8 flags;
unsigned long flags;
};
static const struct apple_key_translation magic_keyboard_alu_fn_keys[] = {
@@ -152,21 +167,7 @@ static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = {
{ }
};
struct apple_backlight_config_report {
u8 report_id;
u8 version;
u16 backlight_off, backlight_on_min, backlight_on_max;
};
struct apple_backlight_set_report {
u8 report_id;
u8 version;
u16 backlight;
u16 rate;
};
static const struct apple_key_translation apple2021_fn_keys[] = {
static const struct apple_key_translation magic_keyboard_2021_and_2024_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -212,19 +213,19 @@ static const struct apple_key_translation macbookair_fn_keys[] = {
static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_GRAVE, KEY_ESC },
{ KEY_1, KEY_F1 },
{ KEY_2, KEY_F2 },
{ KEY_3, KEY_F3 },
{ KEY_4, KEY_F4 },
{ KEY_5, KEY_F5 },
{ KEY_6, KEY_F6 },
{ KEY_7, KEY_F7 },
{ KEY_8, KEY_F8 },
{ KEY_9, KEY_F9 },
{ KEY_0, KEY_F10 },
{ KEY_MINUS, KEY_F11 },
{ KEY_EQUAL, KEY_F12 },
{ KEY_GRAVE, KEY_ESC, APPLE_FLAG_TB_FKEY },
{ KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY },
{ KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY },
{ KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY },
{ KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY },
{ KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY },
{ KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY },
{ KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY },
{ KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY },
{ KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY },
{ KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY },
{ KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY },
{ KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
@@ -235,18 +236,18 @@ static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = {
static const struct apple_key_translation macbookpro_dedicated_esc_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_1, KEY_F1 },
{ KEY_2, KEY_F2 },
{ KEY_3, KEY_F3 },
{ KEY_4, KEY_F4 },
{ KEY_5, KEY_F5 },
{ KEY_6, KEY_F6 },
{ KEY_7, KEY_F7 },
{ KEY_8, KEY_F8 },
{ KEY_9, KEY_F9 },
{ KEY_0, KEY_F10 },
{ KEY_MINUS, KEY_F11 },
{ KEY_EQUAL, KEY_F12 },
{ KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY },
{ KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY },
{ KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY },
{ KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY },
{ KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY },
{ KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY },
{ KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY },
{ KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY },
{ KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY },
{ KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY },
{ KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY },
{ KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
@@ -425,7 +426,12 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
unsigned int real_fnmode;
if (fnmode == 3) {
real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1;
if (asc->quirks & APPLE_DISABLE_FKEYS)
real_fnmode = 4;
else if (asc->quirks & APPLE_IS_NON_APPLE)
real_fnmode = 2;
else
real_fnmode = 1;
} else {
real_fnmode = fnmode;
}
@@ -466,42 +472,54 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
asc->fn_on = !!value;
if (real_fnmode) {
if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS)
switch (hid->product) {
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO:
case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS:
table = magic_keyboard_alu_fn_keys;
else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015)
break;
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015:
table = magic_keyboard_2015_fn_keys;
else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021)
table = apple2021_fn_keys;
else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 ||
hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 ||
hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213)
table = macbookpro_no_esc_fn_keys;
else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K ||
hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 ||
hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F)
table = macbookpro_dedicated_esc_fn_keys;
else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K ||
hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K)
table = apple_fn_keys;
else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
table = macbookair_fn_keys;
else if (hid->product < 0x21d || hid->product >= 0x300)
table = powerbook_fn_keys;
else
break;
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024:
case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024:
table = magic_keyboard_2021_and_2024_fn_keys;
break;
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
table = macbookpro_no_esc_fn_keys;
break;
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
table = macbookpro_dedicated_esc_fn_keys;
break;
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
table = apple_fn_keys;
break;
default:
if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
table = macbookair_fn_keys;
else if (hid->product < 0x21d || hid->product >= 0x300)
table = powerbook_fn_keys;
else
table = apple_fn_keys;
}
trans = apple_find_translation(table, code);
@@ -524,9 +542,17 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
do_translate = asc->fn_on;
break;
default:
/* should never happen */
/* case 4 */
do_translate = false;
}
} else if (trans->flags & APPLE_FLAG_TB_FKEY) {
switch (real_fnmode) {
case 4:
do_translate = false;
break;
default:
do_translate = asc->fn_on;
}
} else {
do_translate = asc->fn_on;
}
@@ -619,7 +645,7 @@ static void apple_battery_timer_tick(struct timer_list *t)
if (apple_fetch_battery(hdev) == 0) {
mod_timer(&asc->battery_timer,
jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
jiffies + secs_to_jiffies(APPLE_BATTERY_TIMEOUT_SEC));
}
}
@@ -682,7 +708,7 @@ static void apple_setup_input(struct input_dev *input)
apple_setup_key_translation(input, apple_iso_keyboard);
apple_setup_key_translation(input, magic_keyboard_alu_fn_keys);
apple_setup_key_translation(input, magic_keyboard_2015_fn_keys);
apple_setup_key_translation(input, apple2021_fn_keys);
apple_setup_key_translation(input, magic_keyboard_2021_and_2024_fn_keys);
apple_setup_key_translation(input, macbookpro_no_esc_fn_keys);
apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys);
}
@@ -890,7 +916,8 @@ static int apple_magic_backlight_init(struct hid_device *hdev)
backlight->brightness = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_BRIGHTNESS];
backlight->power = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_POWER];
if (!backlight->brightness || !backlight->power)
if (!backlight->brightness || backlight->brightness->maxfield < 2 ||
!backlight->power || backlight->power->maxfield < 2)
return -ENODEV;
backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT;
@@ -933,10 +960,12 @@ static int apple_probe(struct hid_device *hdev,
return ret;
}
timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
mod_timer(&asc->battery_timer,
jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
apple_fetch_battery(hdev);
if (quirks & APPLE_RDESC_BATTERY) {
timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
mod_timer(&asc->battery_timer,
jiffies + secs_to_jiffies(APPLE_BATTERY_TIMEOUT_SEC));
apple_fetch_battery(hdev);
}
if (quirks & APPLE_BACKLIGHT_CTL)
apple_backlight_init(hdev);
@@ -950,7 +979,9 @@ static int apple_probe(struct hid_device *hdev,
return 0;
out_err:
timer_delete_sync(&asc->battery_timer);
if (quirks & APPLE_RDESC_BATTERY)
timer_delete_sync(&asc->battery_timer);
hid_hw_stop(hdev);
return ret;
}
@@ -959,7 +990,8 @@ static void apple_remove(struct hid_device *hdev)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
timer_delete_sync(&asc->battery_timer);
if (asc->quirks & APPLE_RDESC_BATTERY)
timer_delete_sync(&asc->battery_timer);
hid_hw_stop(hdev);
}
@@ -1129,19 +1161,25 @@ static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
@@ -1157,10 +1195,6 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
@@ -1169,6 +1203,18 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT),
.driver_data = APPLE_MAGIC_BACKLIGHT },
+8 -4
View File
@@ -66,8 +66,12 @@ static s32 snto32(__u32 value, unsigned int n)
static u32 s32ton(__s32 value, unsigned int n)
{
s32 a = value >> (n - 1);
s32 a;
if (!value || !n)
return 0;
a = value >> (n - 1);
if (a && a != -1)
return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
return value & ((1 << n) - 1);
@@ -659,9 +663,9 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
default:
if (item->tag >= HID_MAIN_ITEM_TAG_RESERVED_MIN &&
item->tag <= HID_MAIN_ITEM_TAG_RESERVED_MAX)
hid_warn(parser->device, "reserved main item tag 0x%x\n", item->tag);
hid_warn_ratelimited(parser->device, "reserved main item tag 0x%x\n", item->tag);
else
hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag);
hid_warn_ratelimited(parser->device, "unknown main item tag 0x%x\n", item->tag);
ret = 0;
}
@@ -2809,7 +2813,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
{
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
return scnprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n",
return sysfs_emit(buf, "hid:b%04Xg%04Xv%08Xp%08X\n",
hdev->bus, hdev->group, hdev->vendor, hdev->product);
}
static DEVICE_ATTR_RO(modalias);
+1 -1
View File
@@ -3726,7 +3726,7 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
*/
if (!list->hdev || !list->hdev->debug) {
ret = -EIO;
set_current_state(TASK_RUNNING);
__set_current_state(TASK_RUNNING);
goto out;
}
+17 -13
View File
@@ -167,20 +167,27 @@
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 0x0267
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015 0x026c
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024 0x0321
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024 0x0322
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT 0x0278
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
@@ -188,10 +195,6 @@
#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241
#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
#define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102
#define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302
@@ -846,7 +849,7 @@
#define USB_DEVICE_ID_PXN_V12 0x1212
#define USB_DEVICE_ID_PXN_V12_LITE 0x1112
#define USB_DEVICE_ID_PXN_V12_LITE_2 0x1211
#define USB_DEVICE_LITE_STAR_GT987_FF 0x2141
#define USB_DEVICE_ID_LITE_STAR_GT987 0x2141
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_Z_10_SPK 0x0a07
@@ -1406,6 +1409,7 @@
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW 0x0933
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO 0x091b
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
#define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
+3 -3
View File
@@ -956,7 +956,7 @@ static ssize_t lg4ff_combine_show(struct device *dev, struct device_attribute *a
return 0;
}
count = scnprintf(buf, PAGE_SIZE, "%u\n", entry->wdata.combine);
count = sysfs_emit(buf, "%u\n", entry->wdata.combine);
return count;
}
@@ -1009,7 +1009,7 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att
return 0;
}
count = scnprintf(buf, PAGE_SIZE, "%u\n", entry->wdata.range);
count = sysfs_emit(buf, "%u\n", entry->wdata.range);
return count;
}
@@ -1073,7 +1073,7 @@ static ssize_t lg4ff_real_id_show(struct device *dev, struct device_attribute *a
return 0;
}
count = scnprintf(buf, PAGE_SIZE, "%s: %s\n", entry->wdata.real_tag, entry->wdata.real_name);
count = sysfs_emit(buf, "%s: %s\n", entry->wdata.real_tag, entry->wdata.real_name);
return count;
}
+40 -24
View File
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define MOUSE_REPORT_ID 0x29
#define MOUSE2_REPORT_ID 0x12
#define DOUBLE_REPORT_ID 0xf7
#define USB_BATTERY_TIMEOUT_MS 60000
#define USB_BATTERY_TIMEOUT_SEC 60
/* These definitions are not precise, but they're close enough. (Bits
* 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
@@ -791,17 +791,31 @@ static void magicmouse_enable_mt_work(struct work_struct *work)
hid_err(msc->hdev, "unable to request touch data (%d)\n", ret);
}
static bool is_usb_magicmouse2(__u32 vendor, __u32 product)
{
if (vendor != USB_VENDOR_ID_APPLE)
return false;
return product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC;
}
static bool is_usb_magictrackpad2(__u32 vendor, __u32 product)
{
if (vendor != USB_VENDOR_ID_APPLE)
return false;
return product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC;
}
static int magicmouse_fetch_battery(struct hid_device *hdev)
{
#ifdef CONFIG_HID_BATTERY_STRENGTH
struct hid_report_enum *report_enum;
struct hid_report *report;
if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE ||
(hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC &&
hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC))
if (!hdev->battery ||
(!is_usb_magicmouse2(hdev->vendor, hdev->product) &&
!is_usb_magictrackpad2(hdev->vendor, hdev->product)))
return -1;
report_enum = &hdev->report_enum[hdev->battery_report_type];
@@ -827,7 +841,7 @@ static void magicmouse_battery_timer_tick(struct timer_list *t)
if (magicmouse_fetch_battery(hdev) == 0) {
mod_timer(&msc->battery_timer,
jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS));
jiffies + secs_to_jiffies(USB_BATTERY_TIMEOUT_SEC));
}
}
@@ -863,17 +877,17 @@ static int magicmouse_probe(struct hid_device *hdev,
return ret;
}
timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
mod_timer(&msc->battery_timer,
jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS));
magicmouse_fetch_battery(hdev);
if (is_usb_magicmouse2(id->vendor, id->product) ||
is_usb_magictrackpad2(id->vendor, id->product)) {
timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
mod_timer(&msc->battery_timer,
jiffies + secs_to_jiffies(USB_BATTERY_TIMEOUT_SEC));
magicmouse_fetch_battery(hdev);
}
if (id->vendor == USB_VENDOR_ID_APPLE &&
(id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
hdev->type != HID_TYPE_USBMOUSE)))
if (is_usb_magicmouse2(id->vendor, id->product) ||
(is_usb_magictrackpad2(id->vendor, id->product) &&
hdev->type != HID_TYPE_USBMOUSE))
return 0;
if (!msc->input) {
@@ -936,7 +950,10 @@ static int magicmouse_probe(struct hid_device *hdev,
return 0;
err_stop_hw:
timer_delete_sync(&msc->battery_timer);
if (is_usb_magicmouse2(id->vendor, id->product) ||
is_usb_magictrackpad2(id->vendor, id->product))
timer_delete_sync(&msc->battery_timer);
hid_hw_stop(hdev);
return ret;
}
@@ -947,7 +964,9 @@ static void magicmouse_remove(struct hid_device *hdev)
if (msc) {
cancel_delayed_work_sync(&msc->work);
timer_delete_sync(&msc->battery_timer);
if (is_usb_magicmouse2(hdev->vendor, hdev->product) ||
is_usb_magictrackpad2(hdev->vendor, hdev->product))
timer_delete_sync(&msc->battery_timer);
}
hid_hw_stop(hdev);
@@ -964,11 +983,8 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
* 0x05, 0x01, // Usage Page (Generic Desktop) 0
* 0x09, 0x02, // Usage (Mouse) 2
*/
if (hdev->vendor == USB_VENDOR_ID_APPLE &&
(hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
if ((is_usb_magicmouse2(hdev->vendor, hdev->product) ||
is_usb_magictrackpad2(hdev->vendor, hdev->product)) &&
*rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
hid_info(hdev,
"fixing up magicmouse battery report descriptor\n");
+100 -8
View File
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/gpio/driver.h>
#include <linux/iio/iio.h>
#include <linux/minmax.h>
#include "hid-ids.h"
/* Commands codes in a raw output report */
@@ -55,6 +56,27 @@ enum {
MCP2221_ALT_F_NOT_GPIOD = 0xEF,
};
/* MCP SRAM read offsets cmd: MCP2221_GET_SRAM_SETTINGS */
enum {
MCP2221_SRAM_RD_GP0 = 22,
MCP2221_SRAM_RD_GP1 = 23,
MCP2221_SRAM_RD_GP2 = 24,
MCP2221_SRAM_RD_GP3 = 25,
};
/* MCP SRAM write offsets cmd: MCP2221_SET_SRAM_SETTINGS */
enum {
MCP2221_SRAM_WR_GP_ENA_ALTER = 7,
MCP2221_SRAM_WR_GP0 = 8,
MCP2221_SRAM_WR_GP1 = 9,
MCP2221_SRAM_WR_GP2 = 10,
MCP2221_SRAM_WR_GP3 = 11,
};
#define MCP2221_SRAM_GP_DESIGN_MASK 0x07
#define MCP2221_SRAM_GP_DIRECTION_MASK 0x08
#define MCP2221_SRAM_GP_VALUE_MASK 0x10
/* MCP GPIO direction encoding */
enum {
MCP2221_DIR_OUT = 0x00,
@@ -241,10 +263,7 @@ static int mcp_i2c_write(struct mcp2221 *mcp,
idx = 0;
sent = 0;
if (msg->len < 60)
len = msg->len;
else
len = 60;
len = min(msg->len, 60);
do {
mcp->txbuf[0] = type;
@@ -271,10 +290,7 @@ static int mcp_i2c_write(struct mcp2221 *mcp,
break;
idx = idx + len;
if ((msg->len - sent) < 60)
len = msg->len - sent;
else
len = 60;
len = min(msg->len - sent, 60);
/*
* Testing shows delay is needed between successive writes
@@ -607,6 +623,80 @@ static const struct i2c_algorithm mcp_i2c_algo = {
};
#if IS_REACHABLE(CONFIG_GPIOLIB)
static int mcp_gpio_read_sram(struct mcp2221 *mcp)
{
int ret;
memset(mcp->txbuf, 0, 64);
mcp->txbuf[0] = MCP2221_GET_SRAM_SETTINGS;
mutex_lock(&mcp->lock);
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 64);
mutex_unlock(&mcp->lock);
return ret;
}
/*
* If CONFIG_IIO is not enabled, check for the gpio pins
* if they are in gpio mode. For the ones which are not
* in gpio mode, set them into gpio mode.
*/
static int mcp2221_check_gpio_pinfunc(struct mcp2221 *mcp)
{
int i;
int needgpiofix = 0;
int ret;
if (IS_ENABLED(CONFIG_IIO))
return 0;
ret = mcp_gpio_read_sram(mcp);
if (ret)
return ret;
for (i = 0; i < MCP_NGPIO; i++) {
if ((mcp->mode[i] & MCP2221_SRAM_GP_DESIGN_MASK) != 0x0) {
dev_warn(&mcp->hdev->dev,
"GPIO %d not in gpio mode\n", i);
needgpiofix = 1;
}
}
if (!needgpiofix)
return 0;
/*
* Set all bytes to 0, so Bit 7 is not set. The chip
* only changes content of a register when bit 7 is set.
*/
memset(mcp->txbuf, 0, 64);
mcp->txbuf[0] = MCP2221_SET_SRAM_SETTINGS;
/*
* Set bit 7 in MCP2221_SRAM_WR_GP_ENA_ALTER to enable
* loading of a new set of gpio settings to GP SRAM
*/
mcp->txbuf[MCP2221_SRAM_WR_GP_ENA_ALTER] = 0x80;
for (i = 0; i < MCP_NGPIO; i++) {
if ((mcp->mode[i] & MCP2221_SRAM_GP_DESIGN_MASK) == 0x0) {
/* write current GPIO mode */
mcp->txbuf[MCP2221_SRAM_WR_GP0 + i] = mcp->mode[i];
} else {
/* pin is not in gpio mode, set it to input mode */
mcp->txbuf[MCP2221_SRAM_WR_GP0 + i] = 0x08;
dev_warn(&mcp->hdev->dev,
"Set GPIO mode for gpio pin %d!\n", i);
}
}
mutex_lock(&mcp->lock);
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 64);
mutex_unlock(&mcp->lock);
return ret;
}
static int mcp_gpio_get(struct gpio_chip *gc,
unsigned int offset)
{
@@ -1218,6 +1308,8 @@ static int mcp2221_probe(struct hid_device *hdev,
ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp);
if (ret)
return ret;
mcp2221_check_gpio_pinfunc(mcp);
#endif
#if IS_REACHABLE(CONFIG_IIO)
+57 -5
View File
@@ -73,6 +73,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20)
#define MT_QUIRK_DISABLE_WAKEUP BIT(21)
#define MT_QUIRK_ORIENTATION_INVERT BIT(22)
#define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -220,6 +221,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
#define MT_CLS_GOOGLE 0x0111
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
#define MT_CLS_SMART_TECH 0x0113
#define MT_CLS_APPLE_TOUCHBAR 0x0114
#define MT_CLS_SIS 0x0457
#define MT_DEFAULT_MAXCONTACT 10
@@ -405,6 +407,12 @@ static const struct mt_class mt_classes[] = {
MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_SEPARATE_APP_REPORT,
},
{ .name = MT_CLS_APPLE_TOUCHBAR,
.quirks = MT_QUIRK_HOVERING |
MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE |
MT_QUIRK_APPLE_TOUCHBAR,
.maxcontacts = 11,
},
{ .name = MT_CLS_SIS,
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
MT_QUIRK_ALWAYS_VALID |
@@ -625,6 +633,7 @@ static struct mt_application *mt_find_application(struct mt_device *td,
static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
struct hid_report *report)
{
struct mt_class *cls = &td->mtclass;
struct mt_report_data *rdata;
struct hid_field *field;
int r, n;
@@ -649,7 +658,11 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) {
for (n = 0; n < field->report_count; n++) {
if (field->usage[n].hid == HID_DG_CONTACTID) {
unsigned int hid = field->usage[n].hid;
if (hid == HID_DG_CONTACTID ||
(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR &&
hid == HID_DG_TRANSDUCER_INDEX)) {
rdata->is_mt_collection = true;
break;
}
@@ -821,12 +834,31 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
MT_STORE_FIELD(confidence_state);
return 1;
case HID_DG_TOUCH:
/*
* Legacy devices use TIPSWITCH and not TOUCH.
* One special case here is of the Apple Touch Bars.
* In these devices, the tip state is contained in
* fields with the HID_DG_TOUCH usage.
* Let's just ignore this field for other devices.
*/
if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
return -1;
fallthrough;
case HID_DG_TIPSWITCH:
if (field->application != HID_GD_SYSTEM_MULTIAXIS)
input_set_capability(hi->input,
EV_KEY, BTN_TOUCH);
MT_STORE_FIELD(tip_state);
return 1;
case HID_DG_TRANSDUCER_INDEX:
/*
* Contact ID in case of Apple Touch Bars is contained
* in fields with HID_DG_TRANSDUCER_INDEX usage.
*/
if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
return 0;
fallthrough;
case HID_DG_CONTACTID:
MT_STORE_FIELD(contactid);
app->touches_by_report++;
@@ -883,10 +915,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case HID_DG_CONTACTMAX:
/* contact max are global to the report */
return -1;
case HID_DG_TOUCH:
/* Legacy devices use TIPSWITCH and not TOUCH.
* Let's just ignore this field. */
return -1;
}
/* let hid-input decide for the others */
return 0;
@@ -1314,6 +1342,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
struct input_dev *input = hi->input;
int ret;
/*
* HID_DG_CONTACTMAX field is not present on Apple Touch Bars,
* but the maximum contact count is greater than the default.
*/
if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && cls->maxcontacts)
td->maxcontacts = cls->maxcontacts;
if (!td->maxcontacts)
td->maxcontacts = MT_DEFAULT_MAXCONTACT;
@@ -1321,6 +1356,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
if (td->serial_maybe)
mt_post_parse_default_settings(td, app);
/*
* The application for Apple Touch Bars is HID_DG_TOUCHPAD,
* but these devices are direct.
*/
if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
app->mt_flags |= INPUT_MT_DIRECT;
if (cls->is_indirect)
app->mt_flags |= INPUT_MT_POINTER;
@@ -1823,6 +1865,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret != 0)
return ret;
if (mtclass->name == MT_CLS_APPLE_TOUCHBAR &&
!hid_find_field(hdev, HID_INPUT_REPORT,
HID_DG_TOUCHPAD, HID_DG_TRANSDUCER_INDEX))
return -ENODEV;
if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)
mt_fix_const_fields(hdev, HID_DG_CONTACTID);
@@ -2320,6 +2367,11 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
USB_DEVICE_ID_XIROKU_CSR2) },
/* Apple Touch Bar */
{ .driver_data = MT_CLS_APPLE_TOUCHBAR,
HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
/* Google MT devices */
{ .driver_data = MT_CLS_GOOGLE,
HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,
+1 -8
View File
@@ -314,6 +314,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
@@ -973,14 +974,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ }
+62 -4
View File
@@ -62,6 +62,30 @@ static const __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
return rdesc;
}
/* Buttons considered valid tablet pad inputs. */
static const unsigned int uclogic_extra_input_mapping[] = {
BTN_0,
BTN_1,
BTN_2,
BTN_3,
BTN_4,
BTN_5,
BTN_6,
BTN_7,
BTN_8,
BTN_RIGHT,
BTN_MIDDLE,
BTN_SIDE,
BTN_EXTRA,
BTN_FORWARD,
BTN_BACK,
BTN_B,
BTN_A,
BTN_BASE,
BTN_BASE2,
BTN_X
};
static int uclogic_input_mapping(struct hid_device *hdev,
struct hid_input *hi,
struct hid_field *field,
@@ -72,9 +96,27 @@ static int uclogic_input_mapping(struct hid_device *hdev,
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
struct uclogic_params *params = &drvdata->params;
/* Discard invalid pen usages */
if (params->pen.usage_invalid && (field->application == HID_DG_PEN))
return -1;
if (field->application == HID_GD_KEYPAD) {
/*
* Remap input buttons to sensible ones that are not invalid.
* This only affects previous behavior for devices with more than ten or so buttons.
*/
const int key = (usage->hid & HID_USAGE) - 1;
if (key < ARRAY_SIZE(uclogic_extra_input_mapping)) {
hid_map_usage(hi,
usage,
bit,
max,
EV_KEY,
uclogic_extra_input_mapping[key]);
return 1;
}
} else if (field->application == HID_DG_PEN) {
/* Discard invalid pen usages */
if (params->pen.usage_invalid)
return -1;
}
/* Let hid-core decide what to do */
return 0;
@@ -407,8 +449,22 @@ static int uclogic_raw_event_frame(
/* If need to, and can, transform the bitmap dial reports */
if (frame->bitmap_dial_byte > 0 && frame->bitmap_dial_byte < size) {
if (data[frame->bitmap_dial_byte] == 2)
switch (data[frame->bitmap_dial_byte]) {
case 2:
data[frame->bitmap_dial_byte] = -1;
break;
/* Everything below here is for tablets that shove multiple dials into 1 byte */
case 16:
data[frame->bitmap_dial_byte] = 0;
data[frame->bitmap_second_dial_destination_byte] = 1;
break;
case 32:
data[frame->bitmap_dial_byte] = 0;
data[frame->bitmap_second_dial_destination_byte] = -1;
break;
}
}
return 0;
@@ -546,6 +602,8 @@ static const struct hid_device_id uclogic_devices[] = {
.driver_data = UCLOGIC_MOUSE_FRAME_QUIRK | UCLOGIC_BATTERY_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO) },
{ }
};
MODULE_DEVICE_TABLE(hid, uclogic_devices);
+133 -1
View File
@@ -103,6 +103,8 @@ static void uclogic_params_frame_hid_dbg(
frame->touch_flip_at);
hid_dbg(hdev, "\t\t.bitmap_dial_byte = %u\n",
frame->bitmap_dial_byte);
hid_dbg(hdev, "\t\t.bitmap_second_dial_destination_byte = %u\n",
frame->bitmap_second_dial_destination_byte);
}
/**
@@ -1341,7 +1343,7 @@ static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev,
struct uclogic_params *p)
{
struct uclogic_raw_event_hook *event_hook;
__u8 reconnect_event[] = {
static const __u8 reconnect_event[] = {
/* Event received on wireless tablet reconnection */
0x02, 0xF8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
@@ -1529,6 +1531,126 @@ cleanup:
return rc;
}
/*
* uclogic_params_init_ugee_xppen_pro_22r() - Initializes a UGEE XP-Pen Pro 22R tablet device.
*
* @hdev: The HID device of the tablet interface to initialize and get
* parameters from. Cannot be NULL.
* @params: Parameters to fill in (to be cleaned with
* uclogic_params_cleanup()). Not modified in case of error.
* Cannot be NULL.
*
* Returns:
* Zero, if successful. A negative errno code on error.
*/
static int uclogic_params_init_ugee_xppen_pro_22r(struct uclogic_params *params,
struct hid_device *hdev,
const u8 rdesc_frame_arr[],
const size_t rdesc_frame_size)
{
int rc = 0;
struct usb_interface *iface;
__u8 bInterfaceNumber;
const int str_desc_len = 12;
u8 *str_desc = NULL;
__u8 *rdesc_pen = NULL;
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
enum uclogic_params_frame_type frame_type;
/* The resulting parameters (noop) */
struct uclogic_params p = {0, };
if (!hdev || !params) {
rc = -EINVAL;
goto cleanup;
}
iface = to_usb_interface(hdev->dev.parent);
bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
/* Ignore non-pen interfaces */
if (bInterfaceNumber != 2) {
rc = -EINVAL;
uclogic_params_init_invalid(&p);
goto cleanup;
}
/*
* Initialize the interface by sending magic data.
* This magic data is the same as other UGEE v2 tablets.
*/
rc = uclogic_probe_interface(hdev,
uclogic_ugee_v2_probe_arr,
uclogic_ugee_v2_probe_size,
uclogic_ugee_v2_probe_endpoint);
if (rc) {
uclogic_params_init_invalid(&p);
goto cleanup;
}
/**
* Read the string descriptor containing pen and frame parameters.
* These are slightly different than typical UGEE v2 devices.
*/
rc = uclogic_params_get_str_desc(&str_desc, hdev, 100, str_desc_len);
if (rc != str_desc_len) {
rc = (rc < 0) ? rc : -EINVAL;
hid_err(hdev, "failed retrieving pen and frame parameters: %d\n", rc);
uclogic_params_init_invalid(&p);
goto cleanup;
}
rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
desc_params,
ARRAY_SIZE(desc_params),
&frame_type);
if (rc)
goto cleanup;
// str_desc doesn't report the correct amount of buttons, so manually fix it
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 20;
kfree(str_desc);
str_desc = NULL;
/* Initialize the pen interface */
rdesc_pen = uclogic_rdesc_template_apply(
uclogic_rdesc_ugee_v2_pen_template_arr,
uclogic_rdesc_ugee_v2_pen_template_size,
desc_params, ARRAY_SIZE(desc_params));
if (!rdesc_pen) {
rc = -ENOMEM;
goto cleanup;
}
p.pen.desc_ptr = rdesc_pen;
p.pen.desc_size = uclogic_rdesc_ugee_v2_pen_template_size;
p.pen.id = 0x02;
p.pen.subreport_list[0].value = 0xf0;
p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
/* Initialize the frame interface */
rc = uclogic_params_frame_init_with_desc(
&p.frame_list[0],
rdesc_frame_arr,
rdesc_frame_size,
UCLOGIC_RDESC_V1_FRAME_ID);
if (rc < 0) {
hid_err(hdev, "initializing frame params failed: %d\n", rc);
goto cleanup;
}
p.frame_list[0].bitmap_dial_byte = 7;
p.frame_list[0].bitmap_second_dial_destination_byte = 8;
/* Output parameters */
memcpy(params, &p, sizeof(*params));
memset(&p, 0, sizeof(p));
cleanup:
kfree(str_desc);
uclogic_params_cleanup(&p);
return rc;
}
/**
* uclogic_params_init() - initialize a tablet interface and discover its
* parameters.
@@ -1845,6 +1967,16 @@ int uclogic_params_init(struct uclogic_params *params,
uclogic_params_init_invalid(&p);
}
break;
case VID_PID(USB_VENDOR_ID_UGEE,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO):
rc = uclogic_params_init_ugee_xppen_pro_22r(&p,
hdev,
uclogic_rdesc_xppen_artist_22r_pro_frame_arr,
uclogic_rdesc_xppen_artist_22r_pro_frame_size);
if (rc != 0)
goto cleanup;
break;
}
+5
View File
@@ -175,6 +175,11 @@ struct uclogic_params_frame {
* counterclockwise, as opposed to the normal 1 and -1.
*/
unsigned int bitmap_dial_byte;
/*
* Destination offset for the second bitmap dial byte, if the tablet
* supports a second dial at all.
*/
unsigned int bitmap_second_dial_destination_byte;
};
/*
+44
View File
@@ -1193,6 +1193,50 @@ const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
const size_t uclogic_rdesc_xppen_deco01_frame_size =
sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
/* Fixed report descriptor for XP-Pen Arist 22R Pro frame */
const __u8 uclogic_rdesc_xppen_artist_22r_pro_frame_arr[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x07, /* Usage (Keypad), */
0xA1, 0x01, /* Collection (Application), */
0x85, UCLOGIC_RDESC_V1_FRAME_ID,
/* Report ID (Virtual report), */
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x39, /* Usage (Tablet Function Keys), */
0xA0, /* Collection (Physical), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x95, 0x08, /* Report Count (8), */
0x81, 0x01, /* Input (Constant), */
0x05, 0x09, /* Usage Page (Button), */
0x19, 0x01, /* Usage Minimum (01h), */
0x29, 0x14, /* Usage Maximum (14h), */
0x95, 0x14, /* Report Count (20), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x14, /* Report Count (20), */
0x81, 0x01, /* Input (Constant), */
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x38, /* Usage (Wheel), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x01, /* Report Count (1), */
0x15, 0xFF, /* Logical Minimum (-1), */
0x25, 0x08, /* Logical Maximum (8), */
0x81, 0x06, /* Input (Variable, Relative), */
0x05, 0x0C, /* Usage Page (Consumer Devices), */
0x0A, 0x38, 0x02, /* Usage (AC PAN), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x06, /* Input (Variable, Relative), */
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x02, /* Input (Variable), */
0xC0, /* End Collection */
0xC0, /* End Collection */
};
const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size =
sizeof(uclogic_rdesc_xppen_artist_22r_pro_frame_arr);
/**
* uclogic_rdesc_template_apply() - apply report descriptor parameters to a
* report descriptor template, creating a report descriptor. Copies the
+4
View File
@@ -210,4 +210,8 @@ extern const size_t uclogic_rdesc_ugee_g5_frame_size;
/* Least-significant bit of Ugee G5 frame rotary encoder state */
#define UCLOGIC_RDESC_UGEE_G5_FRAME_RE_LSB 38
/* Fixed report descriptor for XP-Pen Arist 22R Pro frame */
extern const __u8 uclogic_rdesc_xppen_artist_22r_pro_frame_arr[];
extern const size_t uclogic_rdesc_xppen_artist_22r_pro_frame_size;
#endif /* _HID_UCLOGIC_RDESC_H */

Some files were not shown because too many files have changed in this diff Show More