// SPDX-License-Identifier: GPL-2.0-only
/*
 * hid-sensor-custom.c
 * Copyright (c) 2015, Intel Corporation.
 */

#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/kfifo.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/bsearch.h>
#include <linux/platform_device.h>
#include <linux/hid-sensor-hub.h>

#define HID_CUSTOM_NAME_LENGTH		64
#define HID_CUSTOM_MAX_CORE_ATTRS	10
#define HID_CUSTOM_TOTAL_ATTRS		(HID_CUSTOM_MAX_CORE_ATTRS + 1)
#define HID_CUSTOM_FIFO_SIZE		4096
#define HID_CUSTOM_MAX_FEATURE_BYTES	64
#define HID_SENSOR_USAGE_LENGTH (4 + 1)

struct hid_sensor_custom_field {
	int report_id;
	char group_name[HID_CUSTOM_NAME_LENGTH];
	struct hid_sensor_hub_attribute_info attribute;
	struct device_attribute sd_attrs[HID_CUSTOM_MAX_CORE_ATTRS];
	char attr_name[HID_CUSTOM_TOTAL_ATTRS][HID_CUSTOM_NAME_LENGTH];
	struct attribute *attrs[HID_CUSTOM_TOTAL_ATTRS];
	struct attribute_group hid_custom_attribute_group;
};

struct hid_sensor_custom {
	struct mutex mutex;
	struct platform_device *pdev;
	struct hid_sensor_hub_device *hsdev;
	struct hid_sensor_hub_callbacks callbacks;
	int sensor_field_count;
	struct hid_sensor_custom_field *fields;
	int input_field_count;
	int input_report_size;
	int input_report_recd_size;
	bool input_skip_sample;
	bool enable;
	struct hid_sensor_custom_field *power_state;
	struct hid_sensor_custom_field *report_state;
	struct miscdevice custom_dev;
	struct kfifo data_fifo;
	unsigned long misc_opened;
	wait_queue_head_t wait;
	struct platform_device *custom_pdev;
};

/* Header for each sample to user space via dev interface */
struct hid_sensor_sample {
	u32 usage_id;
	u64 timestamp;
	u32 raw_len;
} __packed;

static struct attribute hid_custom_attrs[] = {
	{.name = "name", .mode = S_IRUGO},
	{.name = "units", .mode = S_IRUGO},
	{.name = "unit-expo", .mode = S_IRUGO},
	{.name = "minimum", .mode = S_IRUGO},
	{.name = "maximum", .mode = S_IRUGO},
	{.name = "size", .mode = S_IRUGO},
	{.name = "value", .mode = S_IWUSR | S_IRUGO},
	{.name = NULL}
};

