Loading drivers/hid/wacom_wac.c +81 −6 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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: 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: Loading Loading @@ -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; } Loading Loading @@ -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); } Loading Loading @@ -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; } } Loading Loading @@ -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; } Loading drivers/hid/wacom_wac.h +5 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; }; Loading Loading @@ -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 Loading
drivers/hid/wacom_wac.c +81 −6 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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: 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: Loading Loading @@ -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; } Loading Loading @@ -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); } Loading Loading @@ -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; } } Loading Loading @@ -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; } Loading
drivers/hid/wacom_wac.h +5 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; }; Loading Loading @@ -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