diff options
author | Alexander Holler <holler@ahsoftware.de> | 2012-12-09 06:44:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-12-12 10:49:10 -0500 |
commit | 83499b52c61f50292f0aae36499de8a8fc3e37c3 (patch) | |
tree | e9e64260fc9aa83cfc6c34bc5226c5252b84c68c | |
parent | 1a1e8c6fada5f6dc48aa5dad453c9d9ebfdc8218 (diff) |
HID: sensors: autodetect USB HID sensor hubs
It should not be necessary to add IDs for HID sensor hubs to lists in
hid-core.c and hid-sensor-hub.c. So instead of a whitelist, autodetect such USB
HID sensor hubs, based on a collection of type physical inside a useage page of
type sensor. If some sensor hubs stil must be usable as raw devices, a
blacklist might be created.
Signed-off-by: Alexander Holler <holler@ahsoftware.de>
Acked-by: "Pandruvada, Srinivas" <srinivas.pandruvada@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-core.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 32 | ||||
-rw-r--r-- | include/linux/hid-sensor-ids.h | 1 | ||||
-rw-r--r-- | include/linux/hid.h | 2 |
4 files changed, 13 insertions, 33 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f4109fd657ff..7df5399a9386 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -713,7 +713,12 @@ static int hid_scan_report(struct hid_device *hid) | |||
713 | hid_scan_usage(hid, u); | 713 | hid_scan_usage(hid, u); |
714 | break; | 714 | break; |
715 | } | 715 | } |
716 | } | 716 | } else if (page == HID_UP_SENSOR && |
717 | item.type == HID_ITEM_TYPE_MAIN && | ||
718 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && | ||
719 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && | ||
720 | hid->bus == BUS_USB) | ||
721 | hid->group = HID_GROUP_SENSOR_HUB; | ||
717 | } | 722 | } |
718 | 723 | ||
719 | return 0; | 724 | return 0; |
@@ -1465,6 +1470,10 @@ EXPORT_SYMBOL_GPL(hid_disconnect); | |||
1465 | * there is a proper autodetection and autoloading in place (based on presence | 1470 | * there is a proper autodetection and autoloading in place (based on presence |
1466 | * of HID_DG_CONTACTID), so those devices don't need to be added to this list, | 1471 | * of HID_DG_CONTACTID), so those devices don't need to be added to this list, |
1467 | * as we are doing the right thing in hid_scan_usage(). | 1472 | * as we are doing the right thing in hid_scan_usage(). |
1473 | * | ||
1474 | * Autodetection for (USB) HID sensor hubs exists too. If a collection of type | ||
1475 | * physical is found inside a usage page of type sensor, hid-sensor-hub will be | ||
1476 | * used as a driver. See hid_scan_report(). | ||
1468 | */ | 1477 | */ |
1469 | static const struct hid_device_id hid_have_special_driver[] = { | 1478 | static const struct hid_device_id hid_have_special_driver[] = { |
1470 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1479 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index d9d73e9163eb..ca88ddc2d78f 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -82,23 +82,6 @@ struct hid_sensor_hub_callbacks_list { | |||
82 | void *priv; | 82 | void *priv; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static int sensor_hub_check_for_sensor_page(struct hid_device *hdev) | ||
86 | { | ||
87 | int i; | ||
88 | int ret = -EINVAL; | ||
89 | |||
90 | for (i = 0; i < hdev->maxcollection; i++) { | ||
91 | struct hid_collection *col = &hdev->collection[i]; | ||
92 | if (col->type == HID_COLLECTION_PHYSICAL && | ||
93 | (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) { | ||
94 | ret = 0; | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, | 85 | static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, |
103 | int dir) | 86 | int dir) |
104 | { | 87 | { |
@@ -524,10 +507,6 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
524 | hid_err(hdev, "parse failed\n"); | 507 | hid_err(hdev, "parse failed\n"); |
525 | goto err_free; | 508 | goto err_free; |
526 | } | 509 | } |
527 | if (sensor_hub_check_for_sensor_page(hdev) < 0) { | ||
528 | hid_err(hdev, "sensor page not found\n"); | ||
529 | goto err_free; | ||
530 | } | ||
531 | INIT_LIST_HEAD(&hdev->inputs); | 510 | INIT_LIST_HEAD(&hdev->inputs); |
532 | 511 | ||
533 | ret = hid_hw_start(hdev, 0); | 512 | ret = hid_hw_start(hdev, 0); |
@@ -630,16 +609,7 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
630 | } | 609 | } |
631 | 610 | ||
632 | static const struct hid_device_id sensor_hub_devices[] = { | 611 | static const struct hid_device_id sensor_hub_devices[] = { |
633 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, | 612 | { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, |
634 | USB_DEVICE_ID_SENSOR_HUB_1020) }, | ||
635 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, | ||
636 | USB_DEVICE_ID_SENSOR_HUB_1020) }, | ||
637 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, | ||
638 | USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
639 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, | ||
640 | USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
641 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, | ||
642 | USB_DEVICE_ID_SENSOR_HUB_7014) }, | ||
643 | { } | 613 | { } |
644 | }; | 614 | }; |
645 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); | 615 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); |
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h index ca8d7e94eb3c..55f277372fed 100644 --- a/include/linux/hid-sensor-ids.h +++ b/include/linux/hid-sensor-ids.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #ifndef _HID_SENSORS_IDS_H | 19 | #ifndef _HID_SENSORS_IDS_H |
20 | #define _HID_SENSORS_IDS_H | 20 | #define _HID_SENSORS_IDS_H |
21 | 21 | ||
22 | #define HID_UP_SENSOR 0x00200000 | ||
23 | #define HID_MAX_PHY_DEVICES 0xFF | 22 | #define HID_MAX_PHY_DEVICES 0xFF |
24 | 23 | ||
25 | /* Accel 3D (200073) */ | 24 | /* Accel 3D (200073) */ |
diff --git a/include/linux/hid.h b/include/linux/hid.h index c076041a069e..c5f6ec2b15c2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -167,6 +167,7 @@ struct hid_item { | |||
167 | #define HID_UP_MSVENDOR 0xff000000 | 167 | #define HID_UP_MSVENDOR 0xff000000 |
168 | #define HID_UP_CUSTOM 0x00ff0000 | 168 | #define HID_UP_CUSTOM 0x00ff0000 |
169 | #define HID_UP_LOGIVENDOR 0xffbc0000 | 169 | #define HID_UP_LOGIVENDOR 0xffbc0000 |
170 | #define HID_UP_SENSOR 0x00200000 | ||
170 | 171 | ||
171 | #define HID_USAGE 0x0000ffff | 172 | #define HID_USAGE 0x0000ffff |
172 | 173 | ||
@@ -292,6 +293,7 @@ struct hid_item { | |||
292 | */ | 293 | */ |
293 | #define HID_GROUP_GENERIC 0x0001 | 294 | #define HID_GROUP_GENERIC 0x0001 |
294 | #define HID_GROUP_MULTITOUCH 0x0002 | 295 | #define HID_GROUP_MULTITOUCH 0x0002 |
296 | #define HID_GROUP_SENSOR_HUB 0x0003 | ||
295 | 297 | ||
296 | /* | 298 | /* |
297 | * This is the global environment of the parser. This information is | 299 | * This is the global environment of the parser. This information is |