// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AMD MP2 Sensors transport driver
 *
 * Copyright 2020-2021 Advanced Micro Devices, Inc.
 * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com>
 *	    Sandeep Singh <sandeep.singh@amd.com>
 *	    Basavaraj Natikar <Basavaraj.Natikar@amd.com>
 */
#include <linux/hid.h>
#include <linux/wait.h>
#include <linux/sched.h>

#include "amd_sfh_hid.h"

#define AMD_SFH_RESPONSE_TIMEOUT	1500

/**
 * amdtp_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 amdtp_hid_parse(struct hid_device *hid)
{
	struct amdtp_hid_data *hid_data = hid->driver_data;
	struct amdtp_cl_data *cli_data = hid_data->cli_data;

	return hid_parse_report(hid, cli_data->report_descr[hid_data->index],
			      cli_data->report_descr_sz[hid_data->index]);
}

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

static void amdtp_hid_stop(struct hid_device *hid)
{
}

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

static void amdtp_hid_close(struct hid_device *hid)
{
}

static int amdtp_raw_request(struct hid_device *hdev, u8 reportnum,
			     u8 *buf, size_t len, u8 rtype, int reqtype)
{
	return 0;
}

static void amdtp_hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype)
{
	int rc;

	switch (reqtype) {
	case HID_REQ_GET_REPORT:
		rc = amd_sfh_get_report(hid, rep->id, rep->type);
		if (rc)
			dev_err(&hid->dev, "AMDSFH  get report error\n");
		break;
	case HID_REQ_SET_REPORT:
		amd_sfh_set_report(hid, rep->id, reqtype);
		break;
	default:
		break;
	}
}

static int amdtp_wait_for_response(struct hid_device *hid)
{
	struct amdtp_hid_data *hid_data =  hid->driver_data;
	struct amdtp_cl_data *cli_data = hid_data->cli_data;
	int i, ret = 0;

	for (i = 0; i < cli_data->num_hid_devices; i++) {
		if (cli_data->hid_sensor_hubs[i] == hid)
			break;
	}

	if (!cli_data->request_done[i])
		ret = wait_event_interruptible_timeout(hid_data->hid_wait,
						       cli_data->request_done[i],
						       msecs_to_jiffies(AMD_SFH_RESPONSE_TIMEOUT));
	if (ret == -ERESTARTSYS)
		return -ERESTARTSYS;
	else if (ret < 0)
		return -ETIMEDOUT;
	else
		return 0;
}

void amdtp_hid_wakeup(struct hid_device *hid)
{
	struct amdtp_hid_data *hid_data = hid->driver_data;
	struct amdtp_cl_data *cli_data = hid_data->cli_data;

	cli_data->request_done[cli_data->cur_hid_dev] = true;
	wake_up_interruptible(&hid_data->hid_wait);
}

static struct hid_ll_driver amdtp_hid_ll_driver = {
	.parse	=	amdtp_hid_parse,
	.start	=	amdtp_hid_start,
	.stop	=	amdtp_hid_stop,
	.open	=	amdtp_hid_open,
	.close	=	amdtp_hid_close,
	.request  =	amdtp_hid_request,
	.wait	=	amdtp_wait_for_response,
	.raw_request  =	amdtp_raw_request,
};

int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)
{
	struct hid_device *hid;
	struct amdtp_hid_data *hid_data;
	int rc;

	hid = hid_allocate_device();
	if (IS_ERR(hid))
		return PTR_ERR(hid);

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

	hid->ll_driver = &amdtp_hid_ll_driver;
	hid_data->index = cur_hid_dev;
	hid_data->cli_data = cli_data;
	init_waitqueue_head(&hid_data->hid_wait);

	hid->driver_data = hid_data;
	cli_data->hid_sensor_hubs[cur_hid_dev] = hid;
	hid->bus = BUS_AMD_AMDTP;
	hid->vendor = AMD_SFH_HID_VENDOR;
	hid->product = AMD_SFH_HID_PRODUCT;
	snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp",
		 hid->vendor, hid->product);

	rc = hid_add_device(hid);
	if (rc)
		goto err_hid_device;
	return 0;

err_hid_device:
	kfree(hid_data);
err_hid_data:
	hid_destroy_device(hid);
	return rc;
}

void amdtp_hid_remove(struct amdtp_cl_data *cli_data)
{
	int i;

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