/*
 * Pegasus Mobile Notetaker Pen input tablet driver
 *
 * Copyright (c) 2016 Martin Kepplinger <martink@posteo.de>
 */

/*
 * request packet (control endpoint):
 * |-------------------------------------|
 * | Report ID | Nr of bytes | command   |
 * | (1 byte)  | (1 byte)    | (n bytes) |
 * |-------------------------------------|
 * | 0x02      | n           |           |
 * |-------------------------------------|
 *
 * data packet after set xy mode command, 0x80 0xb5 0x02 0x01
 * and pen is in range:
 *
 * byte	byte name		value (bits)
 * --------------------------------------------
 * 0	status			0 1 0 0 0 0 X X
 * 1	color			0 0 0 0 H 0 S T
 * 2	X low
 * 3	X high
 * 4	Y low
 * 5	Y high
 *
 * X X	battery state:
 *	no state reported	0x00
 *	battery low		0x01
 *	battery good		0x02
 *
 * H	Hovering
 * S	Switch 1 (pen button)
 * T	Tip
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/usb/input.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

/* USB HID defines */
#define USB_REQ_GET_REPORT		0x01
#define USB_REQ_SET_REPORT		0x09

#define USB_VENDOR_ID_PEGASUSTECH	0x0e20
#define USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100	0x0101

/* device specific defines */
#define NOTETAKER_REPORT_ID		0x02
#define NOTETAKER_SET_CMD		0x80
#define NOTETAKER_SET_MODE		0xb5

#define NOTETAKER_LED_MOUSE		0x02
#define PEN_MODE_XY			0x01

#define SPECIAL_COMMAND			0x80
#define BUTTON_PRESSED			0xb5
#define COMMAND_VERSION			0xa9

/* in xy data packet */
#define BATTERY_NO_REPORT		0x40
#define BATTERY_LOW			0x41
#define BATTERY_GOOD			0x42
#define PEN_BUTTON_PRESSED		BIT(1)
#define PEN_TIP				BIT(0)

struct pegasus {
	unsigned char *data;
	u8 data_len;
	dma_addr_t data_dma;
	struct input_dev *dev;
	struct usb_device *usbdev;
	struct usb_interface *intf;
	struct urb *irq;
	char name[128];
	char phys[64];
	struct work_struct init;
};

static int pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
{
	const int sizeof_buf = len + 2;
	int result;
	int error;
	u8 *cmd_buf;

	cmd_buf = kmalloc(sizeof_buf, GFP_KERNEL);
	if (!cmd_buf)
		return -ENOMEM;

	cmd_buf[0] = NOTETAKER_REPORT_ID;
	cmd_buf[1] = len;
	memcpy(cmd_buf + 2, data, len);

	result = usb_control_msg(pegasus->usbdev,
				 usb_sndctrlpipe(pegasus->usbdev, 0),
				 USB_REQ_SET_REPORT,
				 USB_TYPE_VENDOR | USB_DIR_OUT,
				 0, 0, cmd_buf, sizeof_buf,
				 USB_CTRL_SET_TIMEOUT);

	kfree(cmd_buf);

	if (unlikely(result != sizeof_buf)) {
		error = result < 0 ? result : -EIO;
		dev_err(&pegasus->usbdev->dev, "control msg error: %d\n",
			error);
		return error;
	}

	return 0;
}

static int pegasus_set_mode(struct pegasus *pegasus, u8 mode, u8 led)
{
	u8 cmd[] = { NOTETAKER_SET_CMD, NOTETAKER_SET_MODE, led, mode };

	return pegasus_control_msg(pegasus, cmd, sizeof(cmd));
}

static void pegasus_parse_packet(struct pegasus *pegasus)
{
	unsigned char *data = pegasus->data;
	struct input_dev *dev = pegasus->dev;
	u16 x, y;

	switch (data[0]) {
	case SPECIAL_COMMAND:
		/* device button pressed */
		if (data[1] == BUTTON_PRESSED)
			schedule_work(&pegasus->init);

		break;

	/* xy data */
	case BATTERY_LOW:
		dev_warn_once(&dev->dev, "Pen battery low\n");
		/* fall through */

	case BATTERY_NO_REPORT:
	case BATTERY_GOOD:
		x = le16_to_cpup((__le16 *)&data[2]);
		y = le16_to_cpup((__le16 *)&data[4]);

		/* pen-up event */
		if (x == 0 && y == 0)
			break;

		input_report_key(dev, BTN_TOUCH, data[1] & PEN_TIP);
		input_report_key(dev, BTN_RIGHT, data[1] & PEN_BUTTON_PRESSED);
		input_report_key(dev, BTN_TOOL_PEN, 1);
		input_report_abs(dev, ABS_X, (s16)x);
		input_report_abs(dev, ABS_Y, y);

		input_sync(dev);
		break;

	default:
		dev_warn_once(&pegasus->usbdev->dev,
			      "unknown answer from device\n");
	}
}

