Skip to content

Commit 57ac86c

Browse files
bentissJiri Kosina
authored andcommitted
HID: logitech-hidpp: add support of the first Logitech Wireless Touchpad
This touchpad differs from the T650 in several ways: - the resolution is not correctly returned by the device - it presents physical buttons, so the button flag in the raw touch report is not filled. Signed-off-by: Benjamin Tissoires <[email protected]> Tested-by: Andrew de los Reyes <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 586bdc4 commit 57ac86c

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

drivers/hid/hid-logitech-hidpp.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ MODULE_AUTHOR("Nestor Lopez Casado <[email protected]>");
3838

3939
/* bits 1..20 are reserved for classes */
4040
#define HIDPP_QUIRK_DELAYED_INIT BIT(21)
41+
#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22)
4142

4243
/*
4344
* There are two hidpp protocols in use, the first version hidpp10 is known
@@ -596,6 +597,8 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
596597
/* Touchpad HID++ devices */
597598
/* -------------------------------------------------------------------------- */
598599

600+
#define WTP_MANUAL_RESOLUTION 39
601+
599602
struct wtp_data {
600603
struct input_dev *input;
601604
u16 x_size, y_size;
@@ -634,7 +637,10 @@ static void wtp_populate_input(struct hidpp_device *hidpp,
634637

635638
input_set_capability(input_dev, EV_KEY, BTN_LEFT);
636639

637-
__set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
640+
if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)
641+
input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
642+
else
643+
__set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
638644

639645
input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
640646
INPUT_MT_DROP_UNUSED);
@@ -676,7 +682,8 @@ static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
676682
for (i = 0; i < 2; i++)
677683
wtp_touch_event(wd, &(raw->fingers[i]));
678684

679-
if (raw->end_of_frame)
685+
if (raw->end_of_frame &&
686+
!(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
680687
input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
681688

682689
if (raw->end_of_frame || raw->finger_count <= 2) {
@@ -736,9 +743,17 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
736743

737744
switch (data[0]) {
738745
case 0x02:
739-
if (size < 21)
740-
return 1;
741-
return wtp_mouse_raw_xy_event(hidpp, &data[7]);
746+
if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
747+
input_event(wd->input, EV_KEY, BTN_LEFT,
748+
!!(data[1] & 0x01));
749+
input_event(wd->input, EV_KEY, BTN_RIGHT,
750+
!!(data[1] & 0x02));
751+
input_sync(wd->input);
752+
} else {
753+
if (size < 21)
754+
return 1;
755+
return wtp_mouse_raw_xy_event(hidpp, &data[7]);
756+
}
742757
case REPORT_ID_HIDPP_LONG:
743758
if ((report->fap.feature_index != wd->mt_feature_index) ||
744759
(report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
@@ -775,6 +790,8 @@ static int wtp_get_config(struct hidpp_device *hidpp)
775790
wd->maxcontacts = raw_info.maxcontacts;
776791
wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT;
777792
wd->resolution = raw_info.res;
793+
if (!wd->resolution)
794+
wd->resolution = WTP_MANUAL_RESOLUTION;
778795

779796
return 0;
780797
}
@@ -1130,6 +1147,11 @@ static void hidpp_remove(struct hid_device *hdev)
11301147
}
11311148

11321149
static const struct hid_device_id hidpp_devices[] = {
1150+
{ /* wireless touchpad */
1151+
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1152+
USB_VENDOR_ID_LOGITECH, 0x4011),
1153+
.driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
1154+
HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
11331155
{ /* wireless touchpad T650 */
11341156
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
11351157
USB_VENDOR_ID_LOGITECH, 0x4101),

0 commit comments

Comments
 (0)