Merge tag 'sched-urgent-2021-05-09' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / hid / hid-sensor-custom.c
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
27 struct 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
37 struct 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 */
59 struct hid_sensor_sample {
60         u32 usage_id;
61         u64 timestamp;
62         u32 raw_len;
63 } __packed;
64
65 static 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
76 static 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
141 static 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
152 static 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
160 static 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
230 static 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         }
258 unlock_state:
259         mutex_unlock(&sensor_inst->mutex);
260         if (ret < 0)
261                 return ret;
262
263         return count;
264 }
265 static DEVICE_ATTR_RW(enable_sensor);
266
267 static struct attribute *enable_sensor_attrs[] = {
268         &dev_attr_enable_sensor.attr,
269         NULL,
270 };
271
272 static const struct attribute_group enable_sensor_attr_group = {
273         .attrs = enable_sensor_attrs,
274 };
275
276 static 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
384 static 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;
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                 sensor_hub_set_feature(sensor_inst->hsdev, report_id,
407                                        index, sizeof(value), &value);
408         } else
409                 return -EINVAL;
410
411         return count;
412 }
413
414 static int hid_sensor_capture_sample(struct hid_sensor_hub_device *hsdev,
415                                   unsigned usage_id, size_t raw_len,
416                                   char *raw_data, void *priv)
417 {
418         struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);
419         struct hid_sensor_sample header;
420
421         /* If any error occurs in a sample, rest of the fields are ignored */
422         if (sensor_inst->input_skip_sample) {
423                 hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n");
424                 return 0;
425         }
426
427         hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__,
428                 (int) (sensor_inst->input_report_recd_size + raw_len),
429                 sensor_inst->input_report_size);
430
431         if (!test_bit(0, &sensor_inst->misc_opened))
432                 return 0;
433
434         if (!sensor_inst->input_report_recd_size) {
435                 int required_size = sizeof(struct hid_sensor_sample) +
436                                                 sensor_inst->input_report_size;
437                 header.usage_id = hsdev->usage;
438                 header.raw_len = sensor_inst->input_report_size;
439                 header.timestamp = ktime_get_real_ns();
440                 if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) {
441                         kfifo_in(&sensor_inst->data_fifo,
442                                  (unsigned char *)&header,
443                                  sizeof(header));
444                 } else
445                         sensor_inst->input_skip_sample = true;
446         }
447         if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len)
448                 kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data,
449                          raw_len);
450
451         sensor_inst->input_report_recd_size += raw_len;
452
453         return 0;
454 }
455
456 static int hid_sensor_send_event(struct hid_sensor_hub_device *hsdev,
457                                  unsigned usage_id, void *priv)
458 {
459         struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);
460
461         if (!test_bit(0, &sensor_inst->misc_opened))
462                 return 0;
463
464         sensor_inst->input_report_recd_size = 0;
465         sensor_inst->input_skip_sample = false;
466
467         wake_up(&sensor_inst->wait);
468
469         return 0;
470 }
471
472 static int hid_sensor_custom_add_field(struct hid_sensor_custom *sensor_inst,
473                                        int index, int report_type,
474                                        struct hid_report *report,
475                                        struct hid_field *field)
476 {
477         struct hid_sensor_custom_field *sensor_field;
478         void *fields;
479
480         fields = krealloc(sensor_inst->fields,
481                           (sensor_inst->sensor_field_count + 1) *
482                            sizeof(struct hid_sensor_custom_field), GFP_KERNEL);
483         if (!fields) {
484                 kfree(sensor_inst->fields);
485                 return -ENOMEM;
486         }
487         sensor_inst->fields = fields;
488         sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count];
489         sensor_field->attribute.usage_id = sensor_inst->hsdev->usage;
490         if (field->logical)
491                 sensor_field->attribute.attrib_id = field->logical;
492         else
493                 sensor_field->attribute.attrib_id = field->usage[0].hid;
494
495         sensor_field->attribute.index = index;
496         sensor_field->attribute.report_id = report->id;
497         sensor_field->attribute.units = field->unit;
498         sensor_field->attribute.unit_expo = field->unit_exponent;
499         sensor_field->attribute.size = (field->report_size / 8);
500         sensor_field->attribute.logical_minimum = field->logical_minimum;
501         sensor_field->attribute.logical_maximum = field->logical_maximum;
502
503         if (report_type == HID_FEATURE_REPORT)
504                 snprintf(sensor_field->group_name,
505                          sizeof(sensor_field->group_name), "feature-%x-%x",
506                          sensor_field->attribute.index,
507                          sensor_field->attribute.attrib_id);
508         else if (report_type == HID_INPUT_REPORT) {
509                 snprintf(sensor_field->group_name,
510                          sizeof(sensor_field->group_name),
511                          "input-%x-%x", sensor_field->attribute.index,
512                          sensor_field->attribute.attrib_id);
513                 sensor_inst->input_field_count++;
514                 sensor_inst->input_report_size += (field->report_size *
515                                                    field->report_count) / 8;
516         }
517
518         memset(&sensor_field->hid_custom_attribute_group, 0,
519                sizeof(struct attribute_group));
520         sensor_inst->sensor_field_count++;
521
522         return 0;
523 }
524
525 static int hid_sensor_custom_add_fields(struct hid_sensor_custom *sensor_inst,
526                                         struct hid_report_enum *report_enum,
527                                         int report_type)
528 {
529         int i;
530         int ret;
531         struct hid_report *report;
532         struct hid_field *field;
533         struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;
534
535         list_for_each_entry(report, &report_enum->report_list, list) {
536                 for (i = 0; i < report->maxfield; ++i) {
537                         field = report->field[i];
538                         if (field->maxusage &&
539                             ((field->usage[0].collection_index >=
540                               hsdev->start_collection_index) &&
541                               (field->usage[0].collection_index <
542                                hsdev->end_collection_index))) {
543
544                                 ret = hid_sensor_custom_add_field(sensor_inst,
545                                                                   i,
546                                                                   report_type,
547                                                                   report,
548                                                                   field);
549                                 if (ret)
550                                         return ret;
551
552                         }
553                 }
554         }
555
556         return 0;
557 }
558
559 static int hid_sensor_custom_add_attributes(struct hid_sensor_custom
560                                                                 *sensor_inst)
561 {
562         struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;
563         struct hid_device *hdev = hsdev->hdev;
564         int ret = -1;
565         int i, j;
566
567         for (j = 0; j < HID_REPORT_TYPES; ++j) {
568                 if (j == HID_OUTPUT_REPORT)
569                         continue;
570
571                 ret = hid_sensor_custom_add_fields(sensor_inst,
572                                                    &hdev->report_enum[j], j);
573                 if (ret)
574                         return ret;
575
576         }
577
578         /* Create sysfs attributes */
579         for (i = 0; i < sensor_inst->sensor_field_count; ++i) {
580                 j = 0;
581                 while (j < HID_CUSTOM_TOTAL_ATTRS &&
582                        hid_custom_attrs[j].name) {
583                         struct device_attribute *device_attr;
584
585                         device_attr = &sensor_inst->fields[i].sd_attrs[j];
586
587                         snprintf((char *)&sensor_inst->fields[i].attr_name[j],
588                                  HID_CUSTOM_NAME_LENGTH, "%s-%s",
589                                  sensor_inst->fields[i].group_name,
590                                  hid_custom_attrs[j].name);
591                         sysfs_attr_init(&device_attr->attr);
592                         device_attr->attr.name =
593                                 (char *)&sensor_inst->fields[i].attr_name[j];
594                         device_attr->attr.mode = hid_custom_attrs[j].mode;
595                         device_attr->show = show_value;
596                         if (hid_custom_attrs[j].mode & S_IWUSR)
597                                 device_attr->store = store_value;
598                         sensor_inst->fields[i].attrs[j] = &device_attr->attr;
599                         ++j;
600                 }
601                 sensor_inst->fields[i].attrs[j] = NULL;
602                 sensor_inst->fields[i].hid_custom_attribute_group.attrs =
603                                                 sensor_inst->fields[i].attrs;
604                 sensor_inst->fields[i].hid_custom_attribute_group.name =
605                                         sensor_inst->fields[i].group_name;
606                 ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
607                                          &sensor_inst->fields[i].
608                                          hid_custom_attribute_group);
609                 if (ret)
610                         break;
611
612                 /* For power or report field store indexes */
613                 if (sensor_inst->fields[i].attribute.attrib_id ==
614                                         HID_USAGE_SENSOR_PROY_POWER_STATE)
615                         sensor_inst->power_state = &sensor_inst->fields[i];
616                 else if (sensor_inst->fields[i].attribute.attrib_id ==
617                                         HID_USAGE_SENSOR_PROP_REPORT_STATE)
618                         sensor_inst->report_state = &sensor_inst->fields[i];
619         }
620
621         return ret;
622 }
623
624 static void hid_sensor_custom_remove_attributes(struct hid_sensor_custom *
625                                                                 sensor_inst)
626 {
627         int i;
628
629         for (i = 0; i < sensor_inst->sensor_field_count; ++i)
630                 sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
631                                    &sensor_inst->fields[i].
632                                    hid_custom_attribute_group);
633
634         kfree(sensor_inst->fields);
635 }
636
637 static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf,
638                                       size_t count, loff_t *f_ps)
639 {
640         struct hid_sensor_custom *sensor_inst;
641         unsigned int copied;
642         int ret;
643
644         sensor_inst = container_of(file->private_data,
645                                    struct hid_sensor_custom, custom_dev);
646
647         if (count < sizeof(struct hid_sensor_sample))
648                 return -EINVAL;
649
650         do {
651                 if (kfifo_is_empty(&sensor_inst->data_fifo)) {
652                         if (file->f_flags & O_NONBLOCK)
653                                 return -EAGAIN;
654
655                         ret = wait_event_interruptible(sensor_inst->wait,
656                                 !kfifo_is_empty(&sensor_inst->data_fifo));
657                         if (ret)
658                                 return ret;
659                 }
660                 ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count,
661                                     &copied);
662                 if (ret)
663                         return ret;
664
665         } while (copied == 0);
666
667         return copied;
668 }
669
670 static int hid_sensor_custom_release(struct inode *inode, struct file *file)
671 {
672         struct hid_sensor_custom *sensor_inst;
673
674         sensor_inst = container_of(file->private_data,
675                                    struct hid_sensor_custom, custom_dev);
676
677         clear_bit(0, &sensor_inst->misc_opened);
678
679         return 0;
680 }
681
682 static int hid_sensor_custom_open(struct inode *inode, struct file *file)
683 {
684         struct hid_sensor_custom *sensor_inst;
685
686         sensor_inst = container_of(file->private_data,
687                                    struct hid_sensor_custom, custom_dev);
688         /* We essentially have single reader and writer */
689         if (test_and_set_bit(0, &sensor_inst->misc_opened))
690                 return -EBUSY;
691
692         return stream_open(inode, file);
693 }
694
695 static __poll_t hid_sensor_custom_poll(struct file *file,
696                                            struct poll_table_struct *wait)
697 {
698         struct hid_sensor_custom *sensor_inst;
699         __poll_t mask = 0;
700
701         sensor_inst = container_of(file->private_data,
702                                    struct hid_sensor_custom, custom_dev);
703
704         poll_wait(file, &sensor_inst->wait, wait);
705
706         if (!kfifo_is_empty(&sensor_inst->data_fifo))
707                 mask = EPOLLIN | EPOLLRDNORM;
708
709         return mask;
710 }
711
712 static const struct file_operations hid_sensor_custom_fops = {
713         .open =  hid_sensor_custom_open,
714         .read =  hid_sensor_custom_read,
715         .release = hid_sensor_custom_release,
716         .poll = hid_sensor_custom_poll,
717         .llseek = noop_llseek,
718 };
719
720 static int hid_sensor_custom_dev_if_add(struct hid_sensor_custom *sensor_inst)
721 {
722         int ret;
723
724         ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE,
725                           GFP_KERNEL);
726         if (ret)
727                 return ret;
728
729         init_waitqueue_head(&sensor_inst->wait);
730
731         sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR;
732         sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev);
733         sensor_inst->custom_dev.fops = &hid_sensor_custom_fops,
734         ret = misc_register(&sensor_inst->custom_dev);
735         if (ret) {
736                 kfifo_free(&sensor_inst->data_fifo);
737                 return ret;
738         }
739         return 0;
740 }
741
742 static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom
743                                                                 *sensor_inst)
744 {
745         wake_up(&sensor_inst->wait);
746         misc_deregister(&sensor_inst->custom_dev);
747         kfifo_free(&sensor_inst->data_fifo);
748
749 }
750
751 /* luid defined in FW (e.g. ISH).  Maybe used to identify sensor. */
752 static const char *const known_sensor_luid[] = { "020B000000000000" };
753
754 static int get_luid_table_index(unsigned char *usage_str)
755 {
756         int i;
757
758         for (i = 0; i < ARRAY_SIZE(known_sensor_luid); i++) {
759                 if (!strncmp(usage_str, known_sensor_luid[i],
760                              strlen(known_sensor_luid[i])))
761                         return i;
762         }
763
764         return -ENODEV;
765 }
766
767 static int get_known_custom_sensor_index(struct hid_sensor_hub_device *hsdev)
768 {
769         struct hid_sensor_hub_attribute_info sensor_manufacturer = { 0 };
770         struct hid_sensor_hub_attribute_info sensor_luid_info = { 0 };
771         int report_size;
772         int ret;
773         static u16 w_buf[HID_CUSTOM_MAX_FEATURE_BYTES];
774         static char buf[HID_CUSTOM_MAX_FEATURE_BYTES];
775         int i;
776
777         memset(w_buf, 0, sizeof(w_buf));
778         memset(buf, 0, sizeof(buf));
779
780         /* get manufacturer info */
781         ret = sensor_hub_input_get_attribute_info(hsdev,
782                         HID_FEATURE_REPORT, hsdev->usage,
783                         HID_USAGE_SENSOR_PROP_MANUFACTURER, &sensor_manufacturer);
784         if (ret < 0)
785                 return ret;
786
787         report_size =
788                 sensor_hub_get_feature(hsdev, sensor_manufacturer.report_id,
789                                        sensor_manufacturer.index, sizeof(w_buf),
790                                        w_buf);
791         if (report_size <= 0) {
792                 hid_err(hsdev->hdev,
793                         "Failed to get sensor manufacturer info %d\n",
794                         report_size);
795                 return -ENODEV;
796         }
797
798         /* convert from wide char to char */
799         for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
800                 buf[i] = (char)w_buf[i];
801
802         /* ensure it's ISH sensor */
803         if (strncmp(buf, "INTEL", strlen("INTEL")))
804                 return -ENODEV;
805
806         memset(w_buf, 0, sizeof(w_buf));
807         memset(buf, 0, sizeof(buf));
808
809         /* get real usage id */
810         ret = sensor_hub_input_get_attribute_info(hsdev,
811                         HID_FEATURE_REPORT, hsdev->usage,
812                         HID_USAGE_SENSOR_PROP_SERIAL_NUM, &sensor_luid_info);
813         if (ret < 0)
814                 return ret;
815
816         report_size = sensor_hub_get_feature(hsdev, sensor_luid_info.report_id,
817                                              sensor_luid_info.index, sizeof(w_buf),
818                                              w_buf);
819         if (report_size <= 0) {
820                 hid_err(hsdev->hdev, "Failed to get real usage info %d\n",
821                         report_size);
822                 return -ENODEV;
823         }
824
825         /* convert from wide char to char */
826         for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
827                 buf[i] = (char)w_buf[i];
828
829         if (strlen(buf) != strlen(known_sensor_luid[0]) + 5) {
830                 hid_err(hsdev->hdev,
831                         "%s luid length not match %zu != (%zu + 5)\n", __func__,
832                         strlen(buf), strlen(known_sensor_luid[0]));
833                 return -ENODEV;
834         }
835
836         /* get table index with luid (not matching 'LUID: ' in luid) */
837         return get_luid_table_index(&buf[5]);
838 }
839
840 static struct platform_device *
841 hid_sensor_register_platform_device(struct platform_device *pdev,
842                                     struct hid_sensor_hub_device *hsdev,
843                                     int index)
844 {
845         char real_usage[HID_SENSOR_USAGE_LENGTH] = { 0 };
846         struct platform_device *custom_pdev;
847         const char *dev_name;
848         char *c;
849
850         /* copy real usage id */
851         memcpy(real_usage, known_sensor_luid[index], 4);
852
853         /* usage id are all lowcase */
854         for (c = real_usage; *c != '\0'; c++)
855                 *c = tolower(*c);
856
857         /* HID-SENSOR-INT-REAL_USAGE_ID */
858         dev_name = kasprintf(GFP_KERNEL, "HID-SENSOR-INT-%s", real_usage);
859         if (!dev_name)
860                 return ERR_PTR(-ENOMEM);
861
862         custom_pdev = platform_device_register_data(pdev->dev.parent, dev_name,
863                                                     PLATFORM_DEVID_NONE, hsdev,
864                                                     sizeof(*hsdev));
865         kfree(dev_name);
866         return custom_pdev;
867 }
868
869 static int hid_sensor_custom_probe(struct platform_device *pdev)
870 {
871         struct hid_sensor_custom *sensor_inst;
872         struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
873         int ret;
874         int index;
875
876         sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst),
877                                    GFP_KERNEL);
878         if (!sensor_inst)
879                 return -ENOMEM;
880
881         sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample;
882         sensor_inst->callbacks.send_event = hid_sensor_send_event;
883         sensor_inst->callbacks.pdev = pdev;
884         sensor_inst->hsdev = hsdev;
885         sensor_inst->pdev = pdev;
886         mutex_init(&sensor_inst->mutex);
887         platform_set_drvdata(pdev, sensor_inst);
888
889         index = get_known_custom_sensor_index(hsdev);
890         if (index >= 0 && index < ARRAY_SIZE(known_sensor_luid)) {
891                 sensor_inst->custom_pdev =
892                         hid_sensor_register_platform_device(pdev, hsdev, index);
893
894                 ret = PTR_ERR_OR_ZERO(sensor_inst->custom_pdev);
895                 if (ret) {
896                         dev_err(&pdev->dev,
897                                 "register_platform_device failed\n");
898                         return ret;
899                 }
900
901                 return 0;
902         }
903
904         ret = sensor_hub_register_callback(hsdev, hsdev->usage,
905                                            &sensor_inst->callbacks);
906         if (ret < 0) {
907                 dev_err(&pdev->dev, "callback reg failed\n");
908                 return ret;
909         }
910
911         ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
912                                  &enable_sensor_attr_group);
913         if (ret)
914                 goto err_remove_callback;
915
916         ret = hid_sensor_custom_add_attributes(sensor_inst);
917         if (ret)
918                 goto err_remove_group;
919
920         ret = hid_sensor_custom_dev_if_add(sensor_inst);
921         if (ret)
922                 goto err_remove_attributes;
923
924         return 0;
925
926 err_remove_attributes:
927         hid_sensor_custom_remove_attributes(sensor_inst);
928 err_remove_group:
929         sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
930                            &enable_sensor_attr_group);
931 err_remove_callback:
932         sensor_hub_remove_callback(hsdev, hsdev->usage);
933
934         return ret;
935 }
936
937 static int hid_sensor_custom_remove(struct platform_device *pdev)
938 {
939         struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev);
940         struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
941
942         if (sensor_inst->custom_pdev) {
943                 platform_device_unregister(sensor_inst->custom_pdev);
944                 return 0;
945         }
946
947         hid_sensor_custom_dev_if_remove(sensor_inst);
948         hid_sensor_custom_remove_attributes(sensor_inst);
949         sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
950                            &enable_sensor_attr_group);
951         sensor_hub_remove_callback(hsdev, hsdev->usage);
952
953         return 0;
954 }
955
956 static const struct platform_device_id hid_sensor_custom_ids[] = {
957         {
958                 .name = "HID-SENSOR-2000e1",
959         },
960         {
961                 .name = "HID-SENSOR-2000e2",
962         },
963         { /* sentinel */ }
964 };
965 MODULE_DEVICE_TABLE(platform, hid_sensor_custom_ids);
966
967 static struct platform_driver hid_sensor_custom_platform_driver = {
968         .id_table = hid_sensor_custom_ids,
969         .driver = {
970                 .name   = KBUILD_MODNAME,
971         },
972         .probe          = hid_sensor_custom_probe,
973         .remove         = hid_sensor_custom_remove,
974 };
975 module_platform_driver(hid_sensor_custom_platform_driver);
976
977 MODULE_DESCRIPTION("HID Sensor Custom and Generic sensor Driver");
978 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
979 MODULE_LICENSE("GPL");