summary refs log tree commit diff
path: root/drivers/hid/hid-sensor-hub.c
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-02-19 15:33:56 -0800
committerJiri Kosina <jkosina@suse.cz>2015-02-23 15:16:37 +0100
commitb3f4737d00de317d1549d5cb5b1dad90e19f5cec (patch)
tree92cb55d8f19f340f2daf779336368cb3a34e8426 /drivers/hid/hid-sensor-hub.c
parentcb67126f32f008b9abe97fbfca9b23a797b2458a (diff)
downloadlinux-b3f4737d00de317d1549d5cb5b1dad90e19f5cec.tar.gz
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.c65
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;