static void pegasus_irq(struct urb *urb)
{
	struct pegasus *pegasus = urb->context;
	struct usb_device *dev = pegasus->usbdev;
	int retval;

	switch (urb->status) {
	case 0:
		pegasus_parse_packet(pegasus);
		usb_mark_last_busy(pegasus->usbdev);
		break;

	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		dev_err(&dev->dev, "%s - urb shutting down with status: %d",
			__func__, urb->status);
		return;

	default:
		dev_err(&dev->dev, "%s - nonzero urb status received: %d",
			__func__, urb->status);
		break;
	}

	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
		dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d",
			__func__, retval);
}

static void pegasus_init(struct work_struct *work)
{
	struct pegasus *pegasus = container_of(work, struct pegasus, init);
	int error;

	error = pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
	if (error)
		dev_err(&pegasus->usbdev->dev, "pegasus_set_mode error: %d\n",
			error);
}

static int pegasus_open(struct input_dev *dev)
{
	struct pegasus *pegasus = input_get_drvdata(dev);
	int error;

	error = usb_autopm_get_interface(pegasus->intf);
	if (error)
		return error;

	pegasus->irq->dev = pegasus->usbdev;
	if (usb_submit_urb(pegasus->irq, GFP_KERNEL)) {
		error = -EIO;
		goto err_autopm_put;
	}

	error = pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
	if (error)
		goto err_kill_urb;

	return 0;

err_kill_urb:
	usb_kill_urb(pegasus->irq);
	cancel_work_sync(&pegasus->init);
err_autopm_put:
	usb_autopm_put_interface(pegasus->intf);
	return error;
}

static void pegasus_close(struct input_dev *dev)
{
	struct pegasus *pegasus = input_get_drvdata(dev);

	usb_kill_urb(pegasus->irq);
	cancel_work_sync(&pegasus->init);
	usb_autopm_put_interface(pegasus->intf);
}

static int pegasus_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_endpoint_descriptor *endpoint;
	struct pegasus *pegasus;
	struct input_dev *input_dev;
	int error;
	int pipe;

	/* We control interface 0 */
	if (intf->cur_altsetting->desc.bInterfaceNumber >= 1)
		return -ENODEV;

	/* Sanity check that the device has an endpoint */
	if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
		dev_err(&intf->dev, "Invalid number of endpoints\n");
		return -EINVAL;
	}

	endpoint = &intf->cur_altsetting->endpoint[0].desc;

	pegasus = kzalloc(sizeof(*pegasus), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!pegasus || !input_dev) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	pegasus->usbdev = dev;
	pegasus->dev = input_dev;
	pegasus->intf = intf;

	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
	pegasus->data_len = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

	pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL,
					   &pegasus->data_dma);
	if (!pegasus->data) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	pegasus->irq = usb_alloc_urb(0, GFP_KERNEL);
	if (!pegasus->irq) {
		error = -ENOMEM;
		goto err_free_dma;
	}

	usb_fill_int_urb(pegasus->irq, dev, pipe,
			 pegasus->data, pegasus->data_len,
			 pegasus_irq, pegasus, endpoint->bInterval);

	pegasus->irq->transfer_dma = pegasus->data_dma;
	pegasus->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	if (dev->manufacturer)
		strlcpy(pegasus->name, dev->manufacturer,
			sizeof(pegasus->name));

	if (dev->product) {
		if (dev->manufacturer)
			strlcat(pegasus->name, " ", sizeof(pegasus->name));
		strlcat(pegasus->name, dev->product, sizeof(pegasus->name));
	}

	if (!strlen(pegasus->name))
		snprintf(pegasus->name, sizeof(pegasus->name),
			 "USB Pegasus Device %04x:%04x",
			 le16_to_cpu(dev->descriptor.idVendor),
			 le16_to_cpu(dev->descriptor.idProduct));

	usb_make_path(dev, pegasus->phys, sizeof(pegasus->phys));
	strlcat(pegasus->phys, "/input0", sizeof(pegasus->phys));

	INIT_WORK(&pegasus->init, pegasus_init);

	usb_set_intfdata(intf, pegasus);

	input_dev->name = pegasus->name;
	input_dev->phys = pegasus->phys;
	usb_to_input_id(dev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, pegasus);

	input_dev->open = pegasus_open;
	input_dev->close = pegasus_close;

	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(EV_KEY, input_dev->evbit);

	__set_bit(ABS_X, input_dev->absbit);
	__set_bit(ABS_Y, input_dev->absbit);

	__set_bit(BTN_TOUCH, input_dev->keybit);
	__set_bit(BTN_RIGHT, input_dev->keybit);
	__set_bit(BTN_TOOL_PEN, input_dev->keybit);

	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
	__set_bit(INPUT_PROP_POINTER, input_dev->propbit);

	input_set_abs_params(input_dev, ABS_X, -1500, 1500, 8, 0);
	input_set_abs_params(input_dev, ABS_Y, 1600, 3000, 8, 0);

	error = input_register_device(pegasus->dev);
	if (error)
		goto err_free_urb;

	return 0;

