^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HID Sensors Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2012, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/hid-sensor-ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hid-sensor-hub.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define HID_SENSOR_HUB_ENUM_QUIRK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * struct sensor_hub_data - Hold a instance data for a HID hub device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @hsdev: Stored hid instance for current hub device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @mutex: Mutex to serialize synchronous request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @lock: Spin lock to protect pending request structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @dyn_callback_list: Holds callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @dyn_callback_lock: spin lock to protect callback list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * @ref_cnt: Number of MFD clients have opened this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct sensor_hub_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct list_head dyn_callback_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) spinlock_t dyn_callback_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct mfd_cell *hid_sensor_hub_client_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int hid_sensor_client_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int ref_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * struct hid_sensor_hub_callbacks_list - Stores callback list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @list: list head.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @usage_id: usage id for a physical device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @usage_callback: Stores registered callback functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @priv: Private data for a physical device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct hid_sensor_hub_callbacks_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct hid_sensor_hub_device *hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct hid_sensor_hub_callbacks *usage_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (report->id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) hid_warn(hdev, "No report with id 0x%x found\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int sensor_hub_get_physical_device_count(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) for (i = 0; i < hdev->maxcollection; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct hid_collection *collection = &hdev->collection[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (collection->type == HID_COLLECTION_PHYSICAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) collection->type == HID_COLLECTION_APPLICATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void sensor_hub_fill_attr_info(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct hid_sensor_hub_attribute_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) s32 index, s32 report_id, struct hid_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) info->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) info->report_id = report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) info->units = field->unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) info->unit_expo = field->unit_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) info->size = (field->report_size * field->report_count)/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) info->logical_minimum = field->logical_minimum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) info->logical_maximum = field->logical_maximum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 usage_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int collection_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct hid_sensor_hub_device **hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void **priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct hid_sensor_hub_callbacks_list *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) list_for_each_entry(callback, &pdata->dyn_callback_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if ((callback->usage_id == usage_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) callback->usage_id == HID_USAGE_SENSOR_COLLECTION) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) (collection_index >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) callback->hsdev->start_collection_index) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) (collection_index <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) callback->hsdev->end_collection_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *priv = callback->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *hsdev = callback->hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spin_unlock_irqrestore(&pdata->dyn_callback_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return callback->usage_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 usage_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct hid_sensor_hub_callbacks *usage_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct hid_sensor_hub_callbacks_list *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) list_for_each_entry(callback, &pdata->dyn_callback_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (callback->usage_id == usage_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) callback->hsdev == hsdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) callback->hsdev = hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) callback->usage_callback = usage_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) callback->usage_id = usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) callback->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * If there is a handler registered for the collection type, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * it will handle all reports for sensors in this collection. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * there is also an individual sensor handler registration, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * we want to make sure that the reports are directed to collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * handler, as this may be a fusion sensor. So add collection handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * to the beginning of the list, so that they are matched first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (usage_id == HID_USAGE_SENSOR_COLLECTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) list_add(&callback->list, &pdata->dyn_callback_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) list_add_tail(&callback->list, &pdata->dyn_callback_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 usage_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct hid_sensor_hub_callbacks_list *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) list_for_each_entry(callback, &pdata->dyn_callback_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (callback->usage_id == usage_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) callback->hsdev == hsdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) list_del(&callback->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) kfree(callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 field_index, int buffer_size, void *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __s32 *buf32 = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int remaining_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __s32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!report || (field_index >= report->maxfield)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) remaining_bytes = buffer_size % sizeof(__s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) buffer_size = buffer_size / sizeof(__s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (buffer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (i = 0; i < buffer_size; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = hid_set_field(report->field[field_index], i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) (__force __s32)cpu_to_le32(*buf32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ++buf32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (remaining_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) memcpy(&value, (u8 *)buf32, remaining_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = hid_set_field(report->field[field_index], i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) (__force __s32)cpu_to_le32(value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) hid_hw_wait(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) done_proc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) EXPORT_SYMBOL_GPL(sensor_hub_set_feature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 field_index, int buffer_size, void *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int report_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u8 *val_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int buffer_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) memset(buffer, 0, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!report || (field_index >= report->maxfield) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) report->field[field_index]->report_count < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) hid_hw_wait(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* calculate number of bytes required to read this field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) report_size = DIV_ROUND_UP(report->field[field_index]->report_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) report->field[field_index]->report_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!report_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = min(report_size, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) val_ptr = (u8 *)report->field[field_index]->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) for (i = 0; i < report->field[field_index]->report_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (buffer_index >= ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) memcpy(&((u8 *)buffer)[buffer_index], val_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) report->field[field_index]->report_size / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) val_ptr += sizeof(__s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) buffer_index += (report->field[field_index]->report_size / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) done_proc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u32 usage_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 attr_usage_id, u32 report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) enum sensor_hub_read_flags flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) bool is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) report = sensor_hub_report(report_id, hsdev->hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) HID_INPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mutex_lock(hsdev->mutex_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (flag == SENSOR_HUB_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) memset(&hsdev->pending, 0, sizeof(hsdev->pending));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) init_completion(&hsdev->pending.ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) hsdev->pending.usage_id = usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) hsdev->pending.attr_usage_id = attr_usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) hsdev->pending.raw_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) spin_lock_irqsave(&data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) hsdev->pending.status = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_unlock_irqrestore(&data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (flag == SENSOR_HUB_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) wait_for_completion_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) &hsdev->pending.ready, HZ*5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) switch (hsdev->pending.raw_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ret_val = *(s8 *)hsdev->pending.raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ret_val = *(u8 *)hsdev->pending.raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ret_val = *(s16 *)hsdev->pending.raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret_val = *(u16 *)hsdev->pending.raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret_val = *(u32 *)hsdev->pending.raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) kfree(hsdev->pending.raw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) hsdev->pending.status = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) mutex_unlock(hsdev->mutex_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int hid_sensor_get_usage_index(struct hid_sensor_hub_device *hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) u32 report_id, int field_index, u32 usage_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct hid_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!report || (field_index >= report->maxfield))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto done_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) field = report->field[field_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) for (i = 0; i < field->maxusage; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (field->usage[i].hid == usage_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return field->usage[i].usage_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) done_proc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) EXPORT_SYMBOL_GPL(hid_sensor_get_usage_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 usage_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u32 attr_usage_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct hid_sensor_hub_attribute_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct hid_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct hid_report_enum *report_enum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct hid_device *hdev = hsdev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Initialize with defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) info->usage_id = usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) info->attrib_id = attr_usage_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) info->report_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) info->index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) info->units = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) info->unit_expo = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) report_enum = &hdev->report_enum[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) list_for_each_entry(report, &report_enum->report_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (i = 0; i < report->maxfield; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) field = report->field[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (field->maxusage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (field->physical == usage_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) (field->logical == attr_usage_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) field->usage[0].hid ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) attr_usage_id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) (field->usage[0].collection_index >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) hsdev->start_collection_index) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) (field->usage[0].collection_index <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) hsdev->end_collection_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) sensor_hub_fill_attr_info(info, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) report->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct hid_sensor_hub_callbacks_list *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) hid_dbg(hdev, " sensor_hub_suspend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (callback->usage_callback->suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) callback->usage_callback->suspend(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) callback->hsdev, callback->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int sensor_hub_resume(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct hid_sensor_hub_callbacks_list *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) hid_dbg(hdev, " sensor_hub_resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (callback->usage_callback->resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) callback->usage_callback->resume(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) callback->hsdev, callback->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int sensor_hub_reset_resume(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Handle raw report as sent by device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int sensor_hub_raw_event(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct hid_report *report, u8 *raw_data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u8 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct hid_sensor_hub_callbacks *callback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct hid_collection *collection = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void *priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct hid_sensor_hub_device *hsdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) report->id, size, report->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) hid_dbg(hdev, "maxfield:%d\n", report->maxfield);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (report->type != HID_INPUT_REPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ptr = raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (report->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ptr++; /* Skip report id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) spin_lock_irqsave(&pdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (i = 0; i < report->maxfield; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) i, report->field[i]->usage->collection_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) report->field[i]->usage->hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) (report->field[i]->report_size *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) report->field[i]->report_count)/8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) sz = (report->field[i]->report_size *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) report->field[i]->report_count)/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) collection = &hdev->collection[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) report->field[i]->usage->collection_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) hid_dbg(hdev, "collection->usage %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) collection->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) callback = sensor_hub_get_callback(hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) report->field[i]->physical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) report->field[i]->usage[0].collection_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) &hsdev, &priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ptr += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (hsdev->pending.status && (hsdev->pending.attr_usage_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) report->field[i]->usage->hid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) hsdev->pending.attr_usage_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) report->field[i]->logical)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) hid_dbg(hdev, "data was pending ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (hsdev->pending.raw_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) hsdev->pending.raw_size = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hsdev->pending.raw_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) complete(&hsdev->pending.ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (callback->capture_sample) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (report->field[i]->logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) callback->capture_sample(hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) report->field[i]->logical, sz, ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) callback->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) callback->capture_sample(hsdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) report->field[i]->usage->hid, sz, ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) callback->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ptr += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (callback && collection && callback->send_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) callback->send_event(hsdev, collection->usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) callback->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) spin_unlock_irqrestore(&pdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!data->ref_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = hid_hw_open(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) hid_err(hsdev->hdev, "failed to open hid device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) data->ref_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) EXPORT_SYMBOL_GPL(sensor_hub_device_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) data->ref_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!data->ref_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) hid_hw_close(hsdev->hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) EXPORT_SYMBOL_GPL(sensor_hub_device_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned int *rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Checks if the report descriptor of Thinkpad Helix 2 has a logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * minimum for magnetic flux axis greater than the maximum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) rdesc[921] == 0x07 && rdesc[922] == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* Sets negative logical minimum for mag x, y and z */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return rdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static int sensor_hub_probe(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct sensor_hub_data *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int dev_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct hid_sensor_hub_device *hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct hid_sensor_hub_device *last_hsdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct hid_sensor_hub_device *collection_hsdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (!sd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) hid_err(hdev, "cannot allocate Sensor data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) hid_set_drvdata(hdev, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) sd->quirks = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) spin_lock_init(&sd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) spin_lock_init(&sd->dyn_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mutex_init(&sd->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ret = hid_parse(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) hid_err(hdev, "parse failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) INIT_LIST_HEAD(&hdev->inputs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = hid_hw_start(hdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) hid_err(hdev, "hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) INIT_LIST_HEAD(&sd->dyn_callback_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) sd->hid_sensor_client_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev_cnt = sensor_hub_get_physical_device_count(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (dev_cnt > HID_MAX_PHY_DEVICES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) hid_err(hdev, "Invalid Physical device count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) sd->hid_sensor_hub_client_devs = devm_kcalloc(&hdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dev_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) sizeof(struct mfd_cell),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (sd->hid_sensor_hub_client_devs == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) hid_err(hdev, "Failed to allocate memory for mfd cells\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) for (i = 0; i < hdev->maxcollection; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct hid_collection *collection = &hdev->collection[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (collection->type == HID_COLLECTION_PHYSICAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) collection->type == HID_COLLECTION_APPLICATION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!hsdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) hsdev->hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) hsdev->vendor_id = hdev->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) hsdev->product_id = hdev->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) hsdev->usage = collection->usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) hsdev->mutex_ptr = devm_kzalloc(&hdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) sizeof(struct mutex),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (!hsdev->mutex_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) mutex_init(hsdev->mutex_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) hsdev->start_collection_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (last_hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) last_hsdev->end_collection_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) last_hsdev = hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) "HID-SENSOR-%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) collection->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) hid_err(hdev, "Failed MFD device name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sd->hid_sensor_hub_client_devs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) sd->hid_sensor_client_cnt].name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) sd->hid_sensor_hub_client_devs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) sd->hid_sensor_client_cnt].platform_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) sd->hid_sensor_hub_client_devs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sd->hid_sensor_client_cnt].pdata_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) sizeof(*hsdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) hid_dbg(hdev, "Adding %s:%d\n", name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) hsdev->start_collection_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sd->hid_sensor_client_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (collection_hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) collection_hsdev->end_collection_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (collection->type == HID_COLLECTION_APPLICATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) collection->usage == HID_USAGE_SENSOR_COLLECTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) collection_hsdev = hsdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (last_hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) last_hsdev->end_collection_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (collection_hsdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) collection_hsdev->end_collection_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret = mfd_add_hotplug_devices(&hdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) sd->hid_sensor_hub_client_devs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sd->hid_sensor_client_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto err_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) err_stop_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static void sensor_hub_remove(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct sensor_hub_data *data = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) hid_dbg(hdev, " hardware removed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) hid_hw_close(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_lock_irqsave(&data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct hid_sensor_hub_device *hsdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) data->hid_sensor_hub_client_devs[i].platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (hsdev->pending.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) complete(&hsdev->pending.ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spin_unlock_irqrestore(&data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mfd_remove_devices(&hdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mutex_destroy(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct hid_device_id sensor_hub_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) HID_ANY_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static struct hid_driver sensor_hub_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .name = "hid-sensor-hub",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .id_table = sensor_hub_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .probe = sensor_hub_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .remove = sensor_hub_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .raw_event = sensor_hub_raw_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .report_fixup = sensor_hub_report_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .suspend = sensor_hub_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .resume = sensor_hub_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .reset_resume = sensor_hub_reset_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) module_hid_driver(sensor_hub_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) MODULE_DESCRIPTION("HID Sensor Hub driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) MODULE_LICENSE("GPL");