aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-02-19 18:33:56 -0500
committerJiri Kosina <jkosina@suse.cz>2015-02-23 09:16:37 -0500
commitb3f4737d00de317d1549d5cb5b1dad90e19f5cec (patch)
tree92cb55d8f19f340f2daf779336368cb3a34e8426 /drivers/hid
parentcb67126f32f008b9abe97fbfca9b23a797b2458a (diff)
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')
-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);
250 250
251int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 251int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
252 u32 usage_id, 252 u32 usage_id,
253 u32 attr_usage_id, u32 report_id) 253 u32 attr_usage_id, u32 report_id,
254 enum sensor_hub_read_flags flag)
254{ 255{
255 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 256 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
256 unsigned long flags; 257 unsigned long flags;
257 struct hid_report *report; 258 struct hid_report *report;
258 int ret_val = 0; 259 int ret_val = 0;
259 260
260 mutex_lock(&hsdev->mutex); 261 report = sensor_hub_report(report_id, hsdev->hdev,
261 memset(&hsdev->pending, 0, sizeof(hsdev->pending)); 262 HID_INPUT_REPORT);
262 init_completion(&hsdev->pending.ready);
263 hsdev->pending.usage_id = usage_id;
264 hsdev->pending.attr_usage_id = attr_usage_id;
265 hsdev->pending.raw_size = 0;
266
267 spin_lock_irqsave(&data->lock, flags);
268 hsdev->pending.status = true;
269 spin_unlock_irqrestore(&data->lock, flags);
270 report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
271 if (!report) 263 if (!report)
272 goto err_free; 264 return -EINVAL;
273 265
266 mutex_lock(&hsdev->mutex);
267 if (flag == SENSOR_HUB_SYNC) {
268 memset(&hsdev->pending, 0, sizeof(hsdev->pending));
269 init_completion(&hsdev->pending.ready);
270 hsdev->pending.usage_id = usage_id;
271 hsdev->pending.attr_usage_id = attr_usage_id;
272 hsdev->pending.raw_size = 0;
273
274 spin_lock_irqsave(&data->lock, flags);
275 hsdev->pending.status = true;
276 spin_unlock_irqrestore(&data->lock, flags);
277 }
274 mutex_lock(&data->mutex); 278 mutex_lock(&data->mutex);
275 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); 279 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
276 mutex_unlock(&data->mutex); 280 mutex_unlock(&data->mutex);
277 wait_for_completion_interruptible_timeout(&hsdev->pending.ready, HZ*5); 281 if (flag == SENSOR_HUB_SYNC) {
278 switch (hsdev->pending.raw_size) { 282 wait_for_completion_interruptible_timeout(
279 case 1: 283 &hsdev->pending.ready, HZ*5);
280 ret_val = *(u8 *)hsdev->pending.raw_data; 284 switch (hsdev->pending.raw_size) {
281 break; 285 case 1:
282 case 2: 286 ret_val = *(u8 *)hsdev->pending.raw_data;
283 ret_val = *(u16 *)hsdev->pending.raw_data; 287 break;
284 break; 288 case 2:
285 case 4: 289 ret_val = *(u16 *)hsdev->pending.raw_data;
286 ret_val = *(u32 *)hsdev->pending.raw_data; 290 break;
287 break; 291 case 4:
288 default: 292 ret_val = *(u32 *)hsdev->pending.raw_data;
289 ret_val = 0; 293 break;
294 default:
295 ret_val = 0;
296 }
297 kfree(hsdev->pending.raw_data);
298 hsdev->pending.status = false;
290 } 299 }
291 kfree(hsdev->pending.raw_data);
292
293err_free:
294 hsdev->pending.status = false;
295 mutex_unlock(&hsdev->mutex); 300 mutex_unlock(&hsdev->mutex);
296 301
297 return ret_val; 302 return ret_val;