aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2014-12-12 13:17:26 -0500
committerJiri Kosina <jkosina@suse.cz>2014-12-17 03:13:13 -0500
commite39f2d5956999c05c85814787a113ffadbcd4b26 (patch)
tree55bf92a52e0b733a5c4ca7547e6b74b83de0083a
parent0349678ccd74d16c1f2bb58ecafec13ef7110e36 (diff)
HID: rmi: Scan the report descriptor to determine if the device is suitable for the hid-rmi driver
On composite HID devices there may be multiple HID devices on separate interfaces, but hid-rmi should only bind to the touchpad. The previous version simply checked that the interface protocol was set to mouse. Unfortuately, it is not always the case that the touchpad has the mouse interface protocol set. This patch takes a different approach and scans the report descriptor looking for the Generic Desktop Pointer usage and the Vendor Specific Top Level Collection needed by the hid-rmi driver to interface with the device. Signed-off-by: Andrew Duggan <aduggan@synaptics.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-core.c22
-rw-r--r--include/linux/hid.h4
2 files changed, 20 insertions, 6 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index c3d0ac1a0988..81665b4f2258 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -698,6 +698,7 @@ static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
698static void hid_scan_collection(struct hid_parser *parser, unsigned type) 698static void hid_scan_collection(struct hid_parser *parser, unsigned type)
699{ 699{
700 struct hid_device *hid = parser->device; 700 struct hid_device *hid = parser->device;
701 int i;
701 702
702 if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && 703 if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
703 type == HID_COLLECTION_PHYSICAL) 704 type == HID_COLLECTION_PHYSICAL)
@@ -707,6 +708,14 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
707 hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 && 708 hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 &&
708 hid->group == HID_GROUP_MULTITOUCH) 709 hid->group == HID_GROUP_MULTITOUCH)
709 hid->group = HID_GROUP_GENERIC; 710 hid->group = HID_GROUP_GENERIC;
711
712 if ((parser->global.usage_page << 16) == HID_UP_GENDESK)
713 for (i = 0; i < parser->local.usage_index; i++)
714 if (parser->local.usage[i] == HID_GD_POINTER)
715 parser->scan_flags |= HID_SCAN_FLAG_GD_POINTER;
716
717 if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR)
718 parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC;
710} 719}
711 720
712static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) 721static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
@@ -792,11 +801,14 @@ static int hid_scan_report(struct hid_device *hid)
792 hid->group = HID_GROUP_WACOM; 801 hid->group = HID_GROUP_WACOM;
793 break; 802 break;
794 case USB_VENDOR_ID_SYNAPTICS: 803 case USB_VENDOR_ID_SYNAPTICS:
795 if ((hid->group == HID_GROUP_GENERIC) && 804 if (hid->group == HID_GROUP_GENERIC)
796 (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) 805 if ((parser->scan_flags & HID_SCAN_FLAG_VENDOR_SPECIFIC)
797 /* hid-rmi should only bind to the mouse interface of 806 && (parser->scan_flags & HID_SCAN_FLAG_GD_POINTER))
798 * composite USB devices */ 807 /*
799 hid->group = HID_GROUP_RMI; 808 * hid-rmi should take care of them,
809 * not hid-generic
810 */
811 hid->group = HID_GROUP_RMI;
800 break; 812 break;
801 } 813 }
802 814
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 06c4607744f6..efc7787a41a8 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -574,7 +574,9 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
574#define HID_GLOBAL_STACK_SIZE 4 574#define HID_GLOBAL_STACK_SIZE 4
575#define HID_COLLECTION_STACK_SIZE 4 575#define HID_COLLECTION_STACK_SIZE 4
576 576
577#define HID_SCAN_FLAG_MT_WIN_8 0x00000001 577#define HID_SCAN_FLAG_MT_WIN_8 BIT(0)
578#define HID_SCAN_FLAG_VENDOR_SPECIFIC BIT(1)
579#define HID_SCAN_FLAG_GD_POINTER BIT(2)
578 580
579struct hid_parser { 581struct hid_parser {
580 struct hid_global global; 582 struct hid_global global;