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