// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021 Hans de Goede <hdegoede@redhat.com>
 *
 * Driver for the LetSketch / VSON WP9620N drawing tablet.
 * This drawing tablet is also sold under other brand names such as Case U,
 * presumably this driver will work for all of them. But it has only been
 * tested with a LetSketch WP9620N model.
 *
 * These tablets also work without a special HID driver, but then only part
 * of the active area works and both the pad and stylus buttons are hardwired
 * to special key-combos. E.g. the 2 stylus buttons send right mouse clicks /
 * resp. "e" key presses.
 *
 * This device has 4 USB interfaces:
 *
 * Interface 0 EP 0x81 bootclass mouse, rdesc len 18, report id 0x08,
 *                                                    Application(ff00.0001)
 *  This interface sends raw event input reports in a custom format, but only
 *  after doing the special dance from letsketch_probe(). After enabling this
 *  interface the other 3 interfaces are disabled.
 *
 * Interface 1 EP 0x82 bootclass mouse, rdesc len 83, report id 0x0a, Tablet
 *  This interface sends absolute events for the pen, including pressure,
 *  but only for some part of the active area due to special "aspect ratio"
 *  correction and only half by default since it assumes it will be used
 *  with a phone in portraid mode, while using the tablet in landscape mode.
 *  Also stylus + pad button events are not reported here.
 *
 * Interface 2 EP 0x83 bootclass keybd, rdesc len 64, report id none, Std Kbd
 *  This interfaces send various hard-coded key-combos for the pad buttons
 *  and "e" keypresses for the 2nd stylus button
 *
 * Interface 3 EP 0x84 bootclass mouse, rdesc len 75, report id 0x01, Std Mouse
 *  This reports right-click mouse-button events for the 1st stylus button
 */
#include <linux/device.h>
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/usb.h>

#include <asm/unaligned.h>

#include "hid-ids.h"

#define LETSKETCH_RAW_IF		0

#define LETSKETCH_RAW_DATA_LEN		12
#define LETSKETCH_RAW_REPORT_ID		8

#define LETSKETCH_PAD_BUTTONS		5

#define LETSKETCH_INFO_STR_IDX_BEGIN	0xc8
#define LETSKETCH_INFO_STR_IDX_END	0xca

#define LETSKETCH_GET_STRING_RETRIES	5

struct letsketch_data {
	struct hid_device *hdev;
	struct input_dev *input_tablet;
	struct input_dev *input_tablet_pad;
	struct timer_list inrange_timer;
};

static int letsketch_open(struct input_dev *dev)
{
	struct letsketch_data *data = input_get_drvdata(dev);

	return hid_hw_open(data->hdev);
}

static void letsketch_close(struct input_dev *dev)
{
	struct letsketch_data *data = input_get_drvdata(dev);

	hid_hw_close(data->hdev);
}

static struct input_dev *letsketch_alloc_input_dev(struct letsketch_data *data)
{
	struct input_dev *input;

	input = devm_input_allocate_device(&data->hdev->dev);
	if (!input)
		return NULL;

	input->id.bustype = data->hdev->bus;
	input->id.vendor  = data->hdev->vendor;
	input->id.product = data->hdev->product;
	input->id.version = data->hdev->bus;
	input->phys = data->hdev->phys;
	input->uniq = data->hdev->uniq;
	input->open = letsketch_open;
	input->close = letsketch_close;

	input_set_drvdata(input, data);

	return input;
}

static int letsketch_setup_input_tablet(struct letsketch_data *data)
{
	struct input_dev *input;

	input = letsketch_alloc_input_dev(data);
	if (!input)
		return -ENOMEM;

	input_set_abs_params(input, ABS_X, 0, 50800, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, 31750, 0, 0);
	input_set_abs_params(input, ABS_PRESSURE, 0, 8192, 0, 0);
	input_abs_set_res(input, ABS_X, 240);
	input_abs_set_res(input, ABS_Y, 225);
	input_set_capability(input, EV_KEY, BTN_TOUCH);
	input_set_capability(input, EV_KEY, BTN_TOOL_PEN);
	input_set_capability(input, EV_KEY, BTN_STYLUS);
	input_set_capability(input, EV_KEY, BTN_STYLUS2);

	/* All known brands selling this tablet use WP9620[N] as model name */
	input->name = "WP9620 Tablet";

	data->input_tablet = input;

	return input_register_device(data->input_tablet);
}

static int letsketch_setup_input_tablet_pad(struct letsketch_data *data)
{
	struct input_dev *input;
	int i;

	input = letsketch_alloc_input_dev(data);
	if (!input)
		return -ENOMEM;

	for (i = 0; i < LETSKETCH_PAD_BUTTONS; i++)
		input_set_capability(input, EV_KEY, BTN_0 + i);

	/*
	 * These are never send on the pad input_dev, but must be set
	 * on the Pad to make udev / libwacom happy.
	 */
	input_set_abs_params(input, ABS_X, 0, 1, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, 1, 0, 0);
	input_set_capability(input, EV_KEY, BTN_STYLUS);

	input->name = "WP9620 Pad";

	data->input_tablet_pad = input;

	return input_register_device(data->input_tablet_pad);
}

