Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: hid-sensor-hub: Add support for application collection

Section 4.2.5 of HID Sensor hub specification allows two methods
defining sensor devices.
- Each sensor device by its own collection
- A top level application collection object, including multiple
sensors.
In the first method, each sensor can be in its own sensor application
collection without a physical collection.
In the second method there is a usage id for collection type, which
is defined as an application collection, with multiple physical
collections in it. It is possible to define fusion sensor with this
and may have its own handler. If there is a callback registered
for the collection type, then forward all reports for sensors in
its collection to this handler.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Srinivas Pandruvada and committed by
Jiri Kosina
cb67126f e651a1da

+28 -4
+26 -4
drivers/hid/hid-sensor-hub.c
··· 86 86 87 87 for (i = 0; i < hdev->maxcollection; ++i) { 88 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 91 ++count; 91 92 } 92 93 ··· 119 118 120 119 spin_lock(&pdata->dyn_callback_lock); 121 120 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 122 - if (callback->usage_id == usage_id && 121 + if ((callback->usage_id == usage_id || 122 + callback->usage_id == HID_USAGE_SENSOR_COLLECTION) && 123 123 (collection_index >= 124 124 callback->hsdev->start_collection_index) && 125 125 (collection_index < ··· 159 157 callback->usage_callback = usage_callback; 160 158 callback->usage_id = usage_id; 161 159 callback->priv = NULL; 162 - list_add_tail(&callback->list, &pdata->dyn_callback_list); 160 + /* 161 + * If there is a handler registered for the collection type, then 162 + * it will handle all reports for sensors in this collection. If 163 + * there is also an individual sensor handler registration, then 164 + * we want to make sure that the reports are directed to collection 165 + * handler, as this may be a fusion sensor. So add collection handlers 166 + * to the beginning of the list, so that they are matched first. 167 + */ 168 + if (usage_id == HID_USAGE_SENSOR_COLLECTION) 169 + list_add(&callback->list, &pdata->dyn_callback_list); 170 + else 171 + list_add_tail(&callback->list, &pdata->dyn_callback_list); 163 172 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); 164 173 165 174 return 0; ··· 568 555 int dev_cnt; 569 556 struct hid_sensor_hub_device *hsdev; 570 557 struct hid_sensor_hub_device *last_hsdev = NULL; 558 + struct hid_sensor_hub_device *collection_hsdev = NULL; 571 559 572 560 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); 573 561 if (!sd) { ··· 615 601 for (i = 0; i < hdev->maxcollection; ++i) { 616 602 struct hid_collection *collection = &hdev->collection[i]; 617 603 618 - if (collection->type == HID_COLLECTION_PHYSICAL) { 604 + if (collection->type == HID_COLLECTION_PHYSICAL || 605 + collection->type == HID_COLLECTION_APPLICATION) { 619 606 620 607 hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), 621 608 GFP_KERNEL); ··· 653 638 hid_dbg(hdev, "Adding %s:%d\n", name, 654 639 hsdev->start_collection_index); 655 640 sd->hid_sensor_client_cnt++; 641 + if (collection_hsdev) 642 + collection_hsdev->end_collection_index = i; 643 + if (collection->type == HID_COLLECTION_APPLICATION && 644 + collection->usage == HID_USAGE_SENSOR_COLLECTION) 645 + collection_hsdev = hsdev; 656 646 } 657 647 } 658 648 if (last_hsdev) 659 649 last_hsdev->end_collection_index = i; 650 + if (collection_hsdev) 651 + collection_hsdev->end_collection_index = i; 660 652 661 653 ret = mfd_add_hotplug_devices(&hdev->dev, 662 654 sd->hid_sensor_hub_client_devs,
+2
include/linux/hid-sensor-ids.h
··· 21 21 22 22 #define HID_MAX_PHY_DEVICES 0xFF 23 23 24 + #define HID_USAGE_SENSOR_COLLECTION 0x200001 25 + 24 26 /* Accel 3D (200073) */ 25 27 #define HID_USAGE_SENSOR_ACCEL_3D 0x200073 26 28 #define HID_USAGE_SENSOR_DATA_ACCELERATION 0x200452