// 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[HID_CUSTOM_TOTAL_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_AUTO, 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");