static const struct hid_custom_usage_desc {
	int usage_id;
	char *desc;
} hid_custom_usage_desc_table[] = {
	{0x200201,	"event-sensor-state"},
	{0x200202,	"event-sensor-event"},
	{0x200301,	"property-friendly-name"},
	{0x200302,	"property-persistent-unique-id"},
	{0x200303,	"property-sensor-status"},
	{0x200304,	"property-min-report-interval"},
	{0x200305,	"property-sensor-manufacturer"},
	{0x200306,	"property-sensor-model"},
	{0x200307,	"property-sensor-serial-number"},
	{0x200308,	"property-sensor-description"},
	{0x200309,	"property-sensor-connection-type"},
	{0x20030A,	"property-sensor-device-path"},
	{0x20030B,	"property-hardware-revision"},
	{0x20030C,	"property-firmware-version"},
	{0x20030D,	"property-release-date"},
	{0x20030E,	"property-report-interval"},
	{0x20030F,	"property-change-sensitivity-absolute"},
	{0x200310,	"property-change-sensitivity-percent-range"},
	{0x200311,	"property-change-sensitivity-percent-relative"},
	{0x200312,	"property-accuracy"},
	{0x200313,	"property-resolution"},
	{0x200314,	"property-maximum"},
	{0x200315,	"property-minimum"},
	{0x200316,	"property-reporting-state"},
	{0x200317,	"property-sampling-rate"},
	{0x200318,	"property-response-curve"},
	{0x200319,	"property-power-state"},
	{0x200540,	"data-field-custom"},
	{0x200541,	"data-field-custom-usage"},
	{0x200542,	"data-field-custom-boolean-array"},
	{0x200543,	"data-field-custom-value"},
	{0x200544,	"data-field-custom-value_1"},
	{0x200545,	"data-field-custom-value_2"},
	{0x200546,	"data-field-custom-value_3"},
	{0x200547,	"data-field-custom-value_4"},
	{0x200548,	"data-field-custom-value_5"},
	{0x200549,	"data-field-custom-value_6"},
	{0x20054A,	"data-field-custom-value_7"},
	{0x20054B,	"data-field-custom-value_8"},
	{0x20054C,	"data-field-custom-value_9"},
	{0x20054D,	"data-field-custom-value_10"},
	{0x20054E,	"data-field-custom-value_11"},
	{0x20054F,	"data-field-custom-value_12"},
	{0x200550,	"data-field-custom-value_13"},
	{0x200551,	"data-field-custom-value_14"},
	{0x200552,	"data-field-custom-value_15"},
	{0x200553,	"data-field-custom-value_16"},
	{0x200554,	"data-field-custom-value_17"},
	{0x200555,	"data-field-custom-value_18"},
	{0x200556,	"data-field-custom-value_19"},
	{0x200557,	"data-field-custom-value_20"},
	{0x200558,	"data-field-custom-value_21"},
	{0x200559,	"data-field-custom-value_22"},
	{0x20055A,	"data-field-custom-value_23"},
	{0x20055B,	"data-field-custom-value_24"},
	{0x20055C,	"data-field-custom-value_25"},
	{0x20055D,	"data-field-custom-value_26"},
	{0x20055E,	"data-field-custom-value_27"},
	{0x20055F,	"data-field-custom-value_28"},
};

static int usage_id_cmp(const void *p1, const void *p2)
{
	if (*(int *)p1 < *(int *)p2)
		return -1;

	if (*(int *)p1 > *(int *)p2)
		return 1;

	return 0;
}

static ssize_t enable_sensor_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);

	return sprintf(buf, "%d\n", sensor_inst->enable);
}

static int set_power_report_state(struct hid_sensor_custom *sensor_inst,
				  bool state)
{
	int power_val = -1;
	int report_val = -1;
	u32 power_state_usage_id;
	u32 report_state_usage_id;
	int ret;

	/*
	 * It is possible that the power/report state ids are not present.
	 * In this case this function will return success. But if the
	 * ids are present, then it will return error if set fails.
	 */
	if (state) {
		power_state_usage_id =
			HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
		report_state_usage_id =
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
	} else {
		power_state_usage_id =
			HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM;
		report_state_usage_id =
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM;
	}

	if (sensor_inst->power_state)
		power_val = hid_sensor_get_usage_index(sensor_inst->hsdev,
				sensor_inst->power_state->attribute.report_id,
				sensor_inst->power_state->attribute.index,
				power_state_usage_id);
	if (sensor_inst->report_state)
		report_val = hid_sensor_get_usage_index(sensor_inst->hsdev,
				sensor_inst->report_state->attribute.report_id,
				sensor_inst->report_state->attribute.index,
				report_state_usage_id);

	if (power_val >= 0) {
		power_val +=
			sensor_inst->power_state->attribute.logical_minimum;
		ret = sensor_hub_set_feature(sensor_inst->hsdev,
				sensor_inst->power_state->attribute.report_id,
				sensor_inst->power_state->attribute.index,
				sizeof(power_val),
				&power_val);
		if (ret) {
			hid_err(sensor_inst->hsdev->hdev,
				"Set power state failed\n");
			return ret;
		}
	}

	if (report_val >= 0) {
		report_val +=
			sensor_inst->report_state->attribute.logical_minimum;
		ret = sensor_hub_set_feature(sensor_inst->hsdev,
				sensor_inst->report_state->attribute.report_id,
				sensor_inst->report_state->attribute.index,
				sizeof(report_val),
				&report_val);
		if (ret) {
			hid_err(sensor_inst->hsdev->hdev,
				"Set report state failed\n");
			return ret;
		}
	}

	return 0;
}

