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