/*
 * ISHTP-HID glue driver.
 *
 * Copyright (c) 2012-2016, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 */

#include <linux/hid.h>
#include <uapi/linux/input.h>
#include "ishtp/client.h"
#include "ishtp-hid.h"

/**
 * ishtp_hid_parse() - hid-core .parse() callback
 * @hid:	hid device instance
 *
 * This function gets called during call to hid_add_device
 *
 * Return: 0 on success and non zero on error
 */
static int ishtp_hid_parse(struct hid_device *hid)
{
	struct ishtp_hid_data *hid_data =  hid->driver_data;
	struct ishtp_cl_data *client_data = hid_data->client_data;
	int rv;

	rv = hid_parse_report(hid, client_data->report_descr[hid_data->index],
			      client_data->report_descr_size[hid_data->index]);
	if (rv)
		return	rv;

	return 0;
}

/* Empty callbacks with success return code */
static int ishtp_hid_start(struct hid_device *hid)
{
	return 0;
}

static void ishtp_hid_stop(struct hid_device *hid)
{
}

static int ishtp_hid_open(struct hid_device *hid)
{
	return 0;
}

static void ishtp_hid_close(struct hid_device *hid)
{
}

static int ishtp_raw_request(struct hid_device *hdev, unsigned char reportnum,
	__u8 *buf, size_t len, unsigned char rtype, int reqtype)
{
	return 0;
}

/**
 * ishtp_hid_request() - hid-core .request() callback
 * @hid:	hid device instance
 * @rep:	pointer to hid_report
 * @reqtype:	type of req. [GET|SET]_REPORT
 *
 * This function is used to set/get feaure/input report.
 */
static void ishtp_hid_request(struct hid_device *hid, struct hid_report *rep,
	int reqtype)
{
	struct ishtp_hid_data *hid_data =  hid->driver_data;
	/* the specific report length, just HID part of it */
	unsigned int len = ((rep->size - 1) >> 3) + 1 + (rep->id > 0);
	char *buf;
	unsigned int header_size = sizeof(struct hostif_msg);

	len += header_size;

	hid_data->request_done = false;
	switch (reqtype) {
	case HID_REQ_GET_REPORT:
		hid_ishtp_get_report(hid, rep->id, rep->type);
		break;
	case HID_REQ_SET_REPORT:
		/*
		 * Spare 7 bytes for 64b accesses through
		 * get/put_unaligned_le64()
		 */
		buf = kzalloc(len + 7, GFP_KERNEL);
		if (!buf)
			return;

		hid_output_report(rep, buf + header_size);
		hid_ishtp_set_feature(hid, buf, len, rep->id);
		kfree(buf);
		break;
	}
}

/**
 * ishtp_wait_for_response() - hid-core .wait() callback
 * @hid:	hid device instance
 *
 * This function is used to wait after get feaure/input report.
 *
 * Return: 0 on success and non zero on error
 */
static int ishtp_wait_for_response(struct hid_device *hid)
{
	struct ishtp_hid_data *hid_data =  hid->driver_data;
	struct ishtp_cl_data *client_data = hid_data->client_data;
	int rv;

	hid_ishtp_trace(client_data,  "%s hid %p\n", __func__, hid);

	rv = ishtp_hid_link_ready_wait(hid_data->client_data);
	if (rv)
		return rv;

	if (!hid_data->request_done)
		wait_event_interruptible_timeout(hid_data->hid_wait,
					hid_data->request_done, 3 * HZ);

	if (!hid_data->request_done) {
		hid_err(hid,
			"timeout waiting for response from ISHTP device\n");
		return -ETIMEDOUT;
	}
	hid_ishtp_trace(client_data,  "%s hid %p done\n", __func__, hid);

	hid_data->request_done = false;

	return 0;
}

/**
 * ishtp_hid_wakeup() - Wakeup caller
 * @hid:	hid device instance
 *
 * This function will wakeup caller waiting for Get/Set feature report
 */
void ishtp_hid_wakeup(struct hid_device *hid)
{
	struct ishtp_hid_data *hid_data = hid->driver_data;

	hid_data->request_done = true;
	wake_up_interruptible(&hid_data->hid_wait);
}

static struct hid_ll_driver ishtp_hid_ll_driver = {
	.parse = ishtp_hid_parse,
	.start = ishtp_hid_start,
	.stop = ishtp_hid_stop,
	.open = ishtp_hid_open,
	.close = ishtp_hid_close,
	.request = ishtp_hid_request,
	.wait = ishtp_wait_for_response,
	.raw_request = ishtp_raw_request
};

/**
 * ishtp_hid_probe() - hid register ll driver
 * @cur_hid_dev:	Index of hid device calling to register
 * @client_data:	Client data pointer
 *
 * This function is used to allocate and add HID device.
 *
 * Return: 0 on success, non zero on error
 */
int ishtp_hid_probe(unsigned int cur_hid_dev,
		    struct ishtp_cl_data *client_data)
{
	int rv;
	struct hid_device *hid;
	struct ishtp_hid_data *hid_data;

	hid = hid_allocate_device();
	if (IS_ERR(hid)) {
		rv = PTR_ERR(hid);
		return	-ENOMEM;
	}

	hid_data = kzalloc(sizeof(*hid_data), GFP_KERNEL);
	if (!hid_data) {
		rv = -ENOMEM;
		goto err_hid_data;
	}

	hid_data->index = cur_hid_dev;
	hid_data->client_data = client_data;
	init_waitqueue_head(&hid_data->hid_wait);

	hid->driver_data = hid_data;

	client_data->hid_sensor_hubs[cur_hid_dev] = hid;

	hid->ll_driver = &ishtp_hid_ll_driver;
	hid->bus = BUS_INTEL_ISHTP;
	hid->dev.parent = &client_data->cl_device->dev;
	hid->version = le16_to_cpu(ISH_HID_VERSION);
	hid->vendor = le16_to_cpu(ISH_HID_VENDOR);
	hid->product = le16_to_cpu(ISH_HID_PRODUCT);
	snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", "hid-ishtp",
		hid->vendor, hid->product);

	rv = hid_add_device(hid);
	if (rv)
		goto err_hid_device;

	hid_ishtp_trace(client_data,  "%s allocated hid %p\n", __func__, hid);

	return 0;

err_hid_device:
	kfree(hid_data);
err_hid_data:
	kfree(hid);
	return rv;
}

/**
 * ishtp_hid_probe() - Remove registered hid device
 * @client_data:	client data pointer
 *
 * This function is used to destroy allocatd HID device.
 */
void ishtp_hid_remove(struct ishtp_cl_data *client_data)
{
	int i;

	for (i = 0; i < client_data->num_hid_devices; ++i) {
		if (client_data->hid_sensor_hubs[i]) {
			kfree(client_data->hid_sensor_hubs[i]->driver_data);
			hid_destroy_device(client_data->hid_sensor_hubs[i]);
			client_data->hid_sensor_hubs[i] = NULL;
		}
	}
}
