Lines Matching +full:power +full:- +full:friendly

1 // SPDX-License-Identifier: GPL-2.0-only
3 * hid-sensor-custom.c
19 #include <linux/hid-sensor-hub.h>
69 {.name = "unit-expo", .mode = S_IRUGO},
81 {0x200201, "event-sensor-state"},
82 {0x200202, "event-sensor-event"},
83 {0x200301, "property-friendly-name"},
84 {0x200302, "property-persistent-unique-id"},
85 {0x200303, "property-sensor-status"},
86 {0x200304, "property-min-report-interval"},
87 {0x200305, "property-sensor-manufacturer"},
88 {0x200306, "property-sensor-model"},
89 {0x200307, "property-sensor-serial-number"},
90 {0x200308, "property-sensor-description"},
91 {0x200309, "property-sensor-connection-type"},
92 {0x20030A, "property-sensor-device-path"},
93 {0x20030B, "property-hardware-revision"},
94 {0x20030C, "property-firmware-version"},
95 {0x20030D, "property-release-date"},
96 {0x20030E, "property-report-interval"},
97 {0x20030F, "property-change-sensitivity-absolute"},
98 {0x200310, "property-change-sensitivity-percent-range"},
99 {0x200311, "property-change-sensitivity-percent-relative"},
100 {0x200312, "property-accuracy"},
101 {0x200313, "property-resolution"},
102 {0x200314, "property-maximum"},
103 {0x200315, "property-minimum"},
104 {0x200316, "property-reporting-state"},
105 {0x200317, "property-sampling-rate"},
106 {0x200318, "property-response-curve"},
107 {0x200319, "property-power-state"},
108 {0x200540, "data-field-custom"},
109 {0x200541, "data-field-custom-usage"},
110 {0x200542, "data-field-custom-boolean-array"},
111 {0x200543, "data-field-custom-value"},
112 {0x200544, "data-field-custom-value_1"},
113 {0x200545, "data-field-custom-value_2"},
114 {0x200546, "data-field-custom-value_3"},
115 {0x200547, "data-field-custom-value_4"},
116 {0x200548, "data-field-custom-value_5"},
117 {0x200549, "data-field-custom-value_6"},
118 {0x20054A, "data-field-custom-value_7"},
119 {0x20054B, "data-field-custom-value_8"},
120 {0x20054C, "data-field-custom-value_9"},
121 {0x20054D, "data-field-custom-value_10"},
122 {0x20054E, "data-field-custom-value_11"},
123 {0x20054F, "data-field-custom-value_12"},
124 {0x200550, "data-field-custom-value_13"},
125 {0x200551, "data-field-custom-value_14"},
126 {0x200552, "data-field-custom-value_15"},
127 {0x200553, "data-field-custom-value_16"},
128 {0x200554, "data-field-custom-value_17"},
129 {0x200555, "data-field-custom-value_18"},
130 {0x200556, "data-field-custom-value_19"},
131 {0x200557, "data-field-custom-value_20"},
132 {0x200558, "data-field-custom-value_21"},
133 {0x200559, "data-field-custom-value_22"},
134 {0x20055A, "data-field-custom-value_23"},
135 {0x20055B, "data-field-custom-value_24"},
136 {0x20055C, "data-field-custom-value_25"},
137 {0x20055D, "data-field-custom-value_26"},
138 {0x20055E, "data-field-custom-value_27"},
139 {0x20055F, "data-field-custom-value_28"},
145 return -1; in usage_id_cmp()
158 return sysfs_emit(buf, "%d\n", sensor_inst->enable); in enable_sensor_show()
164 int power_val = -1; in set_power_report_state()
165 int report_val = -1; in set_power_report_state()
171 * It is possible that the power/report state ids are not present. in set_power_report_state()
187 if (sensor_inst->power_state) in set_power_report_state()
188 power_val = hid_sensor_get_usage_index(sensor_inst->hsdev, in set_power_report_state()
189 sensor_inst->power_state->attribute.report_id, in set_power_report_state()
190 sensor_inst->power_state->attribute.index, in set_power_report_state()
192 if (sensor_inst->report_state) in set_power_report_state()
193 report_val = hid_sensor_get_usage_index(sensor_inst->hsdev, in set_power_report_state()
194 sensor_inst->report_state->attribute.report_id, in set_power_report_state()
195 sensor_inst->report_state->attribute.index, in set_power_report_state()
200 sensor_inst->power_state->attribute.logical_minimum; in set_power_report_state()
201 ret = sensor_hub_set_feature(sensor_inst->hsdev, in set_power_report_state()
202 sensor_inst->power_state->attribute.report_id, in set_power_report_state()
203 sensor_inst->power_state->attribute.index, in set_power_report_state()
207 hid_err(sensor_inst->hsdev->hdev, in set_power_report_state()
208 "Set power state failed\n"); in set_power_report_state()
215 sensor_inst->report_state->attribute.logical_minimum; in set_power_report_state()
216 ret = sensor_hub_set_feature(sensor_inst->hsdev, in set_power_report_state()
217 sensor_inst->report_state->attribute.report_id, in set_power_report_state()
218 sensor_inst->report_state->attribute.index, in set_power_report_state()
222 hid_err(sensor_inst->hsdev->hdev, in set_power_report_state()
237 int ret = -EINVAL; in enable_sensor_store()
240 return -EINVAL; in enable_sensor_store()
242 mutex_lock(&sensor_inst->mutex); in enable_sensor_store()
243 if (value && !sensor_inst->enable) { in enable_sensor_store()
244 ret = sensor_hub_device_open(sensor_inst->hsdev); in enable_sensor_store()
250 sensor_hub_device_close(sensor_inst->hsdev); in enable_sensor_store()
253 sensor_inst->enable = true; in enable_sensor_store()
254 } else if (!value && sensor_inst->enable) { in enable_sensor_store()
256 sensor_hub_device_close(sensor_inst->hsdev); in enable_sensor_store()
257 sensor_inst->enable = false; in enable_sensor_store()
260 mutex_unlock(&sensor_inst->mutex); in enable_sensor_store()
288 if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage, in show_value()
291 field_index = index + sensor_inst->input_field_count; in show_value()
292 } else if (sscanf(attr->attr.name, "input-%x-%x-%s", &index, &usage, in show_value()
297 return -EINVAL; in show_value()
303 attribute = &sensor_inst->fields[field_index].attribute; in show_value()
304 report_id = attribute->report_id; in show_value()
311 ret = sensor_hub_get_feature(sensor_inst->hsdev, in show_value()
319 if (i + attribute->size > ret) { in show_value()
321 PAGE_SIZE - len, in show_value()
325 switch (attribute->size) { in show_value()
328 i += attribute->size; in show_value()
332 i += attribute->size; in show_value()
336 i += attribute->size; in show_value()
343 len += scnprintf(&buf[len], PAGE_SIZE - len, in show_value()
346 len += scnprintf(&buf[len], PAGE_SIZE - len, "\n"); in show_value()
351 sensor_inst->hsdev, in show_value()
352 sensor_inst->hsdev->usage, in show_value()
356 value = sensor_inst->fields[field_index].attribute.units; in show_value()
357 else if (!strncmp(name, "unit-expo", strlen("unit-expo"))) in show_value()
358 value = sensor_inst->fields[field_index].attribute.unit_expo; in show_value()
360 value = sensor_inst->fields[field_index].attribute.size; in show_value()
362 value = sensor_inst->fields[field_index].attribute. in show_value()
365 value = sensor_inst->fields[field_index].attribute. in show_value()
375 return sysfs_emit(buf, "%s\n", usage_desc->desc); in show_value()
377 return sysfs_emit(buf, "not-specified\n"); in show_value()
379 return -EINVAL; in show_value()
392 if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage, in store_value()
394 field_index = index + sensor_inst->input_field_count; in store_value()
396 return -EINVAL; in store_value()
402 return -EINVAL; in store_value()
404 report_id = sensor_inst->fields[field_index].attribute. in store_value()
406 ret = sensor_hub_set_feature(sensor_inst->hsdev, report_id, in store_value()
411 return -EINVAL; in store_value()
424 if (sensor_inst->input_skip_sample) { in hid_sensor_capture_sample()
425 hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n"); in hid_sensor_capture_sample()
429 hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__, in hid_sensor_capture_sample()
430 (int) (sensor_inst->input_report_recd_size + raw_len), in hid_sensor_capture_sample()
431 sensor_inst->input_report_size); in hid_sensor_capture_sample()
433 if (!test_bit(0, &sensor_inst->misc_opened)) in hid_sensor_capture_sample()
436 if (!sensor_inst->input_report_recd_size) { in hid_sensor_capture_sample()
438 sensor_inst->input_report_size; in hid_sensor_capture_sample()
439 header.usage_id = hsdev->usage; in hid_sensor_capture_sample()
440 header.raw_len = sensor_inst->input_report_size; in hid_sensor_capture_sample()
442 if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) { in hid_sensor_capture_sample()
443 kfifo_in(&sensor_inst->data_fifo, in hid_sensor_capture_sample()
447 sensor_inst->input_skip_sample = true; in hid_sensor_capture_sample()
449 if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len) in hid_sensor_capture_sample()
450 kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data, in hid_sensor_capture_sample()
453 sensor_inst->input_report_recd_size += raw_len; in hid_sensor_capture_sample()
463 if (!test_bit(0, &sensor_inst->misc_opened)) in hid_sensor_send_event()
466 sensor_inst->input_report_recd_size = 0; in hid_sensor_send_event()
467 sensor_inst->input_skip_sample = false; in hid_sensor_send_event()
469 wake_up(&sensor_inst->wait); in hid_sensor_send_event()
482 fields = krealloc(sensor_inst->fields, in hid_sensor_custom_add_field()
483 (sensor_inst->sensor_field_count + 1) * in hid_sensor_custom_add_field()
486 kfree(sensor_inst->fields); in hid_sensor_custom_add_field()
487 return -ENOMEM; in hid_sensor_custom_add_field()
489 sensor_inst->fields = fields; in hid_sensor_custom_add_field()
490 sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count]; in hid_sensor_custom_add_field()
491 sensor_field->attribute.usage_id = sensor_inst->hsdev->usage; in hid_sensor_custom_add_field()
492 if (field->logical) in hid_sensor_custom_add_field()
493 sensor_field->attribute.attrib_id = field->logical; in hid_sensor_custom_add_field()
495 sensor_field->attribute.attrib_id = field->usage[0].hid; in hid_sensor_custom_add_field()
497 sensor_field->attribute.index = index; in hid_sensor_custom_add_field()
498 sensor_field->attribute.report_id = report->id; in hid_sensor_custom_add_field()
499 sensor_field->attribute.units = field->unit; in hid_sensor_custom_add_field()
500 sensor_field->attribute.unit_expo = field->unit_exponent; in hid_sensor_custom_add_field()
501 sensor_field->attribute.size = (field->report_size / 8); in hid_sensor_custom_add_field()
502 sensor_field->attribute.logical_minimum = field->logical_minimum; in hid_sensor_custom_add_field()
503 sensor_field->attribute.logical_maximum = field->logical_maximum; in hid_sensor_custom_add_field()
506 snprintf(sensor_field->group_name, in hid_sensor_custom_add_field()
507 sizeof(sensor_field->group_name), "feature-%x-%x", in hid_sensor_custom_add_field()
508 sensor_field->attribute.index, in hid_sensor_custom_add_field()
509 sensor_field->attribute.attrib_id); in hid_sensor_custom_add_field()
511 snprintf(sensor_field->group_name, in hid_sensor_custom_add_field()
512 sizeof(sensor_field->group_name), in hid_sensor_custom_add_field()
513 "input-%x-%x", sensor_field->attribute.index, in hid_sensor_custom_add_field()
514 sensor_field->attribute.attrib_id); in hid_sensor_custom_add_field()
515 sensor_inst->input_field_count++; in hid_sensor_custom_add_field()
516 sensor_inst->input_report_size += (field->report_size * in hid_sensor_custom_add_field()
517 field->report_count) / 8; in hid_sensor_custom_add_field()
520 memset(&sensor_field->hid_custom_attribute_group, 0, in hid_sensor_custom_add_field()
522 sensor_inst->sensor_field_count++; in hid_sensor_custom_add_field()
535 struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; in hid_sensor_custom_add_fields()
537 list_for_each_entry(report, &report_enum->report_list, list) { in hid_sensor_custom_add_fields()
538 for (i = 0; i < report->maxfield; ++i) { in hid_sensor_custom_add_fields()
539 field = report->field[i]; in hid_sensor_custom_add_fields()
540 if (field->maxusage && in hid_sensor_custom_add_fields()
541 ((field->usage[0].collection_index >= in hid_sensor_custom_add_fields()
542 hsdev->start_collection_index) && in hid_sensor_custom_add_fields()
543 (field->usage[0].collection_index < in hid_sensor_custom_add_fields()
544 hsdev->end_collection_index))) { in hid_sensor_custom_add_fields()
564 struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; in hid_sensor_custom_add_attributes()
565 struct hid_device *hdev = hsdev->hdev; in hid_sensor_custom_add_attributes()
566 int ret = -1; in hid_sensor_custom_add_attributes()
574 &hdev->report_enum[j], j); in hid_sensor_custom_add_attributes()
581 for (i = 0; i < sensor_inst->sensor_field_count; ++i) { in hid_sensor_custom_add_attributes()
587 device_attr = &sensor_inst->fields[i].sd_attrs[j]; in hid_sensor_custom_add_attributes()
589 snprintf((char *)&sensor_inst->fields[i].attr_name[j], in hid_sensor_custom_add_attributes()
590 HID_CUSTOM_NAME_LENGTH, "%s-%s", in hid_sensor_custom_add_attributes()
591 sensor_inst->fields[i].group_name, in hid_sensor_custom_add_attributes()
593 sysfs_attr_init(&device_attr->attr); in hid_sensor_custom_add_attributes()
594 device_attr->attr.name = in hid_sensor_custom_add_attributes()
595 (char *)&sensor_inst->fields[i].attr_name[j]; in hid_sensor_custom_add_attributes()
596 device_attr->attr.mode = hid_custom_attrs[j].mode; in hid_sensor_custom_add_attributes()
597 device_attr->show = show_value; in hid_sensor_custom_add_attributes()
599 device_attr->store = store_value; in hid_sensor_custom_add_attributes()
600 sensor_inst->fields[i].attrs[j] = &device_attr->attr; in hid_sensor_custom_add_attributes()
603 sensor_inst->fields[i].attrs[j] = NULL; in hid_sensor_custom_add_attributes()
604 sensor_inst->fields[i].hid_custom_attribute_group.attrs = in hid_sensor_custom_add_attributes()
605 sensor_inst->fields[i].attrs; in hid_sensor_custom_add_attributes()
606 sensor_inst->fields[i].hid_custom_attribute_group.name = in hid_sensor_custom_add_attributes()
607 sensor_inst->fields[i].group_name; in hid_sensor_custom_add_attributes()
608 ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, in hid_sensor_custom_add_attributes()
609 &sensor_inst->fields[i]. in hid_sensor_custom_add_attributes()
614 /* For power or report field store indexes */ in hid_sensor_custom_add_attributes()
615 if (sensor_inst->fields[i].attribute.attrib_id == in hid_sensor_custom_add_attributes()
617 sensor_inst->power_state = &sensor_inst->fields[i]; in hid_sensor_custom_add_attributes()
618 else if (sensor_inst->fields[i].attribute.attrib_id == in hid_sensor_custom_add_attributes()
620 sensor_inst->report_state = &sensor_inst->fields[i]; in hid_sensor_custom_add_attributes()
631 for (i = 0; i < sensor_inst->sensor_field_count; ++i) in hid_sensor_custom_remove_attributes()
632 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, in hid_sensor_custom_remove_attributes()
633 &sensor_inst->fields[i]. in hid_sensor_custom_remove_attributes()
636 kfree(sensor_inst->fields); in hid_sensor_custom_remove_attributes()
646 sensor_inst = container_of(file->private_data, in hid_sensor_custom_read()
650 return -EINVAL; in hid_sensor_custom_read()
653 if (kfifo_is_empty(&sensor_inst->data_fifo)) { in hid_sensor_custom_read()
654 if (file->f_flags & O_NONBLOCK) in hid_sensor_custom_read()
655 return -EAGAIN; in hid_sensor_custom_read()
657 ret = wait_event_interruptible(sensor_inst->wait, in hid_sensor_custom_read()
658 !kfifo_is_empty(&sensor_inst->data_fifo)); in hid_sensor_custom_read()
662 ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count, in hid_sensor_custom_read()
676 sensor_inst = container_of(file->private_data, in hid_sensor_custom_release()
679 clear_bit(0, &sensor_inst->misc_opened); in hid_sensor_custom_release()
688 sensor_inst = container_of(file->private_data, in hid_sensor_custom_open()
691 if (test_and_set_bit(0, &sensor_inst->misc_opened)) in hid_sensor_custom_open()
692 return -EBUSY; in hid_sensor_custom_open()
703 sensor_inst = container_of(file->private_data, in hid_sensor_custom_poll()
706 poll_wait(file, &sensor_inst->wait, wait); in hid_sensor_custom_poll()
708 if (!kfifo_is_empty(&sensor_inst->data_fifo)) in hid_sensor_custom_poll()
726 ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE, in hid_sensor_custom_dev_if_add()
731 init_waitqueue_head(&sensor_inst->wait); in hid_sensor_custom_dev_if_add()
733 sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR; in hid_sensor_custom_dev_if_add()
734 sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev); in hid_sensor_custom_dev_if_add()
735 sensor_inst->custom_dev.fops = &hid_sensor_custom_fops; in hid_sensor_custom_dev_if_add()
736 ret = misc_register(&sensor_inst->custom_dev); in hid_sensor_custom_dev_if_add()
738 kfifo_free(&sensor_inst->data_fifo); in hid_sensor_custom_dev_if_add()
747 wake_up(&sensor_inst->wait); in hid_sensor_custom_dev_if_remove()
748 misc_deregister(&sensor_inst->custom_dev); in hid_sensor_custom_dev_if_remove()
749 kfifo_free(&sensor_inst->data_fifo); in hid_sensor_custom_dev_if_remove()
813 while (count-- && *prop && *match) { in hid_sensor_custom_prop_match_str()
820 return (count == -1) || *prop == (u16)*match; in hid_sensor_custom_prop_match_str()
833 hsdev->usage, prop_usage_id, in hid_sensor_custom_get_prop()
841 hid_err(hsdev->hdev, "Failed to get sensor property %08x %d\n", in hid_sensor_custom_get_prop()
854 struct dmi_system_id dmi[] = { match->dmi, { 0 } }; in hid_sensor_custom_do_match()
856 if (!hid_sensor_custom_prop_match_str(prop->serial_num, "LUID:", 5) || in hid_sensor_custom_do_match()
857 !hid_sensor_custom_prop_match_str(prop->serial_num + 5, match->luid, in hid_sensor_custom_do_match()
858 HID_CUSTOM_MAX_FEATURE_BYTES - 5)) in hid_sensor_custom_do_match()
861 if (match->model && in hid_sensor_custom_do_match()
862 !hid_sensor_custom_prop_match_str(prop->model, match->model, in hid_sensor_custom_do_match()
866 if (match->manufacturer && in hid_sensor_custom_do_match()
867 !hid_sensor_custom_prop_match_str(prop->manufacturer, match->manufacturer, in hid_sensor_custom_do_match()
871 if (match->check_dmi && !dmi_check_system(dmi)) in hid_sensor_custom_do_match()
886 prop->serial_num); in hid_sensor_custom_properties_get()
897 prop->model); in hid_sensor_custom_properties_get()
901 prop->manufacturer); in hid_sensor_custom_properties_get()
917 return -ENOMEM; in hid_sensor_custom_get_known()
923 while (match->tag) { in hid_sensor_custom_get_known()
931 ret = -ENODATA; in hid_sensor_custom_get_known()
947 memcpy(real_usage, match->luid, 4); in hid_sensor_register_platform_device()
953 /* HID-SENSOR-TAG-REAL_USAGE_ID */ in hid_sensor_register_platform_device()
954 dev_name = kasprintf(GFP_KERNEL, "HID-SENSOR-%s-%s", in hid_sensor_register_platform_device()
955 match->tag, real_usage); in hid_sensor_register_platform_device()
957 return ERR_PTR(-ENOMEM); in hid_sensor_register_platform_device()
959 custom_pdev = platform_device_register_data(pdev->dev.parent, dev_name, in hid_sensor_register_platform_device()
969 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; in hid_sensor_custom_probe()
973 sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst), in hid_sensor_custom_probe()
976 return -ENOMEM; in hid_sensor_custom_probe()
978 sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample; in hid_sensor_custom_probe()
979 sensor_inst->callbacks.send_event = hid_sensor_send_event; in hid_sensor_custom_probe()
980 sensor_inst->callbacks.pdev = pdev; in hid_sensor_custom_probe()
981 sensor_inst->hsdev = hsdev; in hid_sensor_custom_probe()
982 sensor_inst->pdev = pdev; in hid_sensor_custom_probe()
983 mutex_init(&sensor_inst->mutex); in hid_sensor_custom_probe()
988 sensor_inst->custom_pdev = in hid_sensor_custom_probe()
991 ret = PTR_ERR_OR_ZERO(sensor_inst->custom_pdev); in hid_sensor_custom_probe()
993 dev_err(&pdev->dev, in hid_sensor_custom_probe()
1001 ret = sensor_hub_register_callback(hsdev, hsdev->usage, in hid_sensor_custom_probe()
1002 &sensor_inst->callbacks); in hid_sensor_custom_probe()
1004 dev_err(&pdev->dev, "callback reg failed\n"); in hid_sensor_custom_probe()
1008 ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, in hid_sensor_custom_probe()
1026 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, in hid_sensor_custom_probe()
1029 sensor_hub_remove_callback(hsdev, hsdev->usage); in hid_sensor_custom_probe()
1037 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; in hid_sensor_custom_remove()
1039 if (sensor_inst->custom_pdev) { in hid_sensor_custom_remove()
1040 platform_device_unregister(sensor_inst->custom_pdev); in hid_sensor_custom_remove()
1046 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, in hid_sensor_custom_remove()
1048 sensor_hub_remove_callback(hsdev, hsdev->usage); in hid_sensor_custom_remove()
1053 .name = "HID-SENSOR-2000e1",
1056 .name = "HID-SENSOR-2000e2",