mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 06:53:04 +00:00
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
This commit is contained in:
commit
1a811edf4f
|
@ -1906,11 +1906,12 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
|
|||
if ((code == ABS_X || code == ABS_Y) && !resolution) {
|
||||
resolution = WACOM_INTUOS_RES;
|
||||
hid_warn(input,
|
||||
"Wacom usage (%d) missing resolution \n",
|
||||
code);
|
||||
"Using default resolution for axis type 0x%x code 0x%x\n",
|
||||
type, code);
|
||||
}
|
||||
input_abs_set_res(input, code, resolution);
|
||||
break;
|
||||
case EV_REL:
|
||||
case EV_KEY:
|
||||
case EV_MSC:
|
||||
case EV_SW:
|
||||
|
@ -2047,7 +2048,23 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
|
|||
features->device_type |= WACOM_DEVICETYPE_PAD;
|
||||
break;
|
||||
case WACOM_HID_WD_TOUCHRING:
|
||||
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
|
||||
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
|
||||
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_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;
|
||||
case WACOM_HID_WD_TOUCHRINGSTATUS:
|
||||
|
@ -2112,7 +2129,10 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
|
|||
return;
|
||||
|
||||
if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {
|
||||
if (usage->hid != WACOM_HID_WD_TOUCHRING)
|
||||
bool is_abs_touchring = usage->hid == WACOM_HID_WD_TOUCHRING &&
|
||||
!(field->flags & HID_MAIN_ITEM_RELATIVE);
|
||||
|
||||
if (!is_abs_touchring)
|
||||
wacom_wac->hid_data.inrange_state |= value;
|
||||
}
|
||||
|
||||
|
@ -2165,6 +2185,52 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
|
|||
hdev->product == 0x3AA)
|
||||
value = wacom_offset_rotation(input, usage, value, 1, 2);
|
||||
}
|
||||
else if (field->flags & HID_MAIN_ITEM_RELATIVE) {
|
||||
int hires_value = value * 120 / usage->resolution_multiplier;
|
||||
int *ring_value;
|
||||
int lowres_code;
|
||||
|
||||
if (usage->code == REL_WHEEL_HI_RES) {
|
||||
/* We must invert the sign for vertical
|
||||
* relative scrolling. Clockwise
|
||||
* rotation produces positive values
|
||||
* from HW, but userspace treats
|
||||
* positive REL_WHEEL as a scroll *up*!
|
||||
*/
|
||||
hires_value = -hires_value;
|
||||
ring_value = &wacom_wac->hid_data.ring_value;
|
||||
lowres_code = REL_WHEEL;
|
||||
}
|
||||
else if (usage->code == REL_HWHEEL_HI_RES) {
|
||||
/* No need to invert the sign for
|
||||
* horizontal relative scrolling.
|
||||
* Clockwise rotation produces positive
|
||||
* values from HW and userspace treats
|
||||
* positive REL_HWHEEL as a scroll
|
||||
* right.
|
||||
*/
|
||||
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;
|
||||
|
||||
/* Emulate a legacy wheel click for every 120
|
||||
* units of hi-res travel.
|
||||
*/
|
||||
if (*ring_value >= 120 || *ring_value <= -120) {
|
||||
int clicks = *ring_value / 120;
|
||||
|
||||
input_event(input, usage->type, lowres_code, clicks);
|
||||
*ring_value -= clicks * 120;
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = wacom_offset_rotation(input, usage, value, 1, 4);
|
||||
}
|
||||
|
@ -2322,6 +2388,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
|
|||
wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);
|
||||
features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;
|
||||
break;
|
||||
case WACOM_HID_WD_SEQUENCENUMBER:
|
||||
wacom_wac->hid_data.sequence_number = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2446,9 +2515,15 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
|||
wacom_wac->hid_data.barrelswitch3 = value;
|
||||
return;
|
||||
case WACOM_HID_WD_SEQUENCENUMBER:
|
||||
if (wacom_wac->hid_data.sequence_number != value)
|
||||
hid_warn(hdev, "Dropped %hu packets", (unsigned short)(value - wacom_wac->hid_data.sequence_number));
|
||||
if (wacom_wac->hid_data.sequence_number != value &&
|
||||
wacom_wac->hid_data.sequence_number >= 0) {
|
||||
int sequence_size = field->logical_maximum - field->logical_minimum + 1;
|
||||
int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size;
|
||||
hid_warn(hdev, "Dropped %d packets", drop_count);
|
||||
}
|
||||
wacom_wac->hid_data.sequence_number = value + 1;
|
||||
if (wacom_wac->hid_data.sequence_number > field->logical_maximum)
|
||||
wacom_wac->hid_data.sequence_number = field->logical_minimum;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -312,6 +312,8 @@ struct hid_data {
|
|||
int width;
|
||||
int height;
|
||||
int id;
|
||||
int ring_value;
|
||||
int ring2_value;
|
||||
int cc_report;
|
||||
int cc_index;
|
||||
int cc_value_index;
|
||||
|
@ -324,7 +326,7 @@ struct hid_data {
|
|||
int bat_connected;
|
||||
int ps_connected;
|
||||
bool pad_input_event_flag;
|
||||
unsigned short sequence_number;
|
||||
int sequence_number;
|
||||
ktime_t time_delayed;
|
||||
};
|
||||
|
||||
|
@ -355,6 +357,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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user