static ssize_t enable_sensor_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
	int value;
	int ret = -EINVAL;

	if (kstrtoint(buf, 0, &value) != 0)
		return -EINVAL;

	mutex_lock(&sensor_inst->mutex);
	if (value && !sensor_inst->enable) {
		ret = sensor_hub_device_open(sensor_inst->hsdev);
		if (ret)
			goto unlock_state;

		ret = set_power_report_state(sensor_inst, true);
		if (ret) {
			sensor_hub_device_close(sensor_inst->hsdev);
			goto unlock_state;
		}
		sensor_inst->enable = true;
	} else if (!value && sensor_inst->enable) {
		ret = set_power_report_state(sensor_inst, false);
		sensor_hub_device_close(sensor_inst->hsdev);
		sensor_inst->enable = false;
	}
unlock_state:
	mutex_unlock(&sensor_inst->mutex);
	if (ret < 0)
		return ret;

	return count;
}
static DEVICE_ATTR_RW(enable_sensor);

static struct attribute *enable_sensor_attrs[] = {
	&dev_attr_enable_sensor.attr,
	NULL,
};

static const struct attribute_group enable_sensor_attr_group = {
	.attrs = enable_sensor_attrs,
};

static ssize_t show_value(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
	struct hid_sensor_hub_attribute_info *attribute;
	int index, usage, field_index;
	char name[HID_CUSTOM_NAME_LENGTH];
	bool feature = false;
	bool input = false;
	int value = 0;

	if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
		   name) == 3) {
		feature = true;
		field_index = index + sensor_inst->input_field_count;
	} else if (sscanf(attr->attr.name, "input-%x-%x-%s", &index, &usage,
		   name) == 3) {
		input = true;
		field_index = index;
	} else
		return -EINVAL;

	if (!strncmp(name, "value", strlen("value"))) {
		u32 report_id;
		int ret;

		attribute = &sensor_inst->fields[field_index].attribute;
		report_id = attribute->report_id;
		if (feature) {
			u8 values[HID_CUSTOM_MAX_FEATURE_BYTES];
			int len = 0;
			u64 value = 0;
			int i = 0;

			ret = sensor_hub_get_feature(sensor_inst->hsdev,
						     report_id,
						     index,
						     sizeof(values), values);
			if (ret < 0)
				return ret;

			while (i < ret) {
				if (i + attribute->size > ret) {
					len += scnprintf(&buf[len],
							PAGE_SIZE - len,
							"%d ", values[i]);
					break;
				}
				switch (attribute->size) {
				case 2:
					value = (u64) *(u16 *)&values[i];
					i += attribute->size;
					break;
				case 4:
					value = (u64) *(u32 *)&values[i];
					i += attribute->size;
					break;
				case 8:
					value = *(u64 *)&values[i];
					i += attribute->size;
					break;
				default:
					value = (u64) values[i];
					++i;
					break;
				}
				len += scnprintf(&buf[len], PAGE_SIZE - len,
						"%lld ", value);
			}
			len += scnprintf(&buf[len], PAGE_SIZE - len, "\n");

			return len;
		} else if (input)
			value = sensor_hub_input_attr_get_raw_value(
						sensor_inst->hsdev,
						sensor_inst->hsdev->usage,
						usage, report_id,
						SENSOR_HUB_SYNC, false);
	} else if (!strncmp(name, "units", strlen("units")))
		value = sensor_inst->fields[field_index].attribute.units;
	else if (!strncmp(name, "unit-expo", strlen("unit-expo")))
		value = sensor_inst->fields[field_index].attribute.unit_expo;
	else if (!strncmp(name, "size", strlen("size")))
		value = sensor_inst->fields[field_index].attribute.size;
	else if (!strncmp(name, "minimum", strlen("minimum")))
		value = sensor_inst->fields[field_index].attribute.
							logical_minimum;
	else if (!strncmp(name, "maximum", strlen("maximum")))
		value = sensor_inst->fields[field_index].attribute.
							logical_maximum;
	else if (!strncmp(name, "name", strlen("name"))) {
		struct hid_custom_usage_desc *usage_desc;

		usage_desc = bsearch(&usage, hid_custom_usage_desc_table,
				     ARRAY_SIZE(hid_custom_usage_desc_table),
				     sizeof(struct hid_custom_usage_desc),
				     usage_id_cmp);
		if (usage_desc)
			return snprintf(buf, PAGE_SIZE, "%s\n",
					usage_desc->desc);
		else
			return sprintf(buf, "not-specified\n");
	 } else
		return -EINVAL;

	return sprintf(buf, "%d\n", value);
}

