/*
 * HID class driver for the Greybus.
 *
 * Copyright 2014 Google Inc.
 * Copyright 2014 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */

#include <linux/bitops.h>
#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>

#include "greybus.h"

/* Greybus HID device's structure */
struct gb_hid {
	struct gb_bundle *bundle;
	struct gb_connection		*connection;

	struct hid_device		*hid;
	struct gb_hid_desc_response	hdesc;

	unsigned long			flags;
#define GB_HID_STARTED			0x01
#define GB_HID_READ_PENDING		0x04

	unsigned int			bufsize;
	char				*inbuf;
};

/* Routines to get controller's information over greybus */

/* Operations performed on greybus */
static int gb_hid_get_desc(struct gb_hid *ghid)
{
	return gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_DESC, NULL,
				 0, &ghid->hdesc, sizeof(ghid->hdesc));
}

static int gb_hid_get_report_desc(struct gb_hid *ghid, char *rdesc)
{
	int ret;

	ret = gb_pm_runtime_get_sync(ghid->bundle);
	if (ret)
		return ret;

	ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT_DESC,
				 NULL, 0, rdesc,
				 le16_to_cpu(ghid->hdesc.wReportDescLength));

	gb_pm_runtime_put_autosuspend(ghid->bundle);

	return ret;
}

static int gb_hid_set_power(struct gb_hid *ghid, int type)
{
	int ret;

	ret = gb_pm_runtime_get_sync(ghid->bundle);
	if (ret)
		return ret;

	ret = gb_operation_sync(ghid->connection, type, NULL, 0, NULL, 0);

	gb_pm_runtime_put_autosuspend(ghid->bundle);

	return ret;
}

static int gb_hid_get_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
			     unsigned char *buf, int len)
{
	struct gb_hid_get_report_request request;
	int ret;

	ret = gb_pm_runtime_get_sync(ghid->bundle);
	if (ret)
		return ret;

	request.report_type = report_type;
	request.report_id = report_id;

	ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT,
				 &request, sizeof(request), buf, len);

	gb_pm_runtime_put_autosuspend(ghid->bundle);

	return ret;
}

static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
			     unsigned char *buf, int len)
{
	struct gb_hid_set_report_request *request;
	struct gb_operation *operation;
	int ret, size = sizeof(*request) + len - 1;

	ret = gb_pm_runtime_get_sync(ghid->bundle);
	if (ret)
		return ret;

	operation = gb_operation_create(ghid->connection,
					GB_HID_TYPE_SET_REPORT, size, 0,
					GFP_KERNEL);
	if (!operation) {
		gb_pm_runtime_put_autosuspend(ghid->bundle);
		return -ENOMEM;
	}

	request = operation->request->payload;
	request->report_type = report_type;
	request->report_id = report_id;
	memcpy(request->report, buf, len);

	ret = gb_operation_request_send_sync(operation);
	if (ret) {
		dev_err(&operation->connection->bundle->dev,
			"failed to set report: %d\n", ret);
	} else {
		ret = len;
	}

	gb_operation_put(operation);
	gb_pm_runtime_put_autosuspend(ghid->bundle);

	return ret;
}

static int gb_hid_request_handler(struct gb_operation *op)
{
	struct gb_connection *connection = op->connection;
	struct gb_hid *ghid = gb_connection_get_data(connection);
	struct gb_hid_input_report_request *request = op->request->payload;

	if (op->type != GB_HID_TYPE_IRQ_EVENT) {
		dev_err(&connection->bundle->dev,
			"unsupported unsolicited request\n");
		return -EINVAL;
	}

	if (test_bit(GB_HID_STARTED, &ghid->flags))
		hid_input_report(ghid->hid, HID_INPUT_REPORT,
				 request->report, op->request->payload_size, 1);

	return 0;
}

static int gb_hid_report_len(struct hid_report *report)
{
	return ((report->size - 1) >> 3) + 1 +
		report->device->report_enum[report->type].numbered;
}

static void gb_hid_find_max_report(struct hid_device *hid, unsigned int type,
				   unsigned int *max)
{
	struct hid_report *report;
	unsigned int size;

	list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
		size = gb_hid_report_len(report);
		if (*max < size)
			*max = size;
	}
}

static void gb_hid_free_buffers(struct gb_hid *ghid)
{
	kfree(ghid->inbuf);
	ghid->inbuf = NULL;
	ghid->bufsize = 0;
}

static int gb_hid_alloc_buffers(struct gb_hid *ghid, size_t bufsize)
{
	ghid->inbuf = kzalloc(bufsize, GFP_KERNEL);
	if (!ghid->inbuf)
		return -ENOMEM;

	ghid->bufsize = bufsize;

	return 0;
}

