// SPDX-License-Identifier: GPL-2.0+
/*
 * Surface System Aggregator Module (SSAM) HID transport driver for the
 * generic HID interface (HID/TC=0x15 subsystem). Provides support for
 * integrated HID devices on Surface Laptop 3, Book 3, and later.
 *
 * Copyright (C) 2019-2021 Blaž Hrastnik <blaz@mxxn.io>,
 *                         Maximilian Luz <luzmaximilian@gmail.com>
 */

#include <linux/unaligned.h>
#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>

#include <linux/surface_aggregator/controller.h>
#include <linux/surface_aggregator/device.h>

#include "surface_hid_core.h"


/* -- SAM interface. -------------------------------------------------------- */

struct surface_hid_buffer_slice {
	__u8 entry;
	__le32 offset;
	__le32 length;
	__u8 end;
	__u8 data[];
} __packed;

static_assert(sizeof(struct surface_hid_buffer_slice) == 10);

enum surface_hid_cid {
	SURFACE_HID_CID_OUTPUT_REPORT      = 0x01,
	SURFACE_HID_CID_GET_FEATURE_REPORT = 0x02,
	SURFACE_HID_CID_SET_FEATURE_REPORT = 0x03,
	SURFACE_HID_CID_GET_DESCRIPTOR     = 0x04,
};

static int ssam_hid_get_descriptor(struct surface_hid_device *shid, u8 entry, u8 *buf, size_t len)
{
	u8 buffer[sizeof(struct surface_hid_buffer_slice) + 0x76];
	struct surface_hid_buffer_slice *slice;
	struct ssam_request rqst;
	struct ssam_response rsp;
	u32 buffer_len, offset, length;
	int status;

	/*
	 * Note: The 0x76 above has been chosen because that's what's used by
	 * the Windows driver. Together with the header, this leads to a 128
	 * byte payload in total.
	 */

	buffer_len = ARRAY_SIZE(buffer) - sizeof(struct surface_hid_buffer_slice);

	rqst.target_category = shid->uid.category;
	rqst.target_id = shid->uid.target;
	rqst.command_id = SURFACE_HID_CID_GET_DESCRIPTOR;
	rqst.instance_id = shid->uid.instance;
	rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
	rqst.length = sizeof(struct surface_hid_buffer_slice);
	rqst.payload = buffer;

	rsp.capacity = ARRAY_SIZE(buffer);
	rsp.pointer = buffer;

	slice = (struct surface_hid_buffer_slice *)buffer;
	slice->entry = entry;
	slice->end = 0;

	offset = 0;
	length = buffer_len;

	while (!slice->end && offset < len) {
		put_unaligned_le32(offset, &slice->offset);
		put_unaligned_le32(length, &slice->length);

		rsp.length = 0;

		status = ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp,
				    sizeof(*slice));
		if (status)
			return status;

		offset = get_unaligned_le32(&slice->offset);
		length = get_unaligned_le32(&slice->length);

		/* Don't mess stuff up in case we receive garbage. */
		if (length > buffer_len || offset > len)
			return -EPROTO;

		if (offset + length > len)
			length = len - offset;

		memcpy(buf + offset, &slice->data[0], length);

		offset += length;
		length = buffer_len;
	}

	if (offset != len) {
		dev_err(shid->dev, "unexpected descriptor length: got %u, expected %zu\n",
			offset, len);
		return -EPROTO;
	}

	return 0;
}

static int ssam_hid_set_raw_report(struct surface_hid_device *shid, u8 rprt_id, bool feature,
				   u8 *buf, size_t len)
{
	struct ssam_request rqst;
	u8 cid;

	if (feature)
		cid = SURFACE_HID_CID_SET_FEATURE_REPORT;
	else
		cid = SURFACE_HID_CID_OUTPUT_REPORT;

	rqst.target_category = shid->uid.category;
	rqst.target_id = shid->uid.target;
	rqst.instance_id = shid->uid.instance;
	rqst.command_id = cid;
	rqst.flags = 0;
	rqst.length = len;
	rqst.payload = buf;

	buf[0] = rprt_id;

	return ssam_retry(ssam_request_do_sync, shid->ctrl, &rqst, NULL);
}