static ssize_t store_value(struct device *dev, struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct hid_sensor_custom *sensor_inst = dev_get_drvdata(dev);
	int index, field_index, usage;
	char name[HID_CUSTOM_NAME_LENGTH];
	int value, ret;

	if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
		   name) == 3) {
		field_index = index + sensor_inst->input_field_count;
	} else
		return -EINVAL;

	if (!strncmp(name, "value", strlen("value"))) {
		u32 report_id;

		if (kstrtoint(buf, 0, &value) != 0)
			return -EINVAL;

		report_id = sensor_inst->fields[field_index].attribute.
								report_id;
		ret = sensor_hub_set_feature(sensor_inst->hsdev, report_id,
					     index, sizeof(value), &value);
		if (ret)
			return ret;
	} else
		return -EINVAL;

	return count;
}

static int hid_sensor_capture_sample(struct hid_sensor_hub_device *hsdev,
				  unsigned usage_id, size_t raw_len,
				  char *raw_data, void *priv)
{
	struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);
	struct hid_sensor_sample header;

	/* If any error occurs in a sample, rest of the fields are ignored */
	if (sensor_inst->input_skip_sample) {
		hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n");
		return 0;
	}

	hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__,
		(int) (sensor_inst->input_report_recd_size + raw_len),
		sensor_inst->input_report_size);

	if (!test_bit(0, &sensor_inst->misc_opened))
		return 0;

	if (!sensor_inst->input_report_recd_size) {
		int required_size = sizeof(struct hid_sensor_sample) +
						sensor_inst->input_report_size;
		header.usage_id = hsdev->usage;
		header.raw_len = sensor_inst->input_report_size;
		header.timestamp = ktime_get_real_ns();
		if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) {
			kfifo_in(&sensor_inst->data_fifo,
				 (unsigned char *)&header,
				 sizeof(header));
		} else
			sensor_inst->input_skip_sample = true;
	}
	if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len)
		kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data,
			 raw_len);

	sensor_inst->input_report_recd_size += raw_len;

	return 0;
}

static int hid_sensor_send_event(struct hid_sensor_hub_device *hsdev,
				 unsigned usage_id, void *priv)
{
	struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv);

	if (!test_bit(0, &sensor_inst->misc_opened))
		return 0;

	sensor_inst->input_report_recd_size = 0;
	sensor_inst->input_skip_sample = false;

	wake_up(&sensor_inst->wait);

	return 0;
}

static int hid_sensor_custom_add_field(struct hid_sensor_custom *sensor_inst,
				       int index, int report_type,
				       struct hid_report *report,
				       struct hid_field *field)
{
	struct hid_sensor_custom_field *sensor_field;
	void *fields;