/* Routines dealing with reports */
static void gb_hid_init_report(struct gb_hid *ghid, struct hid_report *report)
{
	unsigned int size;

	size = gb_hid_report_len(report);
	if (gb_hid_get_report(ghid, report->type, report->id, ghid->inbuf,
			      size))
		return;

	/*
	 * hid->driver_lock is held as we are in probe function,
	 * we just need to setup the input fields, so using
	 * hid_report_raw_event is safe.
	 */
	hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1);
}

static void gb_hid_init_reports(struct gb_hid *ghid)
{
	struct hid_device *hid = ghid->hid;
	struct hid_report *report;

	list_for_each_entry(report,
		&hid->report_enum[HID_INPUT_REPORT].report_list, list)
		gb_hid_init_report(ghid, report);

	list_for_each_entry(report,
		&hid->report_enum[HID_FEATURE_REPORT].report_list, list)
		gb_hid_init_report(ghid, report);
}

static int __gb_hid_get_raw_report(struct hid_device *hid,
		unsigned char report_number, __u8 *buf, size_t count,
		unsigned char report_type)
{
	struct gb_hid *ghid = hid->driver_data;
	int ret;

	if (report_type == HID_OUTPUT_REPORT)
		return -EINVAL;

	ret = gb_hid_get_report(ghid, report_type, report_number, buf, count);
	if (!ret)
		ret = count;

	return ret;
}

static int __gb_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
				      size_t len, unsigned char report_type)
{
	struct gb_hid *ghid = hid->driver_data;
	int report_id = buf[0];
	int ret;

	if (report_type == HID_INPUT_REPORT)
		return -EINVAL;

	if (report_id) {
		buf++;
		len--;
	}

	ret = gb_hid_set_report(ghid, report_type, report_id, buf, len);
	if (report_id && ret >= 0)
		ret++; /* add report_id to the number of transfered bytes */

	return 0;
}

static int gb_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
			       __u8 *buf, size_t len, unsigned char rtype,
			       int reqtype)
{
	switch (reqtype) {
	case HID_REQ_GET_REPORT:
		return __gb_hid_get_raw_report(hid, reportnum, buf, len, rtype);
	case HID_REQ_SET_REPORT:
		if (buf[0] != reportnum)
			return -EINVAL;
		return __gb_hid_output_raw_report(hid, buf, len, rtype);
	default:
		return -EIO;
	}
}

/* HID Callbacks */
static int gb_hid_parse(struct hid_device *hid)
{
	struct gb_hid *ghid = hid->driver_data;
	unsigned int rsize;
	char *rdesc;
	int ret;

	rsize = le16_to_cpu(ghid->hdesc.wReportDescLength);
	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
		dbg_hid("weird size of report descriptor (%u)\n", rsize);
		return -EINVAL;
	}

	rdesc = kzalloc(rsize, GFP_KERNEL);
	if (!rdesc) {
		dbg_hid("couldn't allocate rdesc memory\n");
		return -ENOMEM;
	}

	ret = gb_hid_get_report_desc(ghid, rdesc);
	if (ret) {
		hid_err(hid, "reading report descriptor failed\n");
		goto free_rdesc;
	}

	ret = hid_parse_report(hid, rdesc, rsize);
	if (ret)
		dbg_hid("parsing report descriptor failed\n");

free_rdesc:
	kfree(rdesc);

	return ret;
}

static int gb_hid_start(struct hid_device *hid)
{
	struct gb_hid *ghid = hid->driver_data;
	unsigned int bufsize = HID_MIN_BUFFER_SIZE;
	int ret;

	gb_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize);
	gb_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize);
	gb_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize);

	if (bufsize > HID_MAX_BUFFER_SIZE)
		bufsize = HID_MAX_BUFFER_SIZE;

	ret = gb_hid_alloc_buffers(ghid, bufsize);
	if (ret)
		return ret;

	if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
		gb_hid_init_reports(ghid);

	return 0;
}

static void gb_hid_stop(struct hid_device *hid)
{
	struct gb_hid *ghid = hid->driver_data;

	gb_hid_free_buffers(ghid);
}

static int gb_hid_open(struct hid_device *hid)
{
	struct gb_hid *ghid = hid->driver_data;
	int ret;

	ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
	if (ret < 0)
		return ret;

	set_bit(GB_HID_STARTED, &ghid->flags);
	return 0;
}

