diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2014-09-30 13:18:30 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-10-29 05:51:40 -0400 |
commit | 33797820af98cde5c7cee00d00f0d8e255ea199f (patch) | |
tree | 2d85919e568b520986c52fed4af86d077f755bf9 /drivers/hid/hid-logitech-dj.c | |
parent | 925f0f3ed24f98b40c28627e74ff3e7f9d1e28bc (diff) |
HID: logitech: allow the DJ device to request the unifying name
The names of the DJ devices are stored in the receiver. These names
can be retrieved through a HID++ command. However, the protocol says
that you have to ask the receiver for that, not the device iteself.
Introduce a special case in the DJ handling where a device can request
its unifying name, and when such a name is given, forward it also to
the corresponding device.
On the HID++ side, the receiver talks only HID++ 1.0, so we need to
implement this part of the protocol in the module.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Tested-by: Andrew de los Reyes <adlr@chromium.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-logitech-dj.c')
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index feddacd87b8b..9bc39421627f 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -667,6 +667,9 @@ static void logi_dj_ll_close(struct hid_device *hid) | |||
667 | dbg_hid("%s:%s\n", __func__, hid->phys); | 667 | dbg_hid("%s:%s\n", __func__, hid->phys); |
668 | } | 668 | } |
669 | 669 | ||
670 | static u8 unifying_name_query[] = {0x10, 0xff, 0x83, 0xb5, 0x40, 0x00, 0x00}; | ||
671 | static u8 unifying_name_answer[] = {0x11, 0xff, 0x83, 0xb5}; | ||
672 | |||
670 | static int logi_dj_ll_raw_request(struct hid_device *hid, | 673 | static int logi_dj_ll_raw_request(struct hid_device *hid, |
671 | unsigned char reportnum, __u8 *buf, | 674 | unsigned char reportnum, __u8 *buf, |
672 | size_t count, unsigned char report_type, | 675 | size_t count, unsigned char report_type, |
@@ -682,7 +685,13 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
682 | if (count < 2) | 685 | if (count < 2) |
683 | return -EINVAL; | 686 | return -EINVAL; |
684 | 687 | ||
685 | buf[1] = djdev->device_index; | 688 | /* special case where we should not overwrite |
689 | * the device_index */ | ||
690 | if (count == 7 && !memcmp(buf, unifying_name_query, | ||
691 | sizeof(unifying_name_query))) | ||
692 | buf[4] |= djdev->device_index - 1; | ||
693 | else | ||
694 | buf[1] = djdev->device_index; | ||
686 | return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, | 695 | return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, |
687 | count, report_type, reqtype); | 696 | count, report_type, reqtype); |
688 | } | 697 | } |
@@ -873,8 +882,17 @@ static int logi_dj_hidpp_event(struct hid_device *hdev, | |||
873 | unsigned long flags; | 882 | unsigned long flags; |
874 | u8 device_index = dj_report->device_index; | 883 | u8 device_index = dj_report->device_index; |
875 | 884 | ||
876 | if (device_index == HIDPP_RECEIVER_INDEX) | 885 | if (device_index == HIDPP_RECEIVER_INDEX) { |
877 | return false; | 886 | /* special case were the device wants to know its unifying |
887 | * name */ | ||
888 | if (size == HIDPP_REPORT_LONG_LENGTH && | ||
889 | !memcmp(data, unifying_name_answer, | ||
890 | sizeof(unifying_name_answer)) && | ||
891 | ((data[4] & 0xF0) == 0x40)) | ||
892 | device_index = (data[4] & 0x0F) + 1; | ||
893 | else | ||
894 | return false; | ||
895 | } | ||
878 | 896 | ||
879 | /* | 897 | /* |
880 | * Data is from the HID++ collection, in this case, we forward the | 898 | * Data is from the HID++ collection, in this case, we forward the |