	fields = krealloc(sensor_inst->fields,
			  (sensor_inst->sensor_field_count + 1) *
			   sizeof(struct hid_sensor_custom_field), GFP_KERNEL);
	if (!fields) {
		kfree(sensor_inst->fields);
		return -ENOMEM;
	}
	sensor_inst->fields = fields;
	sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count];
	sensor_field->attribute.usage_id = sensor_inst->hsdev->usage;
	if (field->logical)
		sensor_field->attribute.attrib_id = field->logical;
	else
		sensor_field->attribute.attrib_id = field->usage[0].hid;

	sensor_field->attribute.index = index;
	sensor_field->attribute.report_id = report->id;
	sensor_field->attribute.units = field->unit;
	sensor_field->attribute.unit_expo = field->unit_exponent;
	sensor_field->attribute.size = (field->report_size / 8);
	sensor_field->attribute.logical_minimum = field->logical_minimum;
	sensor_field->attribute.logical_maximum = field->logical_maximum;

	if (report_type == HID_FEATURE_REPORT)
		snprintf(sensor_field->group_name,
			 sizeof(sensor_field->group_name), "feature-%x-%x",
			 sensor_field->attribute.index,
			 sensor_field->attribute.attrib_id);
	else if (report_type == HID_INPUT_REPORT) {
		snprintf(sensor_field->group_name,
			 sizeof(sensor_field->group_name),
			 "input-%x-%x", sensor_field->attribute.index,
			 sensor_field->attribute.attrib_id);
		sensor_inst->input_field_count++;
		sensor_inst->input_report_size += (field->report_size *
						   field->report_count) / 8;
	}

	memset(&sensor_field->hid_custom_attribute_group, 0,
	       sizeof(struct attribute_group));
	sensor_inst->sensor_field_count++;

	return 0;
}

static int hid_sensor_custom_add_fields(struct hid_sensor_custom *sensor_inst,
					struct hid_report_enum *report_enum,
					int report_type)
{
	int i;
	int ret;
	struct hid_report *report;
	struct hid_field *field;
	struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;

	list_for_each_entry(report, &report_enum->report_list, list) {
		for (i = 0; i < report->maxfield; ++i) {
			field = report->field[i];
			if (field->maxusage &&
			    ((field->usage[0].collection_index >=
			      hsdev->start_collection_index) &&
			      (field->usage[0].collection_index <
			       hsdev->end_collection_index))) {

				ret = hid_sensor_custom_add_field(sensor_inst,
								  i,
								  report_type,
								  report,
								  field);
				if (ret)
					return ret;

			}
		}
	}

	return 0;
}

static int hid_sensor_custom_add_attributes(struct hid_sensor_custom
								*sensor_inst)
{
	struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev;
	struct hid_device *hdev = hsdev->hdev;
	int ret = -1;
	int i, j;

	for (j = 0; j < HID_REPORT_TYPES; ++j) {
		if (j == HID_OUTPUT_REPORT)
			continue;

		ret = hid_sensor_custom_add_fields(sensor_inst,
						   &hdev->report_enum[j], j);
		if (ret)
			return ret;

	}

	/* Create sysfs attributes */
	for (i = 0; i < sensor_inst->sensor_field_count; ++i) {
		j = 0;
		while (j < HID_CUSTOM_TOTAL_ATTRS &&
		       hid_custom_attrs[j].name) {
			struct device_attribute *device_attr;

			device_attr = &sensor_inst->fields[i].sd_attrs[j];

			snprintf((char *)&sensor_inst->fields[i].attr_name[j],
				 HID_CUSTOM_NAME_LENGTH, "%s-%s",
				 sensor_inst->fields[i].group_name,
				 hid_custom_attrs[j].name);
			sysfs_attr_init(&device_attr->attr);
			device_attr->attr.name =
				(char *)&sensor_inst->fields[i].attr_name[j];
			device_attr->attr.mode = hid_custom_attrs[j].mode;
			device_attr->show = show_value;
			if (hid_custom_attrs[j].mode & S_IWUSR)
				device_attr->store = store_value;
			sensor_inst->fields[i].attrs[j] = &device_attr->attr;
			++j;
		}
		sensor_inst->fields[i].attrs[j] = NULL;
		sensor_inst->fields[i].hid_custom_attribute_group.attrs =
						sensor_inst->fields[i].attrs;
		sensor_inst->fields[i].hid_custom_attribute_group.name =
					sensor_inst->fields[i].group_name;
		ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
					 &sensor_inst->fields[i].
					 hid_custom_attribute_group);
		if (ret)
			break;

		/* For power or report field store indexes */
		if (sensor_inst->fields[i].attribute.attrib_id ==
					HID_USAGE_SENSOR_PROY_POWER_STATE)
			sensor_inst->power_state = &sensor_inst->fields[i];
		else if (sensor_inst->fields[i].attribute.attrib_id ==
					HID_USAGE_SENSOR_PROP_REPORT_STATE)
			sensor_inst->report_state = &sensor_inst->fields[i];
	}

	return ret;
}

