// 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_using_ll_driver(hdev, &usb_hid_driver))
		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");
