aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-sensor-hub.c30
-rw-r--r--include/linux/hid-sensor-ids.h2
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 62fadf8c86fc..c325f85fa3a6 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -86,7 +86,8 @@ static int sensor_hub_get_physical_device_count(struct hid_device *hdev)
86 86
87 for (i = 0; i < hdev->maxcollection; ++i) { 87 for (i = 0; i < hdev->maxcollection; ++i) {
88 struct hid_collection *collection = &hdev->collection[i]; 88 struct hid_collection *collection = &hdev->collection[i];
89 if (collection->type == HID_COLLECTION_PHYSICAL) 89 if (collection->type == HID_COLLECTION_PHYSICAL ||
90 collection->type == HID_COLLECTION_APPLICATION)
90 ++count; 91 ++count;
91 } 92 }
92 93
@@ -118,7 +119,8 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
118 119
119 spin_lock(&pdata->dyn_callback_lock); 120 spin_lock(&pdata->dyn_callback_lock);
120 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 121 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
121 if (callback->usage_id == usage_id && 122 if ((callback->usage_id == usage_id ||
123 callback->usage_id == HID_USAGE_SENSOR_COLLECTION) &&
122 (collection_index >= 124 (collection_index >=
123 callback->hsdev->start_collection_index) && 125 callback->hsdev->start_collection_index) &&
124 (collection_index < 126 (collection_index <
@@ -157,7 +159,18 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
157 callback->usage_callback = usage_callback; 159 callback->usage_callback = usage_callback;
158 callback->usage_id = usage_id; 160 callback->usage_id = usage_id;
159 callback->priv = NULL; 161 callback->priv = NULL;
160 list_add_tail(&callback->list, &pdata->dyn_callback_list); 162 /*
163 * If there is a handler registered for the collection type, then
164 * it will handle all reports for sensors in this collection. If
165 * there is also an individual sensor handler registration, then
166 * we want to make sure that the reports are directed to collection
167 * handler, as this may be a fusion sensor. So add collection handlers
168 * to the beginning of the list, so that they are matched first.
169 */
170 if (usage_id == HID_USAGE_SENSOR_COLLECTION)
171 list_add(&callback->list, &pdata->dyn_callback_list);
172 else
173 list_add_tail(&callback->list, &pdata->dyn_callback_list);
161 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); 174 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
162 175
163 return 0; 176 return 0;
@@ -555,6 +568,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
555 int dev_cnt; 568 int dev_cnt;
556 struct hid_sensor_hub_device *hsdev; 569 struct hid_sensor_hub_device *hsdev;
557 struct hid_sensor_hub_device *last_hsdev = NULL; 570 struct hid_sensor_hub_device *last_hsdev = NULL;
571 struct hid_sensor_hub_device *collection_hsdev = NULL;
558 572
559 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); 573 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
560 if (!sd) { 574 if (!sd) {
@@ -601,7 +615,8 @@ static int sensor_hub_probe(struct hid_device *hdev,
601 for (i = 0; i < hdev->maxcollection; ++i) { 615 for (i = 0; i < hdev->maxcollection; ++i) {
602 struct hid_collection *collection = &hdev->collection[i]; 616 struct hid_collection *collection = &hdev->collection[i];
603 617
604 if (collection->type == HID_COLLECTION_PHYSICAL) { 618 if (collection->type == HID_COLLECTION_PHYSICAL ||
619 collection->type == HID_COLLECTION_APPLICATION) {
605 620
606 hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), 621 hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),
607 GFP_KERNEL); 622 GFP_KERNEL);
@@ -638,10 +653,17 @@ static int sensor_hub_probe(struct hid_device *hdev,
638 hid_dbg(hdev, "Adding %s:%d\n", name, 653 hid_dbg(hdev, "Adding %s:%d\n", name,
639 hsdev->start_collection_index); 654 hsdev->start_collection_index);
640 sd->hid_sensor_client_cnt++; 655 sd->hid_sensor_client_cnt++;
656 if (collection_hsdev)
657 collection_hsdev->end_collection_index = i;
658 if (collection->type == HID_COLLECTION_APPLICATION &&
659 collection->usage == HID_USAGE_SENSOR_COLLECTION)
660 collection_hsdev = hsdev;
641 } 661 }
642 } 662 }
643 if (last_hsdev) 663 if (last_hsdev)
644 last_hsdev->end_collection_index = i; 664 last_hsdev->end_collection_index = i;
665 if (collection_hsdev)
666 collection_hsdev->end_collection_index = i;
645 667
646 ret = mfd_add_hotplug_devices(&hdev->dev, 668 ret = mfd_add_hotplug_devices(&hdev->dev,
647 sd->hid_sensor_hub_client_devs, 669 sd->hid_sensor_hub_client_devs,
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index 109f0e633e01..f2ee90aed0c2 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -21,6 +21,8 @@
21 21
22#define HID_MAX_PHY_DEVICES 0xFF 22#define HID_MAX_PHY_DEVICES 0xFF
23 23
24#define HID_USAGE_SENSOR_COLLECTION 0x200001
25
24/* Accel 3D (200073) */ 26/* Accel 3D (200073) */
25#define HID_USAGE_SENSOR_ACCEL_3D 0x200073 27#define HID_USAGE_SENSOR_ACCEL_3D 0x200073
26#define HID_USAGE_SENSOR_DATA_ACCELERATION 0x200452 28#define HID_USAGE_SENSOR_DATA_ACCELERATION 0x200452