static void hid_sensor_custom_remove_attributes(struct hid_sensor_custom *
								sensor_inst)
{
	int i;

	for (i = 0; i < sensor_inst->sensor_field_count; ++i)
		sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
				   &sensor_inst->fields[i].
				   hid_custom_attribute_group);

	kfree(sensor_inst->fields);
}

static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf,
				      size_t count, loff_t *f_ps)
{
	struct hid_sensor_custom *sensor_inst;
	unsigned int copied;
	int ret;

	sensor_inst = container_of(file->private_data,
				   struct hid_sensor_custom, custom_dev);

	if (count < sizeof(struct hid_sensor_sample))
		return -EINVAL;

	do {
		if (kfifo_is_empty(&sensor_inst->data_fifo)) {
			if (file->f_flags & O_NONBLOCK)
				return -EAGAIN;

			ret = wait_event_interruptible(sensor_inst->wait,
				!kfifo_is_empty(&sensor_inst->data_fifo));
			if (ret)
				return ret;
		}
		ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count,
				    &copied);
		if (ret)
			return ret;

	} while (copied == 0);

	return copied;
}

static int hid_sensor_custom_release(struct inode *inode, struct file *file)
{
	struct hid_sensor_custom *sensor_inst;

	sensor_inst = container_of(file->private_data,
				   struct hid_sensor_custom, custom_dev);

	clear_bit(0, &sensor_inst->misc_opened);

	return 0;
}

static int hid_sensor_custom_open(struct inode *inode, struct file *file)
{
	struct hid_sensor_custom *sensor_inst;

	sensor_inst = container_of(file->private_data,
				   struct hid_sensor_custom, custom_dev);
	/* We essentially have single reader and writer */
	if (test_and_set_bit(0, &sensor_inst->misc_opened))
		return -EBUSY;

	return stream_open(inode, file);
}

static __poll_t hid_sensor_custom_poll(struct file *file,
					   struct poll_table_struct *wait)
{
	struct hid_sensor_custom *sensor_inst;
	__poll_t mask = 0;

	sensor_inst = container_of(file->private_data,
				   struct hid_sensor_custom, custom_dev);

	poll_wait(file, &sensor_inst->wait, wait);

	if (!kfifo_is_empty(&sensor_inst->data_fifo))
		mask = EPOLLIN | EPOLLRDNORM;

	return mask;
}

static const struct file_operations hid_sensor_custom_fops = {
	.open =  hid_sensor_custom_open,
	.read =  hid_sensor_custom_read,
	.release = hid_sensor_custom_release,
	.poll = hid_sensor_custom_poll,
	.llseek = noop_llseek,
};