static void gb_hid_close(struct hid_device *hid)
{
	struct gb_hid *ghid = hid->driver_data;
	int ret;

	clear_bit(GB_HID_STARTED, &ghid->flags);

	/* Save some power */
	ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
	if (ret)
		dev_err(&ghid->connection->bundle->dev,
			"failed to power off (%d)\n", ret);
}

static int gb_hid_power(struct hid_device *hid, int lvl)
{
	struct gb_hid *ghid = hid->driver_data;

	switch (lvl) {
	case PM_HINT_FULLON:
		return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
	case PM_HINT_NORMAL:
		return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
	}

	return 0;
}

/* HID structure to pass callbacks */
static struct hid_ll_driver gb_hid_ll_driver = {
	.parse = gb_hid_parse,
	.start = gb_hid_start,
	.stop = gb_hid_stop,
	.open = gb_hid_open,
	.close = gb_hid_close,
	.power = gb_hid_power,
	.raw_request = gb_hid_raw_request,
};

static int gb_hid_init(struct gb_hid *ghid)
{
	struct hid_device *hid = ghid->hid;
	int ret;

	ret = gb_hid_get_desc(ghid);
	if (ret)
		return ret;

	hid->version = le16_to_cpu(ghid->hdesc.bcdHID);
	hid->vendor = le16_to_cpu(ghid->hdesc.wVendorID);
	hid->product = le16_to_cpu(ghid->hdesc.wProductID);
	hid->country = ghid->hdesc.bCountryCode;

	hid->driver_data = ghid;
	hid->ll_driver = &gb_hid_ll_driver;
	hid->dev.parent = &ghid->connection->bundle->dev;
//	hid->bus = BUS_GREYBUS; /* Need a bustype for GREYBUS in <linux/input.h> */

	/* Set HID device's name */
	snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X",
		 dev_name(&ghid->connection->bundle->dev),
		 hid->vendor, hid->product);

	return 0;
}

static int gb_hid_probe(struct gb_bundle *bundle,
			const struct greybus_bundle_id *id)
{
	struct greybus_descriptor_cport *cport_desc;
	struct gb_connection *connection;
	struct hid_device *hid;
	struct gb_hid *ghid;
	int ret;

	if (bundle->num_cports != 1)
		return -ENODEV;

	cport_desc = &bundle->cport_desc[0];
	if (cport_desc->protocol_id != GREYBUS_PROTOCOL_HID)
		return -ENODEV;

	ghid = kzalloc(sizeof(*ghid), GFP_KERNEL);
	if (!ghid)
		return -ENOMEM;

	connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
						gb_hid_request_handler);
	if (IS_ERR(connection)) {
		ret = PTR_ERR(connection);
		goto err_free_ghid;
	}

	gb_connection_set_data(connection, ghid);
	ghid->connection = connection;

	hid = hid_allocate_device();
	if (IS_ERR(hid)) {
		ret = PTR_ERR(hid);
		goto err_connection_destroy;
	}

	ghid->hid = hid;
	ghid->bundle = bundle;

	greybus_set_drvdata(bundle, ghid);

	ret = gb_connection_enable(connection);
	if (ret)
		goto err_destroy_hid;

	ret = gb_hid_init(ghid);
	if (ret)
		goto err_connection_disable;

	ret = hid_add_device(hid);
	if (ret) {
		hid_err(hid, "can't add hid device: %d\n", ret);
		goto err_connection_disable;
	}

	gb_pm_runtime_put_autosuspend(bundle);

	return 0;

err_connection_disable:
	gb_connection_disable(connection);
err_destroy_hid:
	hid_destroy_device(hid);
err_connection_destroy:
	gb_connection_destroy(connection);
err_free_ghid:
	kfree(ghid);

	return ret;
}

static void gb_hid_disconnect(struct gb_bundle *bundle)
{
	struct gb_hid *ghid = greybus_get_drvdata(bundle);

	if (gb_pm_runtime_get_sync(bundle))
		gb_pm_runtime_get_noresume(bundle);

	hid_destroy_device(ghid->hid);
	gb_connection_disable(ghid->connection);
	gb_connection_destroy(ghid->connection);
	kfree(ghid);
}

static const struct greybus_bundle_id gb_hid_id_table[] = {
	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) },
	{ }
};
MODULE_DEVICE_TABLE(greybus, gb_hid_id_table);

static struct greybus_driver gb_hid_driver = {
	.name		= "hid",
	.probe		= gb_hid_probe,
	.disconnect	= gb_hid_disconnect,
	.id_table	= gb_hid_id_table,
};
module_greybus_driver(gb_hid_driver);

MODULE_LICENSE("GPL v2");
