Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * hid-sensor-custom.c
0004  * Copyright (c) 2015, Intel Corporation.
0005  */
0006 
0007 #include <linux/ctype.h>
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/miscdevice.h>
0012 #include <linux/kfifo.h>
0013 #include <linux/sched.h>
0014 #include <linux/wait.h>
0015 #include <linux/poll.h>
0016 #include <linux/bsearch.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/hid-sensor-hub.h>
0019 
0020 #define HID_CUSTOM_NAME_LENGTH      64
0021 #define HID_CUSTOM_MAX_CORE_ATTRS   10
0022 #define HID_CUSTOM_TOTAL_ATTRS      (HID_CUSTOM_MAX_CORE_ATTRS + 1)
0023 #define HID_CUSTOM_FIFO_SIZE        4096
0024 #define HID_CUSTOM_MAX_FEATURE_BYTES    64
0025 #define HID_SENSOR_USAGE_LENGTH (4 + 1)
0026 
0027 struct hid_sensor_custom_field {
0028     int report_id;
0029     char group_name[HID_CUSTOM_NAME_LENGTH];
0030     struct hid_sensor_hub_attribute_info attribute;
0031     struct device_attribute sd_attrs[HID_CUSTOM_MAX_CORE_ATTRS];
0032     char attr_name[HID_CUSTOM_TOTAL_ATTRS][HID_CUSTOM_NAME_LENGTH];
0033     struct attribute *attrs[HID_CUSTOM_TOTAL_ATTRS];
0034     struct attribute_group hid_custom_attribute_group;
0035 };
0036 
0037 struct hid_sensor_custom {
0038     struct mutex mutex;
0039     struct platform_device *pdev;
0040     struct hid_sensor_hub_device *hsdev;
0041     struct hid_sensor_hub_callbacks callbacks;
0042     int sensor_field_count;
0043     struct hid_sensor_custom_field *fields;
0044     int input_field_count;
0045     int input_report_size;
0046     int input_report_recd_size;
0047     bool input_skip_sample;
0048     bool enable;
0049     struct hid_sensor_custom_field *power_state;
0050     struct hid_sensor_custom_field *report_state;
0051     struct miscdevice custom_dev;
0052     struct kfifo data_fifo;
0053     unsigned long misc_opened;
0054     wait_queue_head_t wait;
0055     struct platform_device *custom_pdev;
0056 };
0057 
0058 /* Header for each sample to user space via dev interface */
0059 struct hid_sensor_sample {
0060     u32 usage_id;
0061     u64 timestamp;
0062     u32 raw_len;
0063 } __packed;
0064 
0065 static struct attribute hid_custom_attrs[] = {
0066     {.name = "name", .mode = S_IRUGO},
0067     {.name = "units", .mode = S_IRUGO},
0068     {.name = "unit-expo", .mode = S_IRUGO},
0069     {.name = "minimum", .mode = S_IRUGO},
0070     {.name = "maximum", .mode = S_IRUGO},
0071     {.name = "size", .mode = S_IRUGO},
0072     {.name = "value", .mode = S_IWUSR | S_IRUGO},
0073     {.name = NULL}
0074 };
0075 
0076 static const struct hid_custom_usage_desc {
0077     int usage_id;
0078     char *desc;
0079 } hid_custom_usage_desc_table[] = {
0080     {0x200201,  "event-sensor-state"},
0081     {0x200202,  "event-sensor-event"},
0082     {0x200301,  "property-friendly-name"},
0083     {0x200302,  "property-persistent-unique-id"},
0084     {0x200303,  "property-sensor-status"},
0085     {0x200304,  "property-min-report-interval"},
0086     {0x200305,  "property-sensor-manufacturer"},
0087     {0x200306,  "property-sensor-model"},
0088     {0x200307,  "property-sensor-serial-number"},
0089     {0x200308,  "property-sensor-description"},
0090     {0x200309,  "property-sensor-connection-type"},
0091     {0x20030A,  "property-sensor-device-path"},
0092     {0x20030B,  "property-hardware-revision"},
0093     {0x20030C,  "property-firmware-version"},
0094     {0x20030D,  "property-release-date"},
0095     {0x20030E,  "property-report-interval"},
0096     {0x20030F,  "property-change-sensitivity-absolute"},
0097     {0x200310,  "property-change-sensitivity-percent-range"},
0098     {0x200311,  "property-change-sensitivity-percent-relative"},
0099     {0x200312,  "property-accuracy"},
0100     {0x200313,  "property-resolution"},
0101     {0x200314,  "property-maximum"},
0102     {0x200315,  "property-minimum"},
0103     {0x200316,  "property-reporting-state"},
0104     {0x200317,  "property-sampling-rate"},
0105     {0x200318,  "property-response-curve"},
0106     {0x200319,  "property-power-state"},
0107     {0x200540,  "data-field-custom"},
0108     {0x200541,  "data-field-custom-usage"},
0109     {0x200542,  "data-field-custom-boolean-array"},
0110     {0x200543,  "data-field-custom-value"},
0111     {0x200544,  "data-field-custom-value_1"},
0112     {0x200545,  "data-field-custom-value_2"},
0113     {0x200546,  "data-field-custom-value_3"},
0114     {0x200547,  "data-field-custom-value_4"},
0115     {0x200548,  "data-field-custom-value_5"},
0116     {0x200549,  "data-field-custom-value_6"},
0117     {0x20054A,  "data-field-custom-value_7"},
0118     {0x20054B,  "data-field-custom-value_8"},
0119     {0x20054C,  "data-field-custom-value_9"},
0120     {0x20054D,  "data-field-custom-value_10"},
0121     {0x20054E,  "data-field-custom-value_11"},
0122     {0x20054F,  "data-field-custom-value_12"},
0123     {0x200550,  "data-field-custom-value_13"},
0124     {0x200551,  "data-field-custom-value_14"},
0125     {0x200552,  "data-field-custom-value_15"},
0126     {0x200553,  "data-field-custom-value_16"},
0127     {0x200554,  "data-field-custom-value_17"},
0128     {0x200555,  "data-field-custom-value_18"},
0129     {0x200556,  "data-field-custom-value_19"},
0130     {0x200557,  "data-field-custom-value_20"},
0131     {0x200558,  "data-field-custom-value_21"},
0132     {0x200559,  "data-field-custom-value_22"},
0133     {0x20055A,  "data-field-custom-value_23"},
0134     {0x20055B,  "data-field-custom-value_24"},
0135     {0x20055C,  "data-field-custom-value_25"},
0136     {0x20055D,  "data-field-custom-value_26"},
0137     {0x20055E,  "data-field-custom-value_27"},
0138     {0x20055F,  "data-field-custom-value_28"},
0139 };
0140 
0141 static int usage_id_cmp(const void *p1, const void *p2)
0142 {
0143     if (*(int *)p1 < *(int *)p2)
0144         return -1;
0145 
0146     if (*(int *)p1 > *(int *)p2)
0147         return 1;
0148 
0149     return 0;
0150 }
0151 
0152 static ssize_t enable_sensor_show(struct device *dev,
0153                   struct device_attribute *attr, char *buf)
0154 {
0155     struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
0156 
0157     return sprintf(buf, "%d\n", sensor_inst->enable);
0158 }
0159 
0160 static int set_power_report_state(struct hid_sensor_custom *sensor_inst,
0161                   bool state)
0162 {
0163     int power_val = -1;
0164     int report_val = -1;
0165     u32 power_state_usage_id;
0166     u32 report_state_usage_id;
0167     int ret;
0168 
0169     /*
0170      * It is possible that the power/report state ids are not present.
0171      * In this case this function will return success. But if the
0172      * ids are present, then it will return error if set fails.
0173      */
0174     if (state) {
0175         power_state_usage_id =
0176             HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
0177         report_state_usage_id =
0178             HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
0179     } else {
0180         power_state_usage_id =
0181             HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM;
0182         report_state_usage_id =
0183             HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM;
0184     }
0185 
0186     if (sensor_inst->power_state)
0187         power_val = hid_sensor_get_usage_index(sensor_inst->hsdev,
0188                 sensor_inst->power_state->attribute.report_id,
0189                 sensor_inst->power_state->attribute.index,
0190                 power_state_usage_id);
0191     if (sensor_inst->report_state)
0192         report_val = hid_sensor_get_usage_index(sensor_inst->hsdev,
0193                 sensor_inst->report_state->attribute.report_id,
0194                 sensor_inst->report_state->attribute.index,
0195                 report_state_usage_id);
0196 
0197     if (power_val >= 0) {
0198         power_val +=
0199             sensor_inst->power_state->attribute.logical_minimum;
0200         ret = sensor_hub_set_feature(sensor_inst->hsdev,
0201                 sensor_inst->power_state->attribute.report_id,
0202                 sensor_inst->power_state->attribute.index,
0203                 sizeof(power_val),
0204                 &power_val);
0205         if (ret) {
0206             hid_err(sensor_inst->hsdev->hdev,
0207                 "Set power state failed\n");
0208             return ret;
0209         }
0210     }
0211 
0212     if (report_val >= 0) {
0213         report_val +=
0214             sensor_inst->report_state->attribute.logical_minimum;
0215         ret = sensor_hub_set_feature(sensor_inst->hsdev,
0216                 sensor_inst->report_state->attribute.report_id,
0217                 sensor_inst->report_state->attribute.index,
0218                 sizeof(report_val),
0219                 &report_val);
0220         if (ret) {
0221             hid_err(sensor_inst->hsdev->hdev,
0222                 "Set report state failed\n");
0223             return ret;
0224         }
0225     }
0226 
0227     return 0;
0228 }
0229 
0230 static ssize_t enable_sensor_store(struct device *dev,
0231                    struct device_attribute *attr,
0232                    const char *buf, size_t count)
0233 {
0234     struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
0235     int value;
0236     int ret = -EINVAL;
0237 
0238     if (kstrtoint(buf, 0, &value) != 0)
0239         return -EINVAL;
0240 
0241     mutex_lock(&sensor_inst->mutex);
0242     if (value && !sensor_inst->enable) {
0243         ret = sensor_hub_device_open(sensor_inst->hsdev);
0244         if (ret)
0245             goto unlock_state;
0246 
0247         ret = set_power_report_state(sensor_inst, true);
0248         if (ret) {
0249             sensor_hub_device_close(sensor_inst->hsdev);
0250             goto unlock_state;
0251         }
0252         sensor_inst->enable = true;
0253     } else if (!value && sensor_inst->enable) {
0254         ret = set_power_report_state(sensor_inst, false);
0255         sensor_hub_device_close(sensor_inst->hsdev);
0256         sensor_inst->enable = false;
0257     }
0258 unlock_state:
0259     mutex_unlock(&sensor_inst->mutex);
0260     if (ret < 0)
0261         return ret;
0262 
0263     return count;
0264 }
0265 static DEVICE_ATTR_RW(enable_sensor);
0266 
0267 static struct attribute *enable_sensor_attrs[] = {
0268     &dev_attr_enable_sensor.attr,
0269     NULL,
0270 };
0271 
0272 static const struct attribute_group enable_sensor_attr_group = {
0273     .attrs = enable_sensor_attrs,
0274 };
0275 
0276 static ssize_t show_value(struct device *dev, struct device_attribute *attr,
0277               char *buf)
0278 {
0279     struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
0280     struct hid_sensor_hub_attribute_info *attribute;
0281     int index, usage, field_index;
0282     char name[HID_CUSTOM_NAME_LENGTH];
0283     bool feature = false;
0284     bool input = false;
0285     int value = 0;
0286 
0287     if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
0288            name) == 3) {
0289         feature = true;
0290         field_index = index + sensor_inst->input_field_count;
0291     } else if (sscanf(attr->attr.name, "input-%x-%x-%s", &index, &usage,
0292            name) == 3) {
0293         input = true;
0294         field_index = index;
0295     } else
0296         return -EINVAL;
0297 
0298     if (!strncmp(name, "value", strlen("value"))) {
0299         u32 report_id;
0300         int ret;
0301 
0302         attribute = &sensor_inst->fields[field_index].attribute;
0303         report_id = attribute->report_id;
0304         if (feature) {
0305             u8 values[HID_CUSTOM_MAX_FEATURE_BYTES];
0306             int len = 0;
0307             u64 value = 0;
0308             int i = 0;
0309 
0310             ret = sensor_hub_get_feature(sensor_inst->hsdev,
0311                              report_id,
0312                              index,
0313                              sizeof(values), values);
0314             if (ret < 0)
0315                 return ret;
0316 
0317             while (i < ret) {
0318                 if (i + attribute->size > ret) {
0319                     len += scnprintf(&buf[len],
0320                             PAGE_SIZE - len,
0321                             "%d ", values[i]);
0322                     break;
0323                 }
0324                 switch (attribute->size) {
0325                 case 2:
0326                     value = (u64) *(u16 *)&values[i];
0327                     i += attribute->size;
0328                     break;
0329                 case 4:
0330                     value = (u64) *(u32 *)&values[i];
0331                     i += attribute->size;
0332                     break;
0333                 case 8:
0334                     value = *(u64 *)&values[i];
0335                     i += attribute->size;
0336                     break;
0337                 default:
0338                     value = (u64) values[i];
0339                     ++i;
0340                     break;
0341                 }
0342                 len += scnprintf(&buf[len], PAGE_SIZE - len,
0343                         "%lld ", value);
0344             }
0345             len += scnprintf(&buf[len], PAGE_SIZE - len, "\n");
0346 
0347             return len;
0348         } else if (input)
0349             value = sensor_hub_input_attr_get_raw_value(
0350                         sensor_inst->hsdev,
0351                         sensor_inst->hsdev->usage,
0352                         usage, report_id,
0353                         SENSOR_HUB_SYNC, false);
0354     } else if (!strncmp(name, "units", strlen("units")))
0355         value = sensor_inst->fields[field_index].attribute.units;
0356     else if (!strncmp(name, "unit-expo", strlen("unit-expo")))
0357         value = sensor_inst->fields[field_index].attribute.unit_expo;
0358     else if (!strncmp(name, "size", strlen("size")))
0359         value = sensor_inst->fields[field_index].attribute.size;
0360     else if (!strncmp(name, "minimum", strlen("minimum")))
0361         value = sensor_inst->fields[field_index].attribute.
0362                             logical_minimum;
0363     else if (!strncmp(name, "maximum", strlen("maximum")))
0364         value = sensor_inst->fields[field_index].attribute.
0365                             logical_maximum;
0366     else if (!strncmp(name, "name", strlen("name"))) {
0367         struct hid_custom_usage_desc *usage_desc;
0368 
0369         usage_desc = bsearch(&usage, hid_custom_usage_desc_table,
0370                      ARRAY_SIZE(hid_custom_usage_desc_table),
0371                      sizeof(struct hid_custom_usage_desc),
0372                      usage_id_cmp);
0373         if (usage_desc)
0374             return snprintf(buf, PAGE_SIZE, "%s\n",
0375                     usage_desc->desc);
0376         else
0377             return sprintf(buf, "not-specified\n");
0378      } else
0379         return -EINVAL;
0380 
0381     return sprintf(buf, "%d\n", value);
0382 }
0383 
0384 static ssize_t store_value(struct device *dev, struct device_attribute *attr,
0385                const char *buf, size_t count)
0386 {
0387     struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
0388     int index, field_index, usage;
0389     char name[HID_CUSTOM_NAME_LENGTH];
0390     int value, ret;
0391 
0392     if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
0393            name) == 3) {
0394         field_index = index + sensor_inst->input_field_count;
0395     } else
0396         return -EINVAL;
0397 
0398     if (!strncmp(name, "value", strlen("value"))) {
0399         u32 report_id;
0400 
0401         if (kstrtoint(buf, 0, &value) != 0)
0402             return -EINVAL;
0403 
0404         report_id = sensor_inst->fields[field_index].attribute.
0405                                 report_id;
0406         ret = sensor_hub_set_feature(sensor_inst->hsdev, report_id,
0407                          index, sizeof(value), &value);
0408         if (ret)
0409             return ret;
0410     } else
0411         return -EINVAL;
0412 
0413     return count;
0414 }
0415 
0416 static int hid_sensor_capture_sample(struct hid_sensor_hub_device *hsdev,
0417                   unsigned usage_id, size_t raw_len,
0418                   char *raw_data, void *priv)
0419 {
0420     struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);
0421     struct hid_sensor_sample header;
0422 
0423     /* If any error occurs in a sample, rest of the fields are ignored */
0424     if (sensor_inst->input_skip_sample) {
0425         hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n");
0426         return 0;
0427     }
0428 
0429     hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__,
0430         (int) (sensor_inst->input_report_recd_size + raw_len),
0431         sensor_inst->input_report_size);
0432 
0433     if (!test_bit(0, &sensor_inst->misc_opened))
0434         return 0;
0435 
0436     if (!sensor_inst->input_report_recd_size) {
0437         int required_size = sizeof(struct hid_sensor_sample) +
0438                         sensor_inst->input_report_size;
0439         header.usage_id = hsdev->usage;
0440         header.raw_len = sensor_inst->input_report_size;
0441         header.timestamp = ktime_get_real_ns();
0442         if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) {
0443             kfifo_in(&sensor_inst->data_fifo,
0444                  (unsigned char *)&header,
0445                  sizeof(header));
0446         } else
0447             sensor_inst->input_skip_sample = true;
0448     }
0449     if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len)
0450         kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data,
0451              raw_len);
0452 
0453     sensor_inst->input_report_recd_size += raw_len;
0454 
0455     return 0;
0456 }
0457 
0458 static int hid_sensor_send_event(struct hid_sensor_hub_device *hsdev,
0459                  unsigned usage_id, void *priv)
0460 {
0461     struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);
0462 
0463     if (!test_bit(0, &sensor_inst->misc_opened))
0464         return 0;
0465 
0466     sensor_inst->input_report_recd_size = 0;
0467     sensor_inst->input_skip_sample = false;
0468 
0469     wake_up(&sensor_inst->wait);
0470 
0471     return 0;
0472 }
0473 
0474 static int hid_sensor_custom_add_field(struct hid_sensor_custom *sensor_inst,
0475                        int index, int report_type,
0476                        struct hid_report *report,
0477                        struct hid_field *field)
0478 {
0479     struct hid_sensor_custom_field *sensor_field;
0480     void *fields;
0481 
0482     fields = krealloc(sensor_inst->fields,
0483               (sensor_inst->sensor_field_count + 1) *
0484                sizeof(struct hid_sensor_custom_field), GFP_KERNEL);
0485     if (!fields) {
0486         kfree(sensor_inst->fields);
0487         return -ENOMEM;
0488     }
0489     sensor_inst->fields = fields;
0490     sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count];
0491     sensor_field->attribute.usage_id = sensor_inst->hsdev->usage;
0492     if (field->logical)
0493         sensor_field->attribute.attrib_id = field->logical;
0494     else
0495         sensor_field->attribute.attrib_id = field->usage[0].hid;
0496 
0497     sensor_field->attribute.index = index;
0498     sensor_field->attribute.report_id = report->id;
0499     sensor_field->attribute.units = field->unit;
0500     sensor_field->attribute.unit_expo = field->unit_exponent;
0501     sensor_field->attribute.size = (field->report_size / 8);
0502     sensor_field->attribute.logical_minimum = field->logical_minimum;
0503     sensor_field->attribute.logical_maximum = field->logical_maximum;
0504 
0505     if (report_type == HID_FEATURE_REPORT)
0506         snprintf(sensor_field->group_name,
0507              sizeof(sensor_field->group_name), "feature-%x-%x",
0508              sensor_field->attribute.index,
0509              sensor_field->attribute.attrib_id);
0510     else if (report_type == HID_INPUT_REPORT) {
0511         snprintf(sensor_field->group_name,
0512              sizeof(sensor_field->group_name),
0513              "input-%x-%x", sensor_field->attribute.index,
0514              sensor_field->attribute.attrib_id);
0515         sensor_inst->input_field_count++;
0516         sensor_inst->input_report_size += (field->report_size *
0517                            field->report_count) / 8;
0518     }
0519 
0520     memset(&sensor_field->hid_custom_attribute_group, 0,
0521            sizeof(struct attribute_group));
0522     sensor_inst->sensor_field_count++;
0523 
0524     return 0;
0525 }
0526 
0527 static int hid_sensor_custom_add_fields(struct hid_sensor_custom *sensor_inst,
0528                     struct hid_report_enum *report_enum,
0529                     int report_type)
0530 {
0531     int i;
0532     int ret;
0533     struct hid_report *report;
0534     struct hid_field *field;
0535     struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;
0536 
0537     list_for_each_entry(report, &report_enum->report_list, list) {
0538         for (i = 0; i < report->maxfield; ++i) {
0539             field = report->field[i];
0540             if (field->maxusage &&
0541                 ((field->usage[0].collection_index >=
0542                   hsdev->start_collection_index) &&
0543                   (field->usage[0].collection_index <
0544                    hsdev->end_collection_index))) {
0545 
0546                 ret = hid_sensor_custom_add_field(sensor_inst,
0547                                   i,
0548                                   report_type,
0549                                   report,
0550                                   field);
0551                 if (ret)
0552                     return ret;
0553 
0554             }
0555         }
0556     }
0557 
0558     return 0;
0559 }
0560 
0561 static int hid_sensor_custom_add_attributes(struct hid_sensor_custom
0562                                 *sensor_inst)
0563 {
0564     struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;
0565     struct hid_device *hdev = hsdev->hdev;
0566     int ret = -1;
0567     int i, j;
0568 
0569     for (j = 0; j < HID_REPORT_TYPES; ++j) {
0570         if (j == HID_OUTPUT_REPORT)
0571             continue;
0572 
0573         ret = hid_sensor_custom_add_fields(sensor_inst,
0574                            &hdev->report_enum[j], j);
0575         if (ret)
0576             return ret;
0577 
0578     }
0579 
0580     /* Create sysfs attributes */
0581     for (i = 0; i < sensor_inst->sensor_field_count; ++i) {
0582         j = 0;
0583         while (j < HID_CUSTOM_TOTAL_ATTRS &&
0584                hid_custom_attrs[j].name) {
0585             struct device_attribute *device_attr;
0586 
0587             device_attr = &sensor_inst->fields[i].sd_attrs[j];
0588 
0589             snprintf((char *)&sensor_inst->fields[i].attr_name[j],
0590                  HID_CUSTOM_NAME_LENGTH, "%s-%s",
0591                  sensor_inst->fields[i].group_name,
0592                  hid_custom_attrs[j].name);
0593             sysfs_attr_init(&device_attr->attr);
0594             device_attr->attr.name =
0595                 (char *)&sensor_inst->fields[i].attr_name[j];
0596             device_attr->attr.mode = hid_custom_attrs[j].mode;
0597             device_attr->show = show_value;
0598             if (hid_custom_attrs[j].mode & S_IWUSR)
0599                 device_attr->store = store_value;
0600             sensor_inst->fields[i].attrs[j] = &device_attr->attr;
0601             ++j;
0602         }
0603         sensor_inst->fields[i].attrs[j] = NULL;
0604         sensor_inst->fields[i].hid_custom_attribute_group.attrs =
0605                         sensor_inst->fields[i].attrs;
0606         sensor_inst->fields[i].hid_custom_attribute_group.name =
0607                     sensor_inst->fields[i].group_name;
0608         ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
0609                      &sensor_inst->fields[i].
0610                      hid_custom_attribute_group);
0611         if (ret)
0612             break;
0613 
0614         /* For power or report field store indexes */
0615         if (sensor_inst->fields[i].attribute.attrib_id ==
0616                     HID_USAGE_SENSOR_PROY_POWER_STATE)
0617             sensor_inst->power_state = &sensor_inst->fields[i];
0618         else if (sensor_inst->fields[i].attribute.attrib_id ==
0619                     HID_USAGE_SENSOR_PROP_REPORT_STATE)
0620             sensor_inst->report_state = &sensor_inst->fields[i];
0621     }
0622 
0623     return ret;
0624 }
0625 
0626 static void hid_sensor_custom_remove_attributes(struct hid_sensor_custom *
0627                                 sensor_inst)
0628 {
0629     int i;
0630 
0631     for (i = 0; i < sensor_inst->sensor_field_count; ++i)
0632         sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
0633                    &sensor_inst->fields[i].
0634                    hid_custom_attribute_group);
0635 
0636     kfree(sensor_inst->fields);
0637 }
0638 
0639 static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf,
0640                       size_t count, loff_t *f_ps)
0641 {
0642     struct hid_sensor_custom *sensor_inst;
0643     unsigned int copied;
0644     int ret;
0645 
0646     sensor_inst = container_of(file->private_data,
0647                    struct hid_sensor_custom, custom_dev);
0648 
0649     if (count < sizeof(struct hid_sensor_sample))
0650         return -EINVAL;
0651 
0652     do {
0653         if (kfifo_is_empty(&sensor_inst->data_fifo)) {
0654             if (file->f_flags & O_NONBLOCK)
0655                 return -EAGAIN;
0656 
0657             ret = wait_event_interruptible(sensor_inst->wait,
0658                 !kfifo_is_empty(&sensor_inst->data_fifo));
0659             if (ret)
0660                 return ret;
0661         }
0662         ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count,
0663                     &copied);
0664         if (ret)
0665             return ret;
0666 
0667     } while (copied == 0);
0668 
0669     return copied;
0670 }
0671 
0672 static int hid_sensor_custom_release(struct inode *inode, struct file *file)
0673 {
0674     struct hid_sensor_custom *sensor_inst;
0675 
0676     sensor_inst = container_of(file->private_data,
0677                    struct hid_sensor_custom, custom_dev);
0678 
0679     clear_bit(0, &sensor_inst->misc_opened);
0680 
0681     return 0;
0682 }
0683 
0684 static int hid_sensor_custom_open(struct inode *inode, struct file *file)
0685 {
0686     struct hid_sensor_custom *sensor_inst;
0687 
0688     sensor_inst = container_of(file->private_data,
0689                    struct hid_sensor_custom, custom_dev);
0690     /* We essentially have single reader and writer */
0691     if (test_and_set_bit(0, &sensor_inst->misc_opened))
0692         return -EBUSY;
0693 
0694     return stream_open(inode, file);
0695 }
0696 
0697 static __poll_t hid_sensor_custom_poll(struct file *file,
0698                        struct poll_table_struct *wait)
0699 {
0700     struct hid_sensor_custom *sensor_inst;
0701     __poll_t mask = 0;
0702 
0703     sensor_inst = container_of(file->private_data,
0704                    struct hid_sensor_custom, custom_dev);
0705 
0706     poll_wait(file, &sensor_inst->wait, wait);
0707 
0708     if (!kfifo_is_empty(&sensor_inst->data_fifo))
0709         mask = EPOLLIN | EPOLLRDNORM;
0710 
0711     return mask;
0712 }
0713 
0714 static const struct file_operations hid_sensor_custom_fops = {
0715     .open =  hid_sensor_custom_open,
0716     .read =  hid_sensor_custom_read,
0717     .release = hid_sensor_custom_release,
0718     .poll = hid_sensor_custom_poll,
0719     .llseek = noop_llseek,
0720 };
0721 
0722 static int hid_sensor_custom_dev_if_add(struct hid_sensor_custom *sensor_inst)
0723 {
0724     int ret;
0725 
0726     ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE,
0727               GFP_KERNEL);
0728     if (ret)
0729         return ret;
0730 
0731     init_waitqueue_head(&sensor_inst->wait);
0732 
0733     sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR;
0734     sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev);
0735     sensor_inst->custom_dev.fops = &hid_sensor_custom_fops,
0736     ret = misc_register(&sensor_inst->custom_dev);
0737     if (ret) {
0738         kfifo_free(&sensor_inst->data_fifo);
0739         return ret;
0740     }
0741     return 0;
0742 }
0743 
0744 static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom
0745                                 *sensor_inst)
0746 {
0747     wake_up(&sensor_inst->wait);
0748     misc_deregister(&sensor_inst->custom_dev);
0749     kfifo_free(&sensor_inst->data_fifo);
0750 
0751 }
0752 
0753 /* luid defined in FW (e.g. ISH).  Maybe used to identify sensor. */
0754 static const char *const known_sensor_luid[] = { "020B000000000000" };
0755 
0756 static int get_luid_table_index(unsigned char *usage_str)
0757 {
0758     int i;
0759 
0760     for (i = 0; i < ARRAY_SIZE(known_sensor_luid); i++) {
0761         if (!strncmp(usage_str, known_sensor_luid[i],
0762                  strlen(known_sensor_luid[i])))
0763             return i;
0764     }
0765 
0766     return -ENODEV;
0767 }
0768 
0769 static int get_known_custom_sensor_index(struct hid_sensor_hub_device *hsdev)
0770 {
0771     struct hid_sensor_hub_attribute_info sensor_manufacturer = { 0 };
0772     struct hid_sensor_hub_attribute_info sensor_luid_info = { 0 };
0773     int report_size;
0774     int ret;
0775     static u16 w_buf[HID_CUSTOM_MAX_FEATURE_BYTES];
0776     static char buf[HID_CUSTOM_MAX_FEATURE_BYTES];
0777     int i;
0778 
0779     memset(w_buf, 0, sizeof(w_buf));
0780     memset(buf, 0, sizeof(buf));
0781 
0782     /* get manufacturer info */
0783     ret = sensor_hub_input_get_attribute_info(hsdev,
0784             HID_FEATURE_REPORT, hsdev->usage,
0785             HID_USAGE_SENSOR_PROP_MANUFACTURER, &sensor_manufacturer);
0786     if (ret < 0)
0787         return ret;
0788 
0789     report_size =
0790         sensor_hub_get_feature(hsdev, sensor_manufacturer.report_id,
0791                        sensor_manufacturer.index, sizeof(w_buf),
0792                        w_buf);
0793     if (report_size <= 0) {
0794         hid_err(hsdev->hdev,
0795             "Failed to get sensor manufacturer info %d\n",
0796             report_size);
0797         return -ENODEV;
0798     }
0799 
0800     /* convert from wide char to char */
0801     for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
0802         buf[i] = (char)w_buf[i];
0803 
0804     /* ensure it's ISH sensor */
0805     if (strncmp(buf, "INTEL", strlen("INTEL")))
0806         return -ENODEV;
0807 
0808     memset(w_buf, 0, sizeof(w_buf));
0809     memset(buf, 0, sizeof(buf));
0810 
0811     /* get real usage id */
0812     ret = sensor_hub_input_get_attribute_info(hsdev,
0813             HID_FEATURE_REPORT, hsdev->usage,
0814             HID_USAGE_SENSOR_PROP_SERIAL_NUM, &sensor_luid_info);
0815     if (ret < 0)
0816         return ret;
0817 
0818     report_size = sensor_hub_get_feature(hsdev, sensor_luid_info.report_id,
0819                          sensor_luid_info.index, sizeof(w_buf),
0820                          w_buf);
0821     if (report_size <= 0) {
0822         hid_err(hsdev->hdev, "Failed to get real usage info %d\n",
0823             report_size);
0824         return -ENODEV;
0825     }
0826 
0827     /* convert from wide char to char */
0828     for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
0829         buf[i] = (char)w_buf[i];
0830 
0831     if (strlen(buf) != strlen(known_sensor_luid[0]) + 5) {
0832         hid_err(hsdev->hdev,
0833             "%s luid length not match %zu != (%zu + 5)\n", __func__,
0834             strlen(buf), strlen(known_sensor_luid[0]));
0835         return -ENODEV;
0836     }
0837 
0838     /* get table index with luid (not matching 'LUID: ' in luid) */
0839     return get_luid_table_index(&buf[5]);
0840 }
0841 
0842 static struct platform_device *
0843 hid_sensor_register_platform_device(struct platform_device *pdev,
0844                     struct hid_sensor_hub_device *hsdev,
0845                     int index)
0846 {
0847     char real_usage[HID_SENSOR_USAGE_LENGTH] = { 0 };
0848     struct platform_device *custom_pdev;
0849     const char *dev_name;
0850     char *c;
0851 
0852     /* copy real usage id */
0853     memcpy(real_usage, known_sensor_luid[index], 4);
0854 
0855     /* usage id are all lowcase */
0856     for (c = real_usage; *c != '\0'; c++)
0857         *c = tolower(*c);
0858 
0859     /* HID-SENSOR-INT-REAL_USAGE_ID */
0860     dev_name = kasprintf(GFP_KERNEL, "HID-SENSOR-INT-%s", real_usage);
0861     if (!dev_name)
0862         return ERR_PTR(-ENOMEM);
0863 
0864     custom_pdev = platform_device_register_data(pdev->dev.parent, dev_name,
0865                             PLATFORM_DEVID_NONE, hsdev,
0866                             sizeof(*hsdev));
0867     kfree(dev_name);
0868     return custom_pdev;
0869 }
0870 
0871 static int hid_sensor_custom_probe(struct platform_device *pdev)
0872 {
0873     struct hid_sensor_custom *sensor_inst;
0874     struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
0875     int ret;
0876     int index;
0877 
0878     sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst),
0879                    GFP_KERNEL);
0880     if (!sensor_inst)
0881         return -ENOMEM;
0882 
0883     sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample;
0884     sensor_inst->callbacks.send_event = hid_sensor_send_event;
0885     sensor_inst->callbacks.pdev = pdev;
0886     sensor_inst->hsdev = hsdev;
0887     sensor_inst->pdev = pdev;
0888     mutex_init(&sensor_inst->mutex);
0889     platform_set_drvdata(pdev, sensor_inst);
0890 
0891     index = get_known_custom_sensor_index(hsdev);
0892     if (index >= 0 && index < ARRAY_SIZE(known_sensor_luid)) {
0893         sensor_inst->custom_pdev =
0894             hid_sensor_register_platform_device(pdev, hsdev, index);
0895 
0896         ret = PTR_ERR_OR_ZERO(sensor_inst->custom_pdev);
0897         if (ret) {
0898             dev_err(&pdev->dev,
0899                 "register_platform_device failed\n");
0900             return ret;
0901         }
0902 
0903         return 0;
0904     }
0905 
0906     ret = sensor_hub_register_callback(hsdev, hsdev->usage,
0907                        &sensor_inst->callbacks);
0908     if (ret < 0) {
0909         dev_err(&pdev->dev, "callback reg failed\n");
0910         return ret;
0911     }
0912 
0913     ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
0914                  &enable_sensor_attr_group);
0915     if (ret)
0916         goto err_remove_callback;
0917 
0918     ret = hid_sensor_custom_add_attributes(sensor_inst);
0919     if (ret)
0920         goto err_remove_group;
0921 
0922     ret = hid_sensor_custom_dev_if_add(sensor_inst);
0923     if (ret)
0924         goto err_remove_attributes;
0925 
0926     return 0;
0927 
0928 err_remove_attributes:
0929     hid_sensor_custom_remove_attributes(sensor_inst);
0930 err_remove_group:
0931     sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
0932                &enable_sensor_attr_group);
0933 err_remove_callback:
0934     sensor_hub_remove_callback(hsdev, hsdev->usage);
0935 
0936     return ret;
0937 }
0938 
0939 static int hid_sensor_custom_remove(struct platform_device *pdev)
0940 {
0941     struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev);
0942     struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
0943 
0944     if (sensor_inst->custom_pdev) {
0945         platform_device_unregister(sensor_inst->custom_pdev);
0946         return 0;
0947     }
0948 
0949     hid_sensor_custom_dev_if_remove(sensor_inst);
0950     hid_sensor_custom_remove_attributes(sensor_inst);
0951     sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
0952                &enable_sensor_attr_group);
0953     sensor_hub_remove_callback(hsdev, hsdev->usage);
0954 
0955     return 0;
0956 }
0957 
0958 static const struct platform_device_id hid_sensor_custom_ids[] = {
0959     {
0960         .name = "HID-SENSOR-2000e1",
0961     },
0962     {
0963         .name = "HID-SENSOR-2000e2",
0964     },
0965     { /* sentinel */ }
0966 };
0967 MODULE_DEVICE_TABLE(platform, hid_sensor_custom_ids);
0968 
0969 static struct platform_driver hid_sensor_custom_platform_driver = {
0970     .id_table = hid_sensor_custom_ids,
0971     .driver = {
0972         .name   = KBUILD_MODNAME,
0973     },
0974     .probe      = hid_sensor_custom_probe,
0975     .remove     = hid_sensor_custom_remove,
0976 };
0977 module_platform_driver(hid_sensor_custom_platform_driver);
0978 
0979 MODULE_DESCRIPTION("HID Sensor Custom and Generic sensor Driver");
0980 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
0981 MODULE_LICENSE("GPL");