static int hid_sensor_custom_dev_if_add(struct hid_sensor_custom *sensor_inst)
{
	int ret;

	ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE,
			  GFP_KERNEL);
	if (ret)
		return ret;

	init_waitqueue_head(&sensor_inst->wait);

	sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR;
	sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev);
	sensor_inst->custom_dev.fops = &hid_sensor_custom_fops,
	ret = misc_register(&sensor_inst->custom_dev);
	if (ret) {
		kfifo_free(&sensor_inst->data_fifo);
		return ret;
	}
	return 0;
}

static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom
								*sensor_inst)
{
	wake_up(&sensor_inst->wait);
	misc_deregister(&sensor_inst->custom_dev);
	kfifo_free(&sensor_inst->data_fifo);

}

/* luid defined in FW (e.g. ISH).  Maybe used to identify sensor. */
static const char *const known_sensor_luid[] = { "020B000000000000" };

static int get_luid_table_index(unsigned char *usage_str)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(known_sensor_luid); i++) {
		if (!strncmp(usage_str, known_sensor_luid[i],
			     strlen(known_sensor_luid[i])))
			return i;
	}

	return -ENODEV;
}

static int get_known_custom_sensor_index(struct hid_sensor_hub_device *hsdev)
{
	struct hid_sensor_hub_attribute_info sensor_manufacturer = { 0 };
	struct hid_sensor_hub_attribute_info sensor_luid_info = { 0 };
	int report_size;
	int ret;
	static u16 w_buf[HID_CUSTOM_MAX_FEATURE_BYTES];
	static char buf[HID_CUSTOM_MAX_FEATURE_BYTES];
	int i;

	memset(w_buf, 0, sizeof(w_buf));
	memset(buf, 0, sizeof(buf));

	/* get manufacturer info */
	ret = sensor_hub_input_get_attribute_info(hsdev,
			HID_FEATURE_REPORT, hsdev->usage,
			HID_USAGE_SENSOR_PROP_MANUFACTURER, &sensor_manufacturer);
	if (ret < 0)
		return ret;

	report_size =
		sensor_hub_get_feature(hsdev, sensor_manufacturer.report_id,
				       sensor_manufacturer.index, sizeof(w_buf),
				       w_buf);
	if (report_size <= 0) {
		hid_err(hsdev->hdev,
			"Failed to get sensor manufacturer info %d\n",
			report_size);
		return -ENODEV;
	}

	/* convert from wide char to char */
	for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
		buf[i] = (char)w_buf[i];

	/* ensure it's ISH sensor */
	if (strncmp(buf, "INTEL", strlen("INTEL")))
		return -ENODEV;

	memset(w_buf, 0, sizeof(w_buf));
	memset(buf, 0, sizeof(buf));

	/* get real usage id */
	ret = sensor_hub_input_get_attribute_info(hsdev,
			HID_FEATURE_REPORT, hsdev->usage,
			HID_USAGE_SENSOR_PROP_SERIAL_NUM, &sensor_luid_info);
	if (ret < 0)
		return ret;

	report_size = sensor_hub_get_feature(hsdev, sensor_luid_info.report_id,
					     sensor_luid_info.index, sizeof(w_buf),
					     w_buf);
	if (report_size <= 0) {
		hid_err(hsdev->hdev, "Failed to get real usage info %d\n",
			report_size);
		return -ENODEV;
	}

	/* convert from wide char to char */
	for (i = 0; i < ARRAY_SIZE(buf) - 1 && w_buf[i]; i++)
		buf[i] = (char)w_buf[i];

	if (strlen(buf) != strlen(known_sensor_luid[0]) + 5) {
		hid_err(hsdev->hdev,
			"%s luid length not match %zu != (%zu + 5)\n", __func__,
			strlen(buf), strlen(known_sensor_luid[0]));
		return -ENODEV;
	}

	/* get table index with luid (not matching 'LUID: ' in luid) */
	return get_luid_table_index(&buf[5]);
}