err_free_urb:
	usb_free_urb(pegasus->irq);
err_free_dma:
	usb_free_coherent(dev, pegasus->data_len,
			  pegasus->data, pegasus->data_dma);
err_free_mem:
	input_free_device(input_dev);
	kfree(pegasus);
	usb_set_intfdata(intf, NULL);

	return error;
}

static void pegasus_disconnect(struct usb_interface *intf)
{
	struct pegasus *pegasus = usb_get_intfdata(intf);

	input_unregister_device(pegasus->dev);

	usb_free_urb(pegasus->irq);
	usb_free_coherent(interface_to_usbdev(intf),
			  pegasus->data_len, pegasus->data,
			  pegasus->data_dma);

	kfree(pegasus);
	usb_set_intfdata(intf, NULL);
}

static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct pegasus *pegasus = usb_get_intfdata(intf);

	mutex_lock(&pegasus->dev->mutex);
	usb_kill_urb(pegasus->irq);
	cancel_work_sync(&pegasus->init);
	mutex_unlock(&pegasus->dev->mutex);

	return 0;
}

static int pegasus_resume(struct usb_interface *intf)
{
	struct pegasus *pegasus = usb_get_intfdata(intf);
	int retval = 0;

	mutex_lock(&pegasus->dev->mutex);
	if (pegasus->dev->users && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
		retval = -EIO;
	mutex_unlock(&pegasus->dev->mutex);

	return retval;
}

static int pegasus_reset_resume(struct usb_interface *intf)
{
	struct pegasus *pegasus = usb_get_intfdata(intf);
	int retval = 0;

	mutex_lock(&pegasus->dev->mutex);
	if (pegasus->dev->users) {
		retval = pegasus_set_mode(pegasus, PEN_MODE_XY,
					  NOTETAKER_LED_MOUSE);
		if (!retval && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
			retval = -EIO;
	}
	mutex_unlock(&pegasus->dev->mutex);

	return retval;
}

static const struct usb_device_id pegasus_ids[] = {
	{ USB_DEVICE(USB_VENDOR_ID_PEGASUSTECH,
		     USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100) },
	{ }
};
MODULE_DEVICE_TABLE(usb, pegasus_ids);

static struct usb_driver pegasus_driver = {
	.name		= "pegasus_notetaker",
	.probe		= pegasus_probe,
	.disconnect	= pegasus_disconnect,
	.suspend	= pegasus_suspend,
	.resume		= pegasus_resume,
	.reset_resume	= pegasus_reset_resume,
	.id_table	= pegasus_ids,
	.supports_autosuspend = 1,
};

module_usb_driver(pegasus_driver);

MODULE_AUTHOR("Martin Kepplinger <martink@posteo.de>");
MODULE_DESCRIPTION("Pegasus Mobile Notetaker Pen tablet driver");
MODULE_LICENSE("GPL");
