Skip to content

Commit 1a811ed

Browse files
author
Benjamin Tissoires
committed
Merge branch 'for-6.12/wacom' into for-linus
Various Wacom fixes (Jason Gerecke): - Support for high-resolution wheel scrolling - Support touchrings with relative motion - Support devices with two touchrings - Support sequence numbers smaller than 16-bit
2 parents 8357632 + 84aecf2 commit 1a811ed

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

drivers/hid/wacom_wac.c

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,11 +1906,12 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
19061906
if ((code == ABS_X || code == ABS_Y) && !resolution) {
19071907
resolution = WACOM_INTUOS_RES;
19081908
hid_warn(input,
1909-
"Wacom usage (%d) missing resolution \n",
1910-
code);
1909+
"Using default resolution for axis type 0x%x code 0x%x\n",
1910+
type, code);
19111911
}
19121912
input_abs_set_res(input, code, resolution);
19131913
break;
1914+
case EV_REL:
19141915
case EV_KEY:
19151916
case EV_MSC:
19161917
case EV_SW:
@@ -2047,7 +2048,23 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
20472048
features->device_type |= WACOM_DEVICETYPE_PAD;
20482049
break;
20492050
case WACOM_HID_WD_TOUCHRING:
2050-
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
2051+
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
2052+
wacom_wac->relring_count++;
2053+
if (wacom_wac->relring_count == 1) {
2054+
wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);
2055+
set_bit(REL_WHEEL, input->relbit);
2056+
}
2057+
else if (wacom_wac->relring_count == 2) {
2058+
wacom_map_usage(input, usage, field, EV_REL, REL_HWHEEL_HI_RES, 0);
2059+
set_bit(REL_HWHEEL, input->relbit);
2060+
}
2061+
} else {
2062+
wacom_wac->absring_count++;
2063+
if (wacom_wac->absring_count == 1)
2064+
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
2065+
else if (wacom_wac->absring_count == 2)
2066+
wacom_map_usage(input, usage, field, EV_ABS, ABS_THROTTLE, 0);
2067+
}
20512068
features->device_type |= WACOM_DEVICETYPE_PAD;
20522069
break;
20532070
case WACOM_HID_WD_TOUCHRINGSTATUS:
@@ -2112,7 +2129,10 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21122129
return;
21132130

21142131
if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {
2115-
if (usage->hid != WACOM_HID_WD_TOUCHRING)
2132+
bool is_abs_touchring = usage->hid == WACOM_HID_WD_TOUCHRING &&
2133+
!(field->flags & HID_MAIN_ITEM_RELATIVE);
2134+
2135+
if (!is_abs_touchring)
21162136
wacom_wac->hid_data.inrange_state |= value;
21172137
}
21182138

@@ -2165,6 +2185,52 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21652185
hdev->product == 0x3AA)
21662186
value = wacom_offset_rotation(input, usage, value, 1, 2);
21672187
}
2188+
else if (field->flags & HID_MAIN_ITEM_RELATIVE) {
2189+
int hires_value = value * 120 / usage->resolution_multiplier;
2190+
int *ring_value;
2191+
int lowres_code;
2192+
2193+
if (usage->code == REL_WHEEL_HI_RES) {
2194+
/* We must invert the sign for vertical
2195+
* relative scrolling. Clockwise
2196+
* rotation produces positive values
2197+
* from HW, but userspace treats
2198+
* positive REL_WHEEL as a scroll *up*!
2199+
*/
2200+
hires_value = -hires_value;
2201+
ring_value = &wacom_wac->hid_data.ring_value;
2202+
lowres_code = REL_WHEEL;
2203+
}
2204+
else if (usage->code == REL_HWHEEL_HI_RES) {
2205+
/* No need to invert the sign for
2206+
* horizontal relative scrolling.
2207+
* Clockwise rotation produces positive
2208+
* values from HW and userspace treats
2209+
* positive REL_HWHEEL as a scroll
2210+
* right.
2211+
*/
2212+
ring_value = &wacom_wac->hid_data.ring2_value;
2213+
lowres_code = REL_HWHEEL;
2214+
}
2215+
else {
2216+
hid_err(wacom->hdev, "unrecognized relative wheel with code %d\n",
2217+
usage->code);
2218+
break;
2219+
}
2220+
2221+
value = hires_value;
2222+
*ring_value += hires_value;
2223+
2224+
/* Emulate a legacy wheel click for every 120
2225+
* units of hi-res travel.
2226+
*/
2227+
if (*ring_value >= 120 || *ring_value <= -120) {
2228+
int clicks = *ring_value / 120;
2229+
2230+
input_event(input, usage->type, lowres_code, clicks);
2231+
*ring_value -= clicks * 120;
2232+
}
2233+
}
21682234
else {
21692235
value = wacom_offset_rotation(input, usage, value, 1, 4);
21702236
}
@@ -2322,6 +2388,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
23222388
wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);
23232389
features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;
23242390
break;
2391+
case WACOM_HID_WD_SEQUENCENUMBER:
2392+
wacom_wac->hid_data.sequence_number = -1;
2393+
break;
23252394
}
23262395
}
23272396

@@ -2446,9 +2515,15 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
24462515
wacom_wac->hid_data.barrelswitch3 = value;
24472516
return;
24482517
case WACOM_HID_WD_SEQUENCENUMBER:
2449-
if (wacom_wac->hid_data.sequence_number != value)
2450-
hid_warn(hdev, "Dropped %hu packets", (unsigned short)(value - wacom_wac->hid_data.sequence_number));
2518+
if (wacom_wac->hid_data.sequence_number != value &&
2519+
wacom_wac->hid_data.sequence_number >= 0) {
2520+
int sequence_size = field->logical_maximum - field->logical_minimum + 1;
2521+
int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size;
2522+
hid_warn(hdev, "Dropped %d packets", drop_count);
2523+
}
24512524
wacom_wac->hid_data.sequence_number = value + 1;
2525+
if (wacom_wac->hid_data.sequence_number > field->logical_maximum)
2526+
wacom_wac->hid_data.sequence_number = field->logical_minimum;
24522527
return;
24532528
}
24542529

drivers/hid/wacom_wac.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ struct hid_data {
312312
int width;
313313
int height;
314314
int id;
315+
int ring_value;
316+
int ring2_value;
315317
int cc_report;
316318
int cc_index;
317319
int cc_value_index;
@@ -324,7 +326,7 @@ struct hid_data {
324326
int bat_connected;
325327
int ps_connected;
326328
bool pad_input_event_flag;
327-
unsigned short sequence_number;
329+
int sequence_number;
328330
ktime_t time_delayed;
329331
};
330332

@@ -355,6 +357,8 @@ struct wacom_wac {
355357
int num_contacts_left;
356358
u8 bt_features;
357359
u8 bt_high_speed;
360+
u8 absring_count;
361+
u8 relring_count;
358362
int mode_report;
359363
int mode_value;
360364
struct hid_data hid_data;

0 commit comments

Comments
 (0)