static struct platform_device *
hid_sensor_register_platform_device(struct platform_device *pdev,
				    struct hid_sensor_hub_device *hsdev,
				    int index)
{
	char real_usage[HID_SENSOR_USAGE_LENGTH] = { 0 };
	struct platform_device *custom_pdev;
	const char *dev_name;
	char *c;

	/* copy real usage id */
	memcpy(real_usage, known_sensor_luid[index], 4);

	/* usage id are all lowcase */
	for (c = real_usage; *c != '\0'; c++)
		*c = tolower(*c);

	/* HID-SENSOR-INT-REAL_USAGE_ID */
	dev_name = kasprintf(GFP_KERNEL, "HID-SENSOR-INT-%s", real_usage);
	if (!dev_name)
		return ERR_PTR(-ENOMEM);

	custom_pdev = platform_device_register_data(pdev->dev.parent, dev_name,
						    PLATFORM_DEVID_NONE, hsdev,
						    sizeof(*hsdev));
	kfree(dev_name);
	return custom_pdev;
}

static int hid_sensor_custom_probe(struct platform_device *pdev)
{
	struct hid_sensor_custom *sensor_inst;
	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
	int ret;
	int index;

	sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst),
				   GFP_KERNEL);
	if (!sensor_inst)
		return -ENOMEM;

	sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample;
	sensor_inst->callbacks.send_event = hid_sensor_send_event;
	sensor_inst->callbacks.pdev = pdev;
	sensor_inst->hsdev = hsdev;
	sensor_inst->pdev = pdev;
	mutex_init(&sensor_inst->mutex);
	platform_set_drvdata(pdev, sensor_inst);

	index = get_known_custom_sensor_index(hsdev);
	if (index >= 0 && index < ARRAY_SIZE(known_sensor_luid)) {
		sensor_inst->custom_pdev =
			hid_sensor_register_platform_device(pdev, hsdev, index);

		ret = PTR_ERR_OR_ZERO(sensor_inst->custom_pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"register_platform_device failed\n");
			return ret;
		}

		return 0;
	}

	ret = sensor_hub_register_callback(hsdev, hsdev->usage,
					   &sensor_inst->callbacks);
	if (ret < 0) {
		dev_err(&pdev->dev, "callback reg failed\n");
		return ret;
	}

	ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
				 &enable_sensor_attr_group);
	if (ret)
		goto err_remove_callback;

	ret = hid_sensor_custom_add_attributes(sensor_inst);
	if (ret)
		goto err_remove_group;

	ret = hid_sensor_custom_dev_if_add(sensor_inst);
	if (ret)
		goto err_remove_attributes;

	return 0;

err_remove_attributes:
	hid_sensor_custom_remove_attributes(sensor_inst);
err_remove_group:
	sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
			   &enable_sensor_attr_group);
err_remove_callback:
	sensor_hub_remove_callback(hsdev, hsdev->usage);

	return ret;
}

static int hid_sensor_custom_remove(struct platform_device *pdev)
{
	struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev);
	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;

	if (sensor_inst->custom_pdev) {
		platform_device_unregister(sensor_inst->custom_pdev);
		return 0;
	}

	hid_sensor_custom_dev_if_remove(sensor_inst);
	hid_sensor_custom_remove_attributes(sensor_inst);
	sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
			   &enable_sensor_attr_group);
	sensor_hub_remove_callback(hsdev, hsdev->usage);

	return 0;
}

static const struct platform_device_id hid_sensor_custom_ids[] = {
	{
		.name = "HID-SENSOR-2000e1",
	},
	{
		.name = "HID-SENSOR-2000e2",
	},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_sensor_custom_ids);

static struct platform_driver hid_sensor_custom_platform_driver = {
	.id_table = hid_sensor_custom_ids,
	.driver = {
		.name	= KBUILD_MODNAME,
	},
	.probe		= hid_sensor_custom_probe,
	.remove		= hid_sensor_custom_remove,
};
module_platform_driver(hid_sensor_custom_platform_driver);

MODULE_DESCRIPTION("HID Sensor Custom and Generic sensor Driver");
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL");
