cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hid-sensor-custom.c (27720B)


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