static int ssam_hid_get_raw_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len)
{
	struct ssam_request rqst;
	struct ssam_response rsp;

	rqst.target_category = shid->uid.category;
	rqst.target_id = shid->uid.target;
	rqst.instance_id = shid->uid.instance;
	rqst.command_id = SURFACE_HID_CID_GET_FEATURE_REPORT;
	rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
	rqst.length = sizeof(rprt_id);
	rqst.payload = &rprt_id;

	rsp.capacity = len;
	rsp.length = 0;
	rsp.pointer = buf;

	return ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, sizeof(rprt_id));
}

static u32 ssam_hid_event_fn(struct ssam_event_notifier *nf, const struct ssam_event *event)
{
	struct surface_hid_device *shid = container_of(nf, struct surface_hid_device, notif);

	if (event->command_id != 0x00)
		return 0;

	hid_input_report(shid->hid, HID_INPUT_REPORT, (u8 *)&event->data[0], event->length, 0);
	return SSAM_NOTIF_HANDLED;
}


/* -- Transport driver. ----------------------------------------------------- */

static int shid_output_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len)
{
	int status;

	status = ssam_hid_set_raw_report(shid, rprt_id, false, buf, len);
	return status >= 0 ? len : status;
}

static int shid_get_feature_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len)
{
	int status;

	status = ssam_hid_get_raw_report(shid, rprt_id, buf, len);
	return status >= 0 ? len : status;
}

static int shid_set_feature_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len)
{
	int status;

	status = ssam_hid_set_raw_report(shid, rprt_id, true, buf, len);
	return status >= 0 ? len : status;
}


/* -- Driver setup. --------------------------------------------------------- */

static int surface_hid_probe(struct ssam_device *sdev)
{
	struct surface_hid_device *shid;

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

	shid->dev = &sdev->dev;
	shid->ctrl = sdev->ctrl;
	shid->uid = sdev->uid;

	shid->notif.base.priority = 1;
	shid->notif.base.fn = ssam_hid_event_fn;
	shid->notif.event.reg = SSAM_EVENT_REGISTRY_REG(sdev->uid.target);
	shid->notif.event.id.target_category = sdev->uid.category;
	shid->notif.event.id.instance = sdev->uid.instance;
	shid->notif.event.mask = SSAM_EVENT_MASK_STRICT;
	shid->notif.event.flags = 0;

	shid->ops.get_descriptor = ssam_hid_get_descriptor;
	shid->ops.output_report = shid_output_report;
	shid->ops.get_feature_report = shid_get_feature_report;
	shid->ops.set_feature_report = shid_set_feature_report;

	ssam_device_set_drvdata(sdev, shid);
	return surface_hid_device_add(shid);
}

static void surface_hid_remove(struct ssam_device *sdev)
{
	surface_hid_device_destroy(ssam_device_get_drvdata(sdev));
}

static const struct ssam_device_id surface_hid_match[] = {
	{ SSAM_SDEV(HID, ANY, SSAM_SSH_IID_ANY, 0x00) },
	{ },
};
MODULE_DEVICE_TABLE(ssam, surface_hid_match);

static struct ssam_device_driver surface_hid_driver = {
	.probe = surface_hid_probe,
	.remove = surface_hid_remove,
	.match_table = surface_hid_match,
	.driver = {
		.name = "surface_hid",
		.pm = &surface_hid_pm_ops,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};
module_ssam_device_driver(surface_hid_driver);

MODULE_AUTHOR("Blaž Hrastnik <blaz@mxxn.io>");
MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
MODULE_DESCRIPTION("HID transport driver for Surface System Aggregator Module");
MODULE_LICENSE("GPL");
