diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2015-02-19 15:33:56 -0800 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-02-23 15:16:37 +0100 |
commit | b3f4737d00de317d1549d5cb5b1dad90e19f5cec (patch) | |
tree | 92cb55d8f19f340f2daf779336368cb3a34e8426 /drivers/hid/hid-sensor-hub.c | |
parent | cb67126f32f008b9abe97fbfca9b23a797b2458a (diff) | |
download | lwn-b3f4737d00de317d1549d5cb5b1dad90e19f5cec.tar.gz lwn-b3f4737d00de317d1549d5cb5b1dad90e19f5cec.zip |
HID: hid-sensor-hub: Extend API for async reads
Add additional flag to read in async mode. In this mode the caller will get
reply via registered callback for capture_sample. Callbacks can be registered
using sensor_hub_register_callback function. The usage id parameter of the
capture_sample can be matched with the usage id of the requested attribute.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-sensor-hub.c')
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index c325f85fa3a6..0a9162363164 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -250,48 +250,53 @@ EXPORT_SYMBOL_GPL(sensor_hub_get_feature); int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, u32 usage_id, - u32 attr_usage_id, u32 report_id) + u32 attr_usage_id, u32 report_id, + enum sensor_hub_read_flags flag) { struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); unsigned long flags; struct hid_report *report; int ret_val = 0; - mutex_lock(&hsdev->mutex); - memset(&hsdev->pending, 0, sizeof(hsdev->pending)); - init_completion(&hsdev->pending.ready); - hsdev->pending.usage_id = usage_id; - hsdev->pending.attr_usage_id = attr_usage_id; - hsdev->pending.raw_size = 0; - - spin_lock_irqsave(&data->lock, flags); - hsdev->pending.status = true; - spin_unlock_irqrestore(&data->lock, flags); - report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT); + report = sensor_hub_report(report_id, hsdev->hdev, + HID_INPUT_REPORT); if (!report) - goto err_free; + return -EINVAL; + mutex_lock(&hsdev->mutex); + if (flag == SENSOR_HUB_SYNC) { + memset(&hsdev->pending, 0, sizeof(hsdev->pending)); + init_completion(&hsdev->pending.ready); + hsdev->pending.usage_id = usage_id; + hsdev->pending.attr_usage_id = attr_usage_id; + hsdev->pending.raw_size = 0; + + spin_lock_irqsave(&data->lock, flags); + hsdev->pending.status = true; + spin_unlock_irqrestore(&data->lock, flags); + } mutex_lock(&data->mutex); hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); mutex_unlock(&data->mutex); - wait_for_completion_interruptible_timeout(&hsdev->pending.ready, HZ*5); - switch (hsdev->pending.raw_size) { - case 1: - ret_val = *(u8 *)hsdev->pending.raw_data; - break; - case 2: - ret_val = *(u16 *)hsdev->pending.raw_data; - break; - case 4: - ret_val = *(u32 *)hsdev->pending.raw_data; - break; - default: - ret_val = 0; + if (flag == SENSOR_HUB_SYNC) { + wait_for_completion_interruptible_timeout( + &hsdev->pending.ready, HZ*5); + switch (hsdev->pending.raw_size) { + case 1: + ret_val = *(u8 *)hsdev->pending.raw_data; + break; + case 2: + ret_val = *(u16 *)hsdev->pending.raw_data; + break; + case 4: + ret_val = *(u32 *)hsdev->pending.raw_data; + break; + default: + ret_val = 0; + } + kfree(hsdev->pending.raw_data); + hsdev->pending.status = false; } - kfree(hsdev->pending.raw_data); - -err_free: - hsdev->pending.status = false; mutex_unlock(&hsdev->mutex); return ret_val; |