diff options
| author | Andrew Duggan <aduggan@synaptics.com> | 2015-01-08 17:51:34 -0500 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2015-01-12 04:12:00 -0500 |
| commit | 79364d87af239e2029aeba3b82bd79c355b9bb86 (patch) | |
| tree | 861cfcb93fabf80e70b7f74f9ae63685bd7ad434 | |
| parent | b8aed6ea39a70a9b9b8de9df8655ac36719b4d3b (diff) | |
HID: rmi: Support touchpads with external buttons
The external buttons on HID touchpads are connected as pass through devices and
button events are not reported in the rmi registers. As a result on these
devices we need to allow the HID generic desktop button events to be processed
by hid-input. Unfortunately, there is no way to query the touchpad to determine
that it has pass through buttons so the RMI_DEVICE_HAS_PHYS_BUTTONS should be
set manually when adding the device to rmi_id[].
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | drivers/hid/hid-rmi.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 6270d2cbdb08..4bf43c82fa67 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | /* device flags */ | 36 | /* device flags */ |
| 37 | #define RMI_DEVICE BIT(0) | 37 | #define RMI_DEVICE BIT(0) |
| 38 | #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) | ||
| 38 | 39 | ||
| 39 | enum rmi_mode_type { | 40 | enum rmi_mode_type { |
| 40 | RMI_MODE_OFF = 0, | 41 | RMI_MODE_OFF = 0, |
| @@ -472,6 +473,15 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field, | |||
| 472 | if ((data->device_flags & RMI_DEVICE) && | 473 | if ((data->device_flags & RMI_DEVICE) && |
| 473 | (field->application == HID_GD_POINTER || | 474 | (field->application == HID_GD_POINTER || |
| 474 | field->application == HID_GD_MOUSE)) { | 475 | field->application == HID_GD_MOUSE)) { |
| 476 | if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) { | ||
| 477 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) | ||
| 478 | return 0; | ||
| 479 | |||
| 480 | if ((usage->hid == HID_GD_X || usage->hid == HID_GD_Y) | ||
| 481 | && !value) | ||
| 482 | return 1; | ||
| 483 | } | ||
| 484 | |||
| 475 | rmi_schedule_reset(hdev); | 485 | rmi_schedule_reset(hdev); |
| 476 | return 1; | 486 | return 1; |
| 477 | } | 487 | } |
| @@ -942,8 +952,13 @@ static int rmi_input_mapping(struct hid_device *hdev, | |||
| 942 | * we want to make HID ignore the advertised HID collection | 952 | * we want to make HID ignore the advertised HID collection |
| 943 | * for RMI deivces | 953 | * for RMI deivces |
| 944 | */ | 954 | */ |
| 945 | if (data->device_flags & RMI_DEVICE) | 955 | if (data->device_flags & RMI_DEVICE) { |
| 956 | if ((data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) && | ||
| 957 | ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)) | ||
| 958 | return 0; | ||
| 959 | |||
| 946 | return -1; | 960 | return -1; |
| 961 | } | ||
| 947 | 962 | ||
| 948 | return 0; | 963 | return 0; |
| 949 | } | 964 | } |
| @@ -991,6 +1006,9 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 991 | return ret; | 1006 | return ret; |
| 992 | } | 1007 | } |
| 993 | 1008 | ||
| 1009 | if (id->driver_data) | ||
| 1010 | data->device_flags = id->driver_data; | ||
| 1011 | |||
| 994 | /* | 1012 | /* |
| 995 | * Check for the RMI specific report ids. If they are misisng | 1013 | * Check for the RMI specific report ids. If they are misisng |
| 996 | * simply return and let the events be processed by hid-input | 1014 | * simply return and let the events be processed by hid-input |
