Skip to content

Commit

Permalink
HID: wacom: Support devices with two touchrings
Browse files Browse the repository at this point in the history
If a device has more than one touchring, we want to be sure that userspace
is able to distinguish them. Following previous standards, the first
absolute ring will be reported as ABS_WHEEL and the second as ABS_THROTTLE.
Relative rings will use REL_WHEEL_HI_RES / REL_WHEEL for the first and
REL_HWHEEL_HI_RES / REL_HWHEEL for the second.

Signed-off-by: Jason Gerecke <[email protected]>
  • Loading branch information
jigpu committed May 2, 2024
1 parent ad08511 commit 6383dd4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
36 changes: 31 additions & 5 deletions 4.5/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -2122,11 +2122,22 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
break;
case WACOM_HID_WD_TOUCHRING:
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);
set_bit(REL_WHEEL, input->relbit);
wacom_wac->relring_count++;
if (wacom_wac->relring_count == 1) {
wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);
set_bit(REL_WHEEL, input->relbit);
}
else if (wacom_wac->relring_count == 2) {
wacom_map_usage(input, usage, field, EV_REL, REL_HWHEEL_HI_RES, 0);
set_bit(REL_HWHEEL, input->relbit);
}
}
else {
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
wacom_wac->absring_count++;
if (wacom_wac->absring_count == 1)
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
else if (wacom_wac->absring_count == 2)
wacom_map_usage(input, usage, field, EV_ABS, ABS_THROTTLE, 0);
}
features->device_type |= WACOM_DEVICETYPE_PAD;
break;
Expand Down Expand Up @@ -2248,14 +2259,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
else if (field->flags & HID_MAIN_ITEM_RELATIVE) {
// Emulate a legacy wheel click for every 120 units high-res travel
int hires_value = value * 120 / usage->resolution_multiplier;
int *ring_value = &wacom_wac->hid_data.ring_value;
int *ring_value;
int lowres_code;

if (usage->code == REL_WHEEL_HI_RES) {
ring_value = &wacom_wac->hid_data.ring_value;
lowres_code = REL_WHEEL;
}
else if (usage->code == REL_HWHEEL_HI_RES) {
ring_value = &wacom_wac->hid_data.ring2_value;
lowres_code = REL_HWHEEL;
}
else {
hid_err(wacom->hdev, "unrecognized relative wheel with code %d\n",
usage->code);
break;
}

value = hires_value;
*ring_value += hires_value;

if (*ring_value >= 120 || *ring_value <= -120) {
int clicks = *ring_value / 120;
input_event(input, usage->type, REL_WHEEL, clicks);
input_event(input, usage->type, lowres_code, clicks);
*ring_value -= clicks * 120;
}
}
Expand Down
3 changes: 3 additions & 0 deletions 4.5/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ struct hid_data {
int height;
int id;
int ring_value;
int ring2_value;
int cc_report;
int cc_index;
int cc_value_index;
Expand Down Expand Up @@ -385,6 +386,8 @@ struct wacom_wac {
int num_contacts_left;
u8 bt_features;
u8 bt_high_speed;
u8 absring_count;
u8 relring_count;
int mode_report;
int mode_value;
struct hid_data hid_data;
Expand Down

0 comments on commit 6383dd4

Please sign in to comment.