Lines Matching +full:sensor +full:- +full:hub

1 // SPDX-License-Identifier: GPL-2.0-only
13 #include <linux/hid-sensor-ids.h>
14 #include <linux/hid-sensor-hub.h>
15 #include "hid-ids.h"
20 * struct sensor_hub_data - Hold a instance data for a HID hub device
25 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
40 * struct hid_sensor_hub_callbacks_list - Stores callback list
43 * @hsdev: Stored hid instance for current hub device.
60 list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) { in sensor_hub_report()
61 if (report->id == id) in sensor_hub_report()
74 for (i = 0; i < hdev->maxcollection; ++i) { in sensor_hub_get_physical_device_count()
75 struct hid_collection *collection = &hdev->collection[i]; in sensor_hub_get_physical_device_count()
76 if (collection->type == HID_COLLECTION_PHYSICAL || in sensor_hub_get_physical_device_count()
77 collection->type == HID_COLLECTION_APPLICATION) in sensor_hub_get_physical_device_count()
88 info->index = index; in sensor_hub_fill_attr_info()
89 info->report_id = report_id; in sensor_hub_fill_attr_info()
90 info->units = field->unit; in sensor_hub_fill_attr_info()
91 info->unit_expo = field->unit_exponent; in sensor_hub_fill_attr_info()
92 info->size = (field->report_size * field->report_count)/8; in sensor_hub_fill_attr_info()
93 info->logical_minimum = field->logical_minimum; in sensor_hub_fill_attr_info()
94 info->logical_maximum = field->logical_maximum; in sensor_hub_fill_attr_info()
108 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); in sensor_hub_get_callback()
109 list_for_each_entry(callback, &pdata->dyn_callback_list, list) in sensor_hub_get_callback()
110 if ((callback->usage_id == usage_id || in sensor_hub_get_callback()
111 callback->usage_id == HID_USAGE_SENSOR_COLLECTION) && in sensor_hub_get_callback()
113 callback->hsdev->start_collection_index) && in sensor_hub_get_callback()
115 callback->hsdev->end_collection_index)) { in sensor_hub_get_callback()
116 *priv = callback->priv; in sensor_hub_get_callback()
117 *hsdev = callback->hsdev; in sensor_hub_get_callback()
118 spin_unlock_irqrestore(&pdata->dyn_callback_lock, in sensor_hub_get_callback()
120 return callback->usage_callback; in sensor_hub_get_callback()
122 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_get_callback()
132 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); in sensor_hub_register_callback()
135 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); in sensor_hub_register_callback()
136 list_for_each_entry(callback, &pdata->dyn_callback_list, list) in sensor_hub_register_callback()
137 if (callback->usage_id == usage_id && in sensor_hub_register_callback()
138 callback->hsdev == hsdev) { in sensor_hub_register_callback()
139 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_register_callback()
140 return -EINVAL; in sensor_hub_register_callback()
144 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_register_callback()
145 return -ENOMEM; in sensor_hub_register_callback()
147 callback->hsdev = hsdev; in sensor_hub_register_callback()
148 callback->usage_callback = usage_callback; in sensor_hub_register_callback()
149 callback->usage_id = usage_id; in sensor_hub_register_callback()
150 callback->priv = NULL; in sensor_hub_register_callback()
154 * there is also an individual sensor handler registration, then in sensor_hub_register_callback()
156 * handler, as this may be a fusion sensor. So add collection handlers in sensor_hub_register_callback()
160 list_add(&callback->list, &pdata->dyn_callback_list); in sensor_hub_register_callback()
162 list_add_tail(&callback->list, &pdata->dyn_callback_list); in sensor_hub_register_callback()
163 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_register_callback()
173 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); in sensor_hub_remove_callback()
176 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); in sensor_hub_remove_callback()
177 list_for_each_entry(callback, &pdata->dyn_callback_list, list) in sensor_hub_remove_callback()
178 if (callback->usage_id == usage_id && in sensor_hub_remove_callback()
179 callback->hsdev == hsdev) { in sensor_hub_remove_callback()
180 list_del(&callback->list); in sensor_hub_remove_callback()
184 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_remove_callback()
194 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); in sensor_hub_set_feature()
201 mutex_lock(&data->mutex); in sensor_hub_set_feature()
202 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); in sensor_hub_set_feature()
203 if (!report || (field_index >= report->maxfield)) { in sensor_hub_set_feature()
204 ret = -EINVAL; in sensor_hub_set_feature()
212 ret = hid_set_field(report->field[field_index], i, in sensor_hub_set_feature()
223 ret = hid_set_field(report->field[field_index], i, in sensor_hub_set_feature()
228 hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); in sensor_hub_set_feature()
229 hid_hw_wait(hsdev->hdev); in sensor_hub_set_feature()
232 mutex_unlock(&data->mutex); in sensor_hub_set_feature()
242 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); in sensor_hub_get_feature()
251 mutex_lock(&data->mutex); in sensor_hub_get_feature()
252 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); in sensor_hub_get_feature()
253 if (!report || (field_index >= report->maxfield) || in sensor_hub_get_feature()
254 report->field[field_index]->report_count < 1) { in sensor_hub_get_feature()
255 ret = -EINVAL; in sensor_hub_get_feature()
258 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); in sensor_hub_get_feature()
259 hid_hw_wait(hsdev->hdev); in sensor_hub_get_feature()
262 report_size = DIV_ROUND_UP(report->field[field_index]->report_size, in sensor_hub_get_feature()
264 report->field[field_index]->report_count; in sensor_hub_get_feature()
266 ret = -EINVAL; in sensor_hub_get_feature()
271 val_ptr = (u8 *)report->field[field_index]->value; in sensor_hub_get_feature()
272 for (i = 0; i < report->field[field_index]->report_count; ++i) { in sensor_hub_get_feature()
277 report->field[field_index]->report_size / 8); in sensor_hub_get_feature()
279 buffer_index += (report->field[field_index]->report_size / 8); in sensor_hub_get_feature()
283 mutex_unlock(&data->mutex); in sensor_hub_get_feature()
296 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); in sensor_hub_input_attr_get_raw_value()
301 report = sensor_hub_report(report_id, hsdev->hdev, in sensor_hub_input_attr_get_raw_value()
304 return -EINVAL; in sensor_hub_input_attr_get_raw_value()
306 mutex_lock(hsdev->mutex_ptr); in sensor_hub_input_attr_get_raw_value()
308 memset(&hsdev->pending, 0, sizeof(hsdev->pending)); in sensor_hub_input_attr_get_raw_value()
309 init_completion(&hsdev->pending.ready); in sensor_hub_input_attr_get_raw_value()
310 hsdev->pending.usage_id = usage_id; in sensor_hub_input_attr_get_raw_value()
311 hsdev->pending.attr_usage_id = attr_usage_id; in sensor_hub_input_attr_get_raw_value()
312 hsdev->pending.raw_size = 0; in sensor_hub_input_attr_get_raw_value()
314 spin_lock_irqsave(&data->lock, flags); in sensor_hub_input_attr_get_raw_value()
315 hsdev->pending.status = true; in sensor_hub_input_attr_get_raw_value()
316 spin_unlock_irqrestore(&data->lock, flags); in sensor_hub_input_attr_get_raw_value()
318 mutex_lock(&data->mutex); in sensor_hub_input_attr_get_raw_value()
319 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); in sensor_hub_input_attr_get_raw_value()
320 mutex_unlock(&data->mutex); in sensor_hub_input_attr_get_raw_value()
323 &hsdev->pending.ready, HZ*5); in sensor_hub_input_attr_get_raw_value()
324 switch (hsdev->pending.raw_size) { in sensor_hub_input_attr_get_raw_value()
327 ret_val = *(s8 *)hsdev->pending.raw_data; in sensor_hub_input_attr_get_raw_value()
329 ret_val = *(u8 *)hsdev->pending.raw_data; in sensor_hub_input_attr_get_raw_value()
333 ret_val = *(s16 *)hsdev->pending.raw_data; in sensor_hub_input_attr_get_raw_value()
335 ret_val = *(u16 *)hsdev->pending.raw_data; in sensor_hub_input_attr_get_raw_value()
338 ret_val = *(u32 *)hsdev->pending.raw_data; in sensor_hub_input_attr_get_raw_value()
343 kfree(hsdev->pending.raw_data); in sensor_hub_input_attr_get_raw_value()
344 hsdev->pending.status = false; in sensor_hub_input_attr_get_raw_value()
346 mutex_unlock(hsdev->mutex_ptr); in sensor_hub_input_attr_get_raw_value()
359 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); in hid_sensor_get_usage_index()
360 if (!report || (field_index >= report->maxfield)) in hid_sensor_get_usage_index()
363 field = report->field[field_index]; in hid_sensor_get_usage_index()
364 for (i = 0; i < field->maxusage; ++i) { in hid_sensor_get_usage_index()
365 if (field->usage[i].hid == usage_id) in hid_sensor_get_usage_index()
366 return field->usage[i].usage_index; in hid_sensor_get_usage_index()
370 return -EINVAL; in hid_sensor_get_usage_index()
380 int ret = -1; in sensor_hub_input_get_attribute_info()
385 struct hid_device *hdev = hsdev->hdev; in sensor_hub_input_get_attribute_info()
388 info->usage_id = usage_id; in sensor_hub_input_get_attribute_info()
389 info->attrib_id = attr_usage_id; in sensor_hub_input_get_attribute_info()
390 info->report_id = -1; in sensor_hub_input_get_attribute_info()
391 info->index = -1; in sensor_hub_input_get_attribute_info()
392 info->units = -1; in sensor_hub_input_get_attribute_info()
393 info->unit_expo = -1; in sensor_hub_input_get_attribute_info()
395 report_enum = &hdev->report_enum[type]; in sensor_hub_input_get_attribute_info()
396 list_for_each_entry(report, &report_enum->report_list, list) { in sensor_hub_input_get_attribute_info()
397 for (i = 0; i < report->maxfield; ++i) { in sensor_hub_input_get_attribute_info()
398 field = report->field[i]; in sensor_hub_input_get_attribute_info()
399 if (field->maxusage) { in sensor_hub_input_get_attribute_info()
400 if ((field->physical == usage_id || in sensor_hub_input_get_attribute_info()
401 field->application == usage_id) && in sensor_hub_input_get_attribute_info()
402 (field->logical == attr_usage_id || in sensor_hub_input_get_attribute_info()
403 field->usage[0].hid == in sensor_hub_input_get_attribute_info()
405 (field->usage[0].collection_index >= in sensor_hub_input_get_attribute_info()
406 hsdev->start_collection_index) && in sensor_hub_input_get_attribute_info()
407 (field->usage[0].collection_index < in sensor_hub_input_get_attribute_info()
408 hsdev->end_collection_index)) { in sensor_hub_input_get_attribute_info()
411 report->id, in sensor_hub_input_get_attribute_info()
433 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); in sensor_hub_suspend()
434 list_for_each_entry(callback, &pdata->dyn_callback_list, list) { in sensor_hub_suspend()
435 if (callback->usage_callback->suspend) in sensor_hub_suspend()
436 callback->usage_callback->suspend( in sensor_hub_suspend()
437 callback->hsdev, callback->priv); in sensor_hub_suspend()
439 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_suspend()
451 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); in sensor_hub_resume()
452 list_for_each_entry(callback, &pdata->dyn_callback_list, list) { in sensor_hub_resume()
453 if (callback->usage_callback->resume) in sensor_hub_resume()
454 callback->usage_callback->resume( in sensor_hub_resume()
455 callback->hsdev, callback->priv); in sensor_hub_resume()
457 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); in sensor_hub_resume()
485 report->id, size, report->type); in sensor_hub_raw_event()
486 hid_dbg(hdev, "maxfield:%d\n", report->maxfield); in sensor_hub_raw_event()
487 if (report->type != HID_INPUT_REPORT) in sensor_hub_raw_event()
491 if (report->id) in sensor_hub_raw_event()
494 spin_lock_irqsave(&pdata->lock, flags); in sensor_hub_raw_event()
496 for (i = 0; i < report->maxfield; ++i) { in sensor_hub_raw_event()
498 i, report->field[i]->usage->collection_index, in sensor_hub_raw_event()
499 report->field[i]->usage->hid, in sensor_hub_raw_event()
500 (report->field[i]->report_size * in sensor_hub_raw_event()
501 report->field[i]->report_count)/8); in sensor_hub_raw_event()
502 sz = (report->field[i]->report_size * in sensor_hub_raw_event()
503 report->field[i]->report_count)/8; in sensor_hub_raw_event()
504 collection = &hdev->collection[ in sensor_hub_raw_event()
505 report->field[i]->usage->collection_index]; in sensor_hub_raw_event()
506 hid_dbg(hdev, "collection->usage %x\n", in sensor_hub_raw_event()
507 collection->usage); in sensor_hub_raw_event()
510 report->field[i]->physical ? report->field[i]->physical : in sensor_hub_raw_event()
511 report->field[i]->application, in sensor_hub_raw_event()
512 report->field[i]->usage[0].collection_index, in sensor_hub_raw_event()
518 if (hsdev->pending.status && (hsdev->pending.attr_usage_id == in sensor_hub_raw_event()
519 report->field[i]->usage->hid || in sensor_hub_raw_event()
520 hsdev->pending.attr_usage_id == in sensor_hub_raw_event()
521 report->field[i]->logical)) { in sensor_hub_raw_event()
523 hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC); in sensor_hub_raw_event()
524 if (hsdev->pending.raw_data) in sensor_hub_raw_event()
525 hsdev->pending.raw_size = sz; in sensor_hub_raw_event()
527 hsdev->pending.raw_size = 0; in sensor_hub_raw_event()
528 complete(&hsdev->pending.ready); in sensor_hub_raw_event()
530 if (callback->capture_sample) { in sensor_hub_raw_event()
531 if (report->field[i]->logical) in sensor_hub_raw_event()
532 callback->capture_sample(hsdev, in sensor_hub_raw_event()
533 report->field[i]->logical, sz, ptr, in sensor_hub_raw_event()
534 callback->pdev); in sensor_hub_raw_event()
536 callback->capture_sample(hsdev, in sensor_hub_raw_event()
537 report->field[i]->usage->hid, sz, ptr, in sensor_hub_raw_event()
538 callback->pdev); in sensor_hub_raw_event()
542 if (callback && collection && callback->send_event) in sensor_hub_raw_event()
543 callback->send_event(hsdev, collection->usage, in sensor_hub_raw_event()
544 callback->pdev); in sensor_hub_raw_event()
545 spin_unlock_irqrestore(&pdata->lock, flags); in sensor_hub_raw_event()
553 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); in sensor_hub_device_open()
555 mutex_lock(&data->mutex); in sensor_hub_device_open()
556 if (!data->ref_cnt) { in sensor_hub_device_open()
557 ret = hid_hw_open(hsdev->hdev); in sensor_hub_device_open()
559 hid_err(hsdev->hdev, "failed to open hid device\n"); in sensor_hub_device_open()
560 mutex_unlock(&data->mutex); in sensor_hub_device_open()
564 data->ref_cnt++; in sensor_hub_device_open()
565 mutex_unlock(&data->mutex); in sensor_hub_device_open()
573 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); in sensor_hub_device_close()
575 mutex_lock(&data->mutex); in sensor_hub_device_close()
576 data->ref_cnt--; in sensor_hub_device_close()
577 if (!data->ref_cnt) in sensor_hub_device_close()
578 hid_hw_close(hsdev->hdev); in sensor_hub_device_close()
579 mutex_unlock(&data->mutex); in sensor_hub_device_close()
590 if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA && in sensor_hub_report_fixup()
617 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); in sensor_hub_probe()
619 hid_err(hdev, "cannot allocate Sensor data\n"); in sensor_hub_probe()
620 return -ENOMEM; in sensor_hub_probe()
625 spin_lock_init(&sd->lock); in sensor_hub_probe()
626 spin_lock_init(&sd->dyn_callback_lock); in sensor_hub_probe()
627 mutex_init(&sd->mutex); in sensor_hub_probe()
633 INIT_LIST_HEAD(&hdev->inputs); in sensor_hub_probe()
640 INIT_LIST_HEAD(&sd->dyn_callback_list); in sensor_hub_probe()
641 sd->hid_sensor_client_cnt = 0; in sensor_hub_probe()
646 ret = -EINVAL; in sensor_hub_probe()
649 sd->hid_sensor_hub_client_devs = devm_kcalloc(&hdev->dev, in sensor_hub_probe()
653 if (sd->hid_sensor_hub_client_devs == NULL) { in sensor_hub_probe()
655 ret = -ENOMEM; in sensor_hub_probe()
659 for (i = 0; i < hdev->maxcollection; ++i) { in sensor_hub_probe()
660 struct hid_collection *collection = &hdev->collection[i]; in sensor_hub_probe()
662 if (collection->type == HID_COLLECTION_PHYSICAL || in sensor_hub_probe()
663 collection->type == HID_COLLECTION_APPLICATION) { in sensor_hub_probe()
665 hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), in sensor_hub_probe()
669 ret = -ENOMEM; in sensor_hub_probe()
672 hsdev->hdev = hdev; in sensor_hub_probe()
673 hsdev->vendor_id = hdev->vendor; in sensor_hub_probe()
674 hsdev->product_id = hdev->product; in sensor_hub_probe()
675 hsdev->usage = collection->usage; in sensor_hub_probe()
676 hsdev->mutex_ptr = devm_kzalloc(&hdev->dev, in sensor_hub_probe()
679 if (!hsdev->mutex_ptr) { in sensor_hub_probe()
680 ret = -ENOMEM; in sensor_hub_probe()
683 mutex_init(hsdev->mutex_ptr); in sensor_hub_probe()
684 hsdev->start_collection_index = i; in sensor_hub_probe()
686 last_hsdev->end_collection_index = i; in sensor_hub_probe()
688 name = devm_kasprintf(&hdev->dev, GFP_KERNEL, in sensor_hub_probe()
689 "HID-SENSOR-%x", in sensor_hub_probe()
690 collection->usage); in sensor_hub_probe()
693 ret = -ENOMEM; in sensor_hub_probe()
696 sd->hid_sensor_hub_client_devs[ in sensor_hub_probe()
697 sd->hid_sensor_client_cnt].name = name; in sensor_hub_probe()
698 sd->hid_sensor_hub_client_devs[ in sensor_hub_probe()
699 sd->hid_sensor_client_cnt].platform_data = in sensor_hub_probe()
701 sd->hid_sensor_hub_client_devs[ in sensor_hub_probe()
702 sd->hid_sensor_client_cnt].pdata_size = in sensor_hub_probe()
705 hsdev->start_collection_index); in sensor_hub_probe()
706 sd->hid_sensor_client_cnt++; in sensor_hub_probe()
708 collection_hsdev->end_collection_index = i; in sensor_hub_probe()
709 if (collection->type == HID_COLLECTION_APPLICATION && in sensor_hub_probe()
710 collection->usage == HID_USAGE_SENSOR_COLLECTION) in sensor_hub_probe()
715 last_hsdev->end_collection_index = i; in sensor_hub_probe()
717 collection_hsdev->end_collection_index = i; in sensor_hub_probe()
719 ret = mfd_add_hotplug_devices(&hdev->dev, in sensor_hub_probe()
720 sd->hid_sensor_hub_client_devs, in sensor_hub_probe()
721 sd->hid_sensor_client_cnt); in sensor_hub_probe()
742 spin_lock_irqsave(&data->lock, flags); in sensor_hub_remove()
743 for (i = 0; i < data->hid_sensor_client_cnt; ++i) { in sensor_hub_remove()
745 data->hid_sensor_hub_client_devs[i].platform_data; in sensor_hub_remove()
746 if (hsdev->pending.status) in sensor_hub_remove()
747 complete(&hsdev->pending.ready); in sensor_hub_remove()
749 spin_unlock_irqrestore(&data->lock, flags); in sensor_hub_remove()
750 mfd_remove_devices(&hdev->dev); in sensor_hub_remove()
751 mutex_destroy(&data->mutex); in sensor_hub_remove()
762 .name = "hid-sensor-hub",
776 MODULE_DESCRIPTION("HID Sensor Hub driver");