1/* 2 * hid-sensor-custom.c 3 * Copyright (c) 2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/init.h> 18#include <linux/miscdevice.h> 19#include <linux/kfifo.h> 20#include <linux/sched.h> 21#include <linux/wait.h> 22#include <linux/poll.h> 23#include <linux/bsearch.h> 24#include <linux/platform_device.h> 25#include <linux/hid-sensor-hub.h> 26 27#define HID_CUSTOM_NAME_LENGTH 64 28#define HID_CUSTOM_MAX_CORE_ATTRS 10 29#define HID_CUSTOM_TOTAL_ATTRS (HID_CUSTOM_MAX_CORE_ATTRS + 1) 30#define HID_CUSTOM_FIFO_SIZE 4096 31#define HID_CUSTOM_MAX_FEATURE_BYTES 64 32 33struct hid_sensor_custom_field { 34 int report_id; 35 char group_name[HID_CUSTOM_NAME_LENGTH]; 36 struct hid_sensor_hub_attribute_info attribute; 37 struct device_attribute sd_attrs[HID_CUSTOM_MAX_CORE_ATTRS]; 38 char attr_name[HID_CUSTOM_TOTAL_ATTRS][HID_CUSTOM_NAME_LENGTH]; 39 struct attribute *attrs[HID_CUSTOM_TOTAL_ATTRS]; 40 struct attribute_group hid_custom_attribute_group; 41}; 42 43struct hid_sensor_custom { 44 struct mutex mutex; 45 struct platform_device *pdev; 46 struct hid_sensor_hub_device *hsdev; 47 struct hid_sensor_hub_callbacks callbacks; 48 int sensor_field_count; 49 struct hid_sensor_custom_field *fields; 50 int input_field_count; 51 int input_report_size; 52 int input_report_recd_size; 53 bool input_skip_sample; 54 bool enable; 55 struct hid_sensor_custom_field *power_state; 56 struct hid_sensor_custom_field *report_state; 57 struct miscdevice custom_dev; 58 struct kfifo data_fifo; 59 unsigned long misc_opened; 60 wait_queue_head_t wait; 61}; 62 63/* Header for each sample to user space via dev interface */ 64struct hid_sensor_sample { 65 u32 usage_id; 66 u64 timestamp; 67 u32 raw_len; 68} __packed; 69 70static struct attribute hid_custom_attrs[] = { 71 {.name = "name", .mode = S_IRUGO}, 72 {.name = "units", .mode = S_IRUGO}, 73 {.name = "unit-expo", .mode = S_IRUGO}, 74 {.name = "minimum", .mode = S_IRUGO}, 75 {.name = "maximum", .mode = S_IRUGO}, 76 {.name = "size", .mode = S_IRUGO}, 77 {.name = "value", .mode = S_IWUSR | S_IRUGO}, 78 {.name = NULL} 79}; 80 81static const struct hid_custom_usage_desc { 82 int usage_id; 83 char *desc; 84} hid_custom_usage_desc_table[] = { 85 {0x200201, "event-sensor-state"}, 86 {0x200202, "event-sensor-event"}, 87 {0x200301, "property-friendly-name"}, 88 {0x200302, "property-persistent-unique-id"}, 89 {0x200303, "property-sensor-status"}, 90 {0x200304, "property-min-report-interval"}, 91 {0x200305, "property-sensor-manufacturer"}, 92 {0x200306, "property-sensor-model"}, 93 {0x200307, "property-sensor-serial-number"}, 94 {0x200308, "property-sensor-description"}, 95 {0x200309, "property-sensor-connection-type"}, 96 {0x20030A, "property-sensor-device-path"}, 97 {0x20030B, "property-hardware-revision"}, 98 {0x20030C, "property-firmware-version"}, 99 {0x20030D, "property-release-date"}, 100 {0x20030E, "property-report-interval"}, 101 {0x20030F, "property-change-sensitivity-absolute"}, 102 {0x200310, "property-change-sensitivity-percent-range"}, 103 {0x200311, "property-change-sensitivity-percent-relative"}, 104 {0x200312, "property-accuracy"}, 105 {0x200313, "property-resolution"}, 106 {0x200314, "property-maximum"}, 107 {0x200315, "property-minimum"}, 108 {0x200316, "property-reporting-state"}, 109 {0x200317, "property-sampling-rate"}, 110 {0x200318, "property-response-curve"}, 111 {0x200319, "property-power-state"}, 112 {0x200540, "data-field-custom"}, 113 {0x200541, "data-field-custom-usage"}, 114 {0x200542, "data-field-custom-boolean-array"}, 115 {0x200543, "data-field-custom-value"}, 116 {0x200544, "data-field-custom-value_1"}, 117 {0x200545, "data-field-custom-value_2"}, 118 {0x200546, "data-field-custom-value_3"}, 119 {0x200547, "data-field-custom-value_4"}, 120 {0x200548, "data-field-custom-value_5"}, 121 {0x200549, "data-field-custom-value_6"}, 122 {0x20054A, "data-field-custom-value_7"}, 123 {0x20054B, "data-field-custom-value_8"}, 124 {0x20054C, "data-field-custom-value_9"}, 125 {0x20054D, "data-field-custom-value_10"}, 126 {0x20054E, "data-field-custom-value_11"}, 127 {0x20054F, "data-field-custom-value_12"}, 128 {0x200550, "data-field-custom-value_13"}, 129 {0x200551, "data-field-custom-value_14"}, 130 {0x200552, "data-field-custom-value_15"}, 131 {0x200553, "data-field-custom-value_16"}, 132 {0x200554, "data-field-custom-value_17"}, 133 {0x200555, "data-field-custom-value_18"}, 134 {0x200556, "data-field-custom-value_19"}, 135 {0x200557, "data-field-custom-value_20"}, 136 {0x200558, "data-field-custom-value_21"}, 137 {0x200559, "data-field-custom-value_22"}, 138 {0x20055A, "data-field-custom-value_23"}, 139 {0x20055B, "data-field-custom-value_24"}, 140 {0x20055C, "data-field-custom-value_25"}, 141 {0x20055D, "data-field-custom-value_26"}, 142 {0x20055E, "data-field-custom-value_27"}, 143 {0x20055F, "data-field-custom-value_28"}, 144}; 145 146static int usage_id_cmp(const void *p1, const void *p2) 147{ 148 if (*(int *)p1 < *(int *)p2) 149 return -1; 150 151 if (*(int *)p1 > *(int *)p2) 152 return 1; 153 154 return 0; 155} 156 157static ssize_t enable_sensor_show(struct device *dev, 158 struct device_attribute *attr, char *buf) 159{ 160 struct platform_device *pdev = to_platform_device(dev); 161 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 162 163 return sprintf(buf, "%d\n", sensor_inst->enable); 164} 165 166static int set_power_report_state(struct hid_sensor_custom *sensor_inst, 167 bool state) 168{ 169 int power_val = -1; 170 int report_val = -1; 171 u32 power_state_usage_id; 172 u32 report_state_usage_id; 173 int ret; 174 175 /* 176 * It is possible that the power/report state ids are not present. 177 * In this case this function will return success. But if the 178 * ids are present, then it will return error if set fails. 179 */ 180 if (state) { 181 power_state_usage_id = 182 HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM; 183 report_state_usage_id = 184 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM; 185 } else { 186 power_state_usage_id = 187 HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM; 188 report_state_usage_id = 189 HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM; 190 } 191 192 if (sensor_inst->power_state) 193 power_val = hid_sensor_get_usage_index(sensor_inst->hsdev, 194 sensor_inst->power_state->attribute.report_id, 195 sensor_inst->power_state->attribute.index, 196 power_state_usage_id); 197 if (sensor_inst->report_state) 198 report_val = hid_sensor_get_usage_index(sensor_inst->hsdev, 199 sensor_inst->report_state->attribute.report_id, 200 sensor_inst->report_state->attribute.index, 201 report_state_usage_id); 202 203 if (power_val >= 0) { 204 power_val += 205 sensor_inst->power_state->attribute.logical_minimum; 206 ret = sensor_hub_set_feature(sensor_inst->hsdev, 207 sensor_inst->power_state->attribute.report_id, 208 sensor_inst->power_state->attribute.index, 209 sizeof(power_val), 210 &power_val); 211 if (ret) { 212 hid_err(sensor_inst->hsdev->hdev, 213 "Set power state failed\n"); 214 return ret; 215 } 216 } 217 218 if (report_val >= 0) { 219 report_val += 220 sensor_inst->report_state->attribute.logical_minimum; 221 ret = sensor_hub_set_feature(sensor_inst->hsdev, 222 sensor_inst->report_state->attribute.report_id, 223 sensor_inst->report_state->attribute.index, 224 sizeof(report_val), 225 &report_val); 226 if (ret) { 227 hid_err(sensor_inst->hsdev->hdev, 228 "Set report state failed\n"); 229 return ret; 230 } 231 } 232 233 return 0; 234} 235 236static ssize_t enable_sensor_store(struct device *dev, 237 struct device_attribute *attr, 238 const char *buf, size_t count) 239{ 240 struct platform_device *pdev = to_platform_device(dev); 241 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 242 int value; 243 int ret = -EINVAL; 244 245 if (kstrtoint(buf, 0, &value) != 0) 246 return -EINVAL; 247 248 mutex_lock(&sensor_inst->mutex); 249 if (value && !sensor_inst->enable) { 250 ret = sensor_hub_device_open(sensor_inst->hsdev); 251 if (ret) 252 goto unlock_state; 253 254 ret = set_power_report_state(sensor_inst, true); 255 if (ret) { 256 sensor_hub_device_close(sensor_inst->hsdev); 257 goto unlock_state; 258 } 259 sensor_inst->enable = true; 260 } else if (!value && sensor_inst->enable) { 261 ret = set_power_report_state(sensor_inst, false); 262 sensor_hub_device_close(sensor_inst->hsdev); 263 sensor_inst->enable = false; 264 } 265unlock_state: 266 mutex_unlock(&sensor_inst->mutex); 267 if (ret < 0) 268 return ret; 269 270 return count; 271} 272static DEVICE_ATTR_RW(enable_sensor); 273 274static struct attribute *enable_sensor_attrs[] = { 275 &dev_attr_enable_sensor.attr, 276 NULL, 277}; 278 279static struct attribute_group enable_sensor_attr_group = { 280 .attrs = enable_sensor_attrs, 281}; 282 283static ssize_t show_value(struct device *dev, struct device_attribute *attr, 284 char *buf) 285{ 286 struct platform_device *pdev = to_platform_device(dev); 287 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 288 struct hid_sensor_hub_attribute_info *attribute; 289 int index, usage, field_index; 290 char name[HID_CUSTOM_NAME_LENGTH]; 291 bool feature = false; 292 bool input = false; 293 int value = 0; 294 295 if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage, 296 name) == 3) { 297 feature = true; 298 field_index = index + sensor_inst->input_field_count; 299 } else if (sscanf(attr->attr.name, "input-%d-%x-%s", &index, &usage, 300 name) == 3) { 301 input = true; 302 field_index = index; 303 } else 304 return -EINVAL; 305 306 if (!strncmp(name, "value", strlen("value"))) { 307 u32 report_id; 308 int ret; 309 310 attribute = &sensor_inst->fields[field_index].attribute; 311 report_id = attribute->report_id; 312 if (feature) { 313 u8 values[HID_CUSTOM_MAX_FEATURE_BYTES]; 314 int len = 0; 315 u64 value = 0; 316 int i = 0; 317 318 ret = sensor_hub_get_feature(sensor_inst->hsdev, 319 report_id, 320 index, 321 sizeof(values), values); 322 if (ret < 0) 323 return ret; 324 325 while (i < ret) { 326 if (i + attribute->size > ret) { 327 len += snprintf(&buf[len], 328 PAGE_SIZE - len, 329 "%d ", values[i]); 330 break; 331 } 332 switch (attribute->size) { 333 case 2: 334 value = (u64) *(u16 *)&values[i]; 335 i += attribute->size; 336 break; 337 case 4: 338 value = (u64) *(u32 *)&values[i]; 339 i += attribute->size; 340 break; 341 case 8: 342 value = *(u64 *)&values[i]; 343 i += attribute->size; 344 break; 345 default: 346 value = (u64) values[i]; 347 ++i; 348 break; 349 } 350 len += snprintf(&buf[len], PAGE_SIZE - len, 351 "%lld ", value); 352 } 353 len += snprintf(&buf[len], PAGE_SIZE - len, "\n"); 354 355 return len; 356 } else if (input) 357 value = sensor_hub_input_attr_get_raw_value( 358 sensor_inst->hsdev, 359 sensor_inst->hsdev->usage, 360 usage, report_id, 361 SENSOR_HUB_SYNC); 362 } else if (!strncmp(name, "units", strlen("units"))) 363 value = sensor_inst->fields[field_index].attribute.units; 364 else if (!strncmp(name, "unit-expo", strlen("unit-expo"))) 365 value = sensor_inst->fields[field_index].attribute.unit_expo; 366 else if (!strncmp(name, "size", strlen("size"))) 367 value = sensor_inst->fields[field_index].attribute.size; 368 else if (!strncmp(name, "minimum", strlen("minimum"))) 369 value = sensor_inst->fields[field_index].attribute. 370 logical_minimum; 371 else if (!strncmp(name, "maximum", strlen("maximum"))) 372 value = sensor_inst->fields[field_index].attribute. 373 logical_maximum; 374 else if (!strncmp(name, "name", strlen("name"))) { 375 struct hid_custom_usage_desc *usage_desc; 376 377 usage_desc = bsearch(&usage, hid_custom_usage_desc_table, 378 ARRAY_SIZE(hid_custom_usage_desc_table), 379 sizeof(struct hid_custom_usage_desc), 380 usage_id_cmp); 381 if (usage_desc) 382 return snprintf(buf, PAGE_SIZE, "%s\n", 383 usage_desc->desc); 384 else 385 return sprintf(buf, "not-specified\n"); 386 } else 387 return -EINVAL; 388 389 return sprintf(buf, "%d\n", value); 390} 391 392static ssize_t store_value(struct device *dev, struct device_attribute *attr, 393 const char *buf, size_t count) 394{ 395 struct platform_device *pdev = to_platform_device(dev); 396 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 397 int index, field_index, usage; 398 char name[HID_CUSTOM_NAME_LENGTH]; 399 int value; 400 401 if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage, 402 name) == 3) { 403 field_index = index + sensor_inst->input_field_count; 404 } else 405 return -EINVAL; 406 407 if (!strncmp(name, "value", strlen("value"))) { 408 u32 report_id; 409 int ret; 410 411 if (kstrtoint(buf, 0, &value) != 0) 412 return -EINVAL; 413 414 report_id = sensor_inst->fields[field_index].attribute. 415 report_id; 416 ret = sensor_hub_set_feature(sensor_inst->hsdev, report_id, 417 index, sizeof(value), &value); 418 } else 419 return -EINVAL; 420 421 return count; 422} 423 424static int hid_sensor_capture_sample(struct hid_sensor_hub_device *hsdev, 425 unsigned usage_id, size_t raw_len, 426 char *raw_data, void *priv) 427{ 428 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv); 429 struct hid_sensor_sample header; 430 431 /* If any error occurs in a sample, rest of the fields are ignored */ 432 if (sensor_inst->input_skip_sample) { 433 hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n"); 434 return 0; 435 } 436 437 hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__, 438 (int) (sensor_inst->input_report_recd_size + raw_len), 439 sensor_inst->input_report_size); 440 441 if (!test_bit(0, &sensor_inst->misc_opened)) 442 return 0; 443 444 if (!sensor_inst->input_report_recd_size) { 445 int required_size = sizeof(struct hid_sensor_sample) + 446 sensor_inst->input_report_size; 447 header.usage_id = hsdev->usage; 448 header.raw_len = sensor_inst->input_report_size; 449 header.timestamp = ktime_get_real_ns(); 450 if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) { 451 kfifo_in(&sensor_inst->data_fifo, 452 (unsigned char *)&header, 453 sizeof(header)); 454 } else 455 sensor_inst->input_skip_sample = true; 456 } 457 if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len) 458 kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data, 459 raw_len); 460 461 sensor_inst->input_report_recd_size += raw_len; 462 463 return 0; 464} 465 466static int hid_sensor_send_event(struct hid_sensor_hub_device *hsdev, 467 unsigned usage_id, void *priv) 468{ 469 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv); 470 471 if (!test_bit(0, &sensor_inst->misc_opened)) 472 return 0; 473 474 sensor_inst->input_report_recd_size = 0; 475 sensor_inst->input_skip_sample = false; 476 477 wake_up(&sensor_inst->wait); 478 479 return 0; 480} 481 482static int hid_sensor_custom_add_field(struct hid_sensor_custom *sensor_inst, 483 int index, int report_type, 484 struct hid_report *report, 485 struct hid_field *field) 486{ 487 struct hid_sensor_custom_field *sensor_field; 488 void *fields; 489 490 fields = krealloc(sensor_inst->fields, 491 (sensor_inst->sensor_field_count + 1) * 492 sizeof(struct hid_sensor_custom_field), GFP_KERNEL); 493 if (!fields) { 494 kfree(sensor_inst->fields); 495 return -ENOMEM; 496 } 497 sensor_inst->fields = fields; 498 sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count]; 499 sensor_field->attribute.usage_id = sensor_inst->hsdev->usage; 500 if (field->logical) 501 sensor_field->attribute.attrib_id = field->logical; 502 else 503 sensor_field->attribute.attrib_id = field->usage[0].hid; 504 505 sensor_field->attribute.index = index; 506 sensor_field->attribute.report_id = report->id; 507 sensor_field->attribute.units = field->unit; 508 sensor_field->attribute.unit_expo = field->unit_exponent; 509 sensor_field->attribute.size = (field->report_size / 8); 510 sensor_field->attribute.logical_minimum = field->logical_minimum; 511 sensor_field->attribute.logical_maximum = field->logical_maximum; 512 513 if (report_type == HID_FEATURE_REPORT) 514 snprintf(sensor_field->group_name, 515 sizeof(sensor_field->group_name), "feature-%x-%x", 516 sensor_field->attribute.index, 517 sensor_field->attribute.attrib_id); 518 else if (report_type == HID_INPUT_REPORT) { 519 snprintf(sensor_field->group_name, 520 sizeof(sensor_field->group_name), 521 "input-%x-%x", sensor_field->attribute.index, 522 sensor_field->attribute.attrib_id); 523 sensor_inst->input_field_count++; 524 sensor_inst->input_report_size += (field->report_size * 525 field->report_count) / 8; 526 } 527 528 memset(&sensor_field->hid_custom_attribute_group, 0, 529 sizeof(struct attribute_group)); 530 sensor_inst->sensor_field_count++; 531 532 return 0; 533} 534 535static int hid_sensor_custom_add_fields(struct hid_sensor_custom *sensor_inst, 536 struct hid_report_enum *report_enum, 537 int report_type) 538{ 539 int i; 540 int ret; 541 struct hid_report *report; 542 struct hid_field *field; 543 struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; 544 545 list_for_each_entry(report, &report_enum->report_list, list) { 546 for (i = 0; i < report->maxfield; ++i) { 547 field = report->field[i]; 548 if (field->maxusage && 549 ((field->usage[0].collection_index >= 550 hsdev->start_collection_index) && 551 (field->usage[0].collection_index < 552 hsdev->end_collection_index))) { 553 554 ret = hid_sensor_custom_add_field(sensor_inst, 555 i, 556 report_type, 557 report, 558 field); 559 if (ret) 560 return ret; 561 562 } 563 } 564 } 565 566 return 0; 567} 568 569static int hid_sensor_custom_add_attributes(struct hid_sensor_custom 570 *sensor_inst) 571{ 572 struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; 573 struct hid_device *hdev = hsdev->hdev; 574 int ret = -1; 575 int i, j; 576 577 for (j = 0; j < HID_REPORT_TYPES; ++j) { 578 if (j == HID_OUTPUT_REPORT) 579 continue; 580 581 ret = hid_sensor_custom_add_fields(sensor_inst, 582 &hdev->report_enum[j], j); 583 if (ret) 584 return ret; 585 586 } 587 588 /* Create sysfs attributes */ 589 for (i = 0; i < sensor_inst->sensor_field_count; ++i) { 590 j = 0; 591 while (j < HID_CUSTOM_TOTAL_ATTRS && 592 hid_custom_attrs[j].name) { 593 struct device_attribute *device_attr; 594 595 device_attr = &sensor_inst->fields[i].sd_attrs[j]; 596 597 snprintf((char *)&sensor_inst->fields[i].attr_name[j], 598 HID_CUSTOM_NAME_LENGTH, "%s-%s", 599 sensor_inst->fields[i].group_name, 600 hid_custom_attrs[j].name); 601 sysfs_attr_init(&device_attr->attr); 602 device_attr->attr.name = 603 (char *)&sensor_inst->fields[i].attr_name[j]; 604 device_attr->attr.mode = hid_custom_attrs[j].mode; 605 device_attr->show = show_value; 606 if (hid_custom_attrs[j].mode & S_IWUSR) 607 device_attr->store = store_value; 608 sensor_inst->fields[i].attrs[j] = &device_attr->attr; 609 ++j; 610 } 611 sensor_inst->fields[i].attrs[j] = NULL; 612 sensor_inst->fields[i].hid_custom_attribute_group.attrs = 613 sensor_inst->fields[i].attrs; 614 sensor_inst->fields[i].hid_custom_attribute_group.name = 615 sensor_inst->fields[i].group_name; 616 ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, 617 &sensor_inst->fields[i]. 618 hid_custom_attribute_group); 619 if (ret) 620 break; 621 622 /* For power or report field store indexes */ 623 if (sensor_inst->fields[i].attribute.attrib_id == 624 HID_USAGE_SENSOR_PROY_POWER_STATE) 625 sensor_inst->power_state = &sensor_inst->fields[i]; 626 else if (sensor_inst->fields[i].attribute.attrib_id == 627 HID_USAGE_SENSOR_PROP_REPORT_STATE) 628 sensor_inst->report_state = &sensor_inst->fields[i]; 629 } 630 631 return ret; 632} 633 634static void hid_sensor_custom_remove_attributes(struct hid_sensor_custom * 635 sensor_inst) 636{ 637 int i; 638 639 for (i = 0; i < sensor_inst->sensor_field_count; ++i) 640 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 641 &sensor_inst->fields[i]. 642 hid_custom_attribute_group); 643 644 kfree(sensor_inst->fields); 645} 646 647static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf, 648 size_t count, loff_t *f_ps) 649{ 650 struct hid_sensor_custom *sensor_inst; 651 unsigned int copied; 652 int ret; 653 654 sensor_inst = container_of(file->private_data, 655 struct hid_sensor_custom, custom_dev); 656 657 if (count < sizeof(struct hid_sensor_sample)) 658 return -EINVAL; 659 660 do { 661 if (kfifo_is_empty(&sensor_inst->data_fifo)) { 662 if (file->f_flags & O_NONBLOCK) 663 return -EAGAIN; 664 665 ret = wait_event_interruptible(sensor_inst->wait, 666 !kfifo_is_empty(&sensor_inst->data_fifo)); 667 if (ret) 668 return ret; 669 } 670 ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count, 671 &copied); 672 if (ret) 673 return ret; 674 675 } while (copied == 0); 676 677 return copied; 678} 679 680static int hid_sensor_custom_release(struct inode *inode, struct file *file) 681{ 682 struct hid_sensor_custom *sensor_inst; 683 684 sensor_inst = container_of(file->private_data, 685 struct hid_sensor_custom, custom_dev); 686 687 clear_bit(0, &sensor_inst->misc_opened); 688 689 return 0; 690} 691 692static int hid_sensor_custom_open(struct inode *inode, struct file *file) 693{ 694 struct hid_sensor_custom *sensor_inst; 695 696 sensor_inst = container_of(file->private_data, 697 struct hid_sensor_custom, custom_dev); 698 /* We essentially have single reader and writer */ 699 if (test_and_set_bit(0, &sensor_inst->misc_opened)) 700 return -EBUSY; 701 702 return nonseekable_open(inode, file); 703} 704 705static unsigned int hid_sensor_custom_poll(struct file *file, 706 struct poll_table_struct *wait) 707{ 708 struct hid_sensor_custom *sensor_inst; 709 unsigned int mask = 0; 710 711 sensor_inst = container_of(file->private_data, 712 struct hid_sensor_custom, custom_dev); 713 714 poll_wait(file, &sensor_inst->wait, wait); 715 716 if (!kfifo_is_empty(&sensor_inst->data_fifo)) 717 mask = POLLIN | POLLRDNORM; 718 719 return mask; 720} 721 722static const struct file_operations hid_sensor_custom_fops = { 723 .open = hid_sensor_custom_open, 724 .read = hid_sensor_custom_read, 725 .release = hid_sensor_custom_release, 726 .poll = hid_sensor_custom_poll, 727 .llseek = noop_llseek, 728}; 729 730static int hid_sensor_custom_dev_if_add(struct hid_sensor_custom *sensor_inst) 731{ 732 int ret; 733 734 ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE, 735 GFP_KERNEL); 736 if (ret) 737 return ret; 738 739 init_waitqueue_head(&sensor_inst->wait); 740 741 sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR; 742 sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev); 743 sensor_inst->custom_dev.fops = &hid_sensor_custom_fops, 744 ret = misc_register(&sensor_inst->custom_dev); 745 if (ret) { 746 kfifo_free(&sensor_inst->data_fifo); 747 return ret; 748 } 749 return 0; 750} 751 752static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom 753 *sensor_inst) 754{ 755 wake_up(&sensor_inst->wait); 756 misc_deregister(&sensor_inst->custom_dev); 757 kfifo_free(&sensor_inst->data_fifo); 758 759} 760 761static int hid_sensor_custom_probe(struct platform_device *pdev) 762{ 763 struct hid_sensor_custom *sensor_inst; 764 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 765 int ret; 766 767 sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst), 768 GFP_KERNEL); 769 if (!sensor_inst) 770 return -ENOMEM; 771 772 sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample; 773 sensor_inst->callbacks.send_event = hid_sensor_send_event; 774 sensor_inst->callbacks.pdev = pdev; 775 sensor_inst->hsdev = hsdev; 776 sensor_inst->pdev = pdev; 777 mutex_init(&sensor_inst->mutex); 778 platform_set_drvdata(pdev, sensor_inst); 779 ret = sensor_hub_register_callback(hsdev, hsdev->usage, 780 &sensor_inst->callbacks); 781 if (ret < 0) { 782 dev_err(&pdev->dev, "callback reg failed\n"); 783 return ret; 784 } 785 786 ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, 787 &enable_sensor_attr_group); 788 if (ret) 789 goto err_remove_callback; 790 791 ret = hid_sensor_custom_add_attributes(sensor_inst); 792 if (ret) 793 goto err_remove_group; 794 795 ret = hid_sensor_custom_dev_if_add(sensor_inst); 796 if (ret) 797 goto err_remove_attributes; 798 799 return 0; 800 801err_remove_attributes: 802 hid_sensor_custom_remove_attributes(sensor_inst); 803err_remove_group: 804 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 805 &enable_sensor_attr_group); 806err_remove_callback: 807 sensor_hub_remove_callback(hsdev, hsdev->usage); 808 809 return ret; 810} 811 812static int hid_sensor_custom_remove(struct platform_device *pdev) 813{ 814 struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 815 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 816 817 hid_sensor_custom_dev_if_remove(sensor_inst); 818 hid_sensor_custom_remove_attributes(sensor_inst); 819 sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 820 &enable_sensor_attr_group); 821 sensor_hub_remove_callback(hsdev, hsdev->usage); 822 823 return 0; 824} 825 826static struct platform_device_id hid_sensor_custom_ids[] = { 827 { 828 .name = "HID-SENSOR-2000e1", 829 }, 830 { 831 .name = "HID-SENSOR-2000e2", 832 }, 833 { /* sentinel */ } 834}; 835MODULE_DEVICE_TABLE(platform, hid_sensor_custom_ids); 836 837static struct platform_driver hid_sensor_custom_platform_driver = { 838 .id_table = hid_sensor_custom_ids, 839 .driver = { 840 .name = KBUILD_MODNAME, 841 }, 842 .probe = hid_sensor_custom_probe, 843 .remove = hid_sensor_custom_remove, 844}; 845module_platform_driver(hid_sensor_custom_platform_driver); 846 847MODULE_DESCRIPTION("HID Sensor Custom and Generic sensor Driver"); 848MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 849MODULE_LICENSE("GPL"); 850