static void letsketch_inrange_timeout(struct timer_list *t)
{
	struct letsketch_data *data = from_timer(data, t, inrange_timer);
	struct input_dev *input = data->input_tablet;

	input_report_key(input, BTN_TOOL_PEN, 0);
	input_sync(input);
}

static int letsketch_raw_event(struct hid_device *hdev,
			       struct hid_report *report,
			       u8 *raw_data, int size)
{
	struct letsketch_data *data = hid_get_drvdata(hdev);
	struct input_dev *input;
	int i;

	if (size != LETSKETCH_RAW_DATA_LEN || raw_data[0] != LETSKETCH_RAW_REPORT_ID)
		return 0;

	switch (raw_data[1] & 0xf0) {
	case 0x80: /* Pen data */
		input = data->input_tablet;
		input_report_key(input, BTN_TOOL_PEN, 1);
		input_report_key(input, BTN_TOUCH, raw_data[1] & 0x01);
		input_report_key(input, BTN_STYLUS, raw_data[1] & 0x02);
		input_report_key(input, BTN_STYLUS2, raw_data[1] & 0x04);
		input_report_abs(input, ABS_X,
				 get_unaligned_le16(raw_data + 2));
		input_report_abs(input, ABS_Y,
				 get_unaligned_le16(raw_data + 4));
		input_report_abs(input, ABS_PRESSURE,
				 get_unaligned_le16(raw_data + 6));
		/*
		 * There is no out of range event, so use a timer for this
		 * when in range we get an event approx. every 8 ms.
		 */
		mod_timer(&data->inrange_timer, jiffies + msecs_to_jiffies(100));
		break;
	case 0xe0: /* Pad data */
		input = data->input_tablet_pad;
		for (i = 0; i < LETSKETCH_PAD_BUTTONS; i++)
			input_report_key(input, BTN_0 + i, raw_data[4] == (i + 1));
		break;
	default:
		hid_warn(data->hdev, "Warning unknown data header: 0x%02x\n",
			 raw_data[0]);
		return 0;
	}

	input_sync(input);
	return 0;
}

/*
 * The tablets magic handshake to put it in raw mode relies on getting
 * string descriptors. But the firmware is buggy and does not like it if
 * we do this too fast. Even if we go slow sometimes the usb_string() call
 * fails. Ignore errors and retry it a couple of times if necessary.
 */
static int letsketch_get_string(struct usb_device *udev, int index, char *buf, int size)
{
	int i, ret;

	for (i = 0; i < LETSKETCH_GET_STRING_RETRIES; i++) {
		usleep_range(5000, 7000);
		ret = usb_string(udev, index, buf, size);
		if (ret > 0)
			return 0;
	}

	dev_err(&udev->dev, "Max retries (%d) exceeded reading string descriptor %d\n",
		LETSKETCH_GET_STRING_RETRIES, index);
	return ret ? ret : -EIO;
}

static int letsketch_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	struct device *dev = &hdev->dev;
	struct letsketch_data *data;
	struct usb_interface *intf;
	struct usb_device *udev;
	char buf[256];
	int i, ret;

	if (!hid_is_usb(hdev))
		return -ENODEV;

	intf = to_usb_interface(hdev->dev.parent);
	if (intf->altsetting->desc.bInterfaceNumber != LETSKETCH_RAW_IF)
		return -ENODEV; /* Ignore the other interfaces */

	udev = interface_to_usbdev(intf);

	/*
	 * Instead of using a set-feature request, or even a custom USB ctrl
	 * message the tablet needs this elaborate magic reading of USB
	 * string descriptors to kick it into raw mode. This is what the
	 * Windows drivers are seen doing in an USB trace under Windows.
	 */
	for (i = LETSKETCH_INFO_STR_IDX_BEGIN; i <= LETSKETCH_INFO_STR_IDX_END; i++) {
		ret = letsketch_get_string(udev, i, buf, sizeof(buf));
		if (ret)
			return ret;

		hid_info(hdev, "Device info: %s\n", buf);
	}

	for (i = 1; i <= 250; i++) {
		ret = letsketch_get_string(udev, i, buf, sizeof(buf));
		if (ret)
			return ret;
	}

	ret = letsketch_get_string(udev, 0x64, buf, sizeof(buf));
	if (ret)
		return ret;

	ret = letsketch_get_string(udev, LETSKETCH_INFO_STR_IDX_BEGIN, buf, sizeof(buf));
	if (ret)
		return ret;

	/*
	 * The tablet should be in raw mode now, end with a final delay before
	 * doing further IO to the device.
	 */
	usleep_range(5000, 7000);

	ret = hid_parse(hdev);
	if (ret)
		return ret;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->hdev = hdev;
	timer_setup(&data->inrange_timer, letsketch_inrange_timeout, 0);
	hid_set_drvdata(hdev, data);

	ret = letsketch_setup_input_tablet(data);
	if (ret)
		return ret;

	ret = letsketch_setup_input_tablet_pad(data);
	if (ret)
		return ret;

	return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
}

static const struct hid_device_id letsketch_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_LETSKETCH, USB_DEVICE_ID_WP9620N) },
	{ }
};
MODULE_DEVICE_TABLE(hid, letsketch_devices);

static struct hid_driver letsketch_driver = {
	.name = "letsketch",
	.id_table = letsketch_devices,
	.probe = letsketch_probe,
	.raw_event = letsketch_raw_event,
};
module_hid_driver(letsketch_driver);

MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
