/*
 * Wacom protocol 4 serial tablet driver
 *
 * Copyright 2014      Hans de Goede <hdegoede@redhat.com>
 * Copyright 2011-2012 Julian Squires <julian@cipht.net>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version of 2 of the License, or (at your
 * option) any later version. See the file COPYING in the main directory of
 * this archive for more details.
 *
 * Many thanks to Bill Seremetis, without whom PenPartner support
 * would not have been possible. Thanks to Patrick Mahoney.
 *
 * This driver was developed with reference to much code written by others,
 * particularly:
 *  - elo, gunze drivers by Vojtech Pavlik <vojtech@ucw.cz>;
 *  - wacom_w8001 driver by Jaya Kumar <jayakumar.lkml@gmail.com>;
 *  - the USB wacom input driver, credited to many people
 *    (see drivers/input/tablet/wacom.h);
 *  - new and old versions of linuxwacom / xf86-input-wacom credited to
 *    Frederic Lepied, France. <Lepied@XFree86.org> and
 *    Ping Cheng, Wacom. <pingc@wacom.com>;
 *  - and xf86wacom.c (a presumably ancient version of the linuxwacom code),
 *    by Frederic Lepied and Raph Levien <raph@gtk.org>.
 *
 * To do:
 *  - support pad buttons; (requires access to a model with pad buttons)
 *  - support (protocol 4-style) tilt (requires access to a > 1.4 rom model)
 */

/*
 * Wacom serial protocol 4 documentation taken from linuxwacom-0.9.9 code,
 * protocol 4 uses 7 or 9 byte of data in the following format:
 *
 *	Byte 1
 *	bit 7  Sync bit always 1
 *	bit 6  Pointing device detected
 *	bit 5  Cursor = 0 / Stylus = 1
 *	bit 4  Reserved
 *	bit 3  1 if a button on the pointing device has been pressed
 *	bit 2  P0 (optional)
 *	bit 1  X15
 *	bit 0  X14
 *
 *	Byte 2
 *	bit 7  Always 0
 *	bits 6-0 = X13 - X7
 *
 *	Byte 3
 *	bit 7  Always 0
 *	bits 6-0 = X6 - X0
 *
 *	Byte 4
 *	bit 7  Always 0
 *	bit 6  B3
 *	bit 5  B2
 *	bit 4  B1
 *	bit 3  B0
 *	bit 2  P1 (optional)
 *	bit 1  Y15
 *	bit 0  Y14
 *
 *	Byte 5
 *	bit 7  Always 0
 *	bits 6-0 = Y13 - Y7
 *
 *	Byte 6
 *	bit 7  Always 0
 *	bits 6-0 = Y6 - Y0
 *
 *	Byte 7
 *	bit 7 Always 0
 *	bit 6  Sign of pressure data; or wheel-rel for cursor tool
 *	bit 5  P7; or REL1 for cursor tool
 *	bit 4  P6; or REL0 for cursor tool
 *	bit 3  P5
 *	bit 2  P4
 *	bit 1  P3
 *	bit 0  P2
 *
 *	byte 8 and 9 are optional and present only
 *	in tilt mode.
 *
 *	Byte 8
 *	bit 7 Always 0
 *	bit 6 Sign of tilt X
 *	bit 5  Xt6
 *	bit 4  Xt5
 *	bit 3  Xt4
 *	bit 2  Xt3
 *	bit 1  Xt2
 *	bit 0  Xt1
 *
 *	Byte 9
 *	bit 7 Always 0
 *	bit 6 Sign of tilt Y
 *	bit 5  Yt6
 *	bit 4  Yt5
 *	bit 3  Yt4
 *	bit 2  Yt3
 *	bit 1  Yt2
 *	bit 0  Yt1
 */

#include <linux/completion.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/slab.h>
#include <linux/string.h>

MODULE_AUTHOR("Julian Squires <julian@cipht.net>, Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Wacom protocol 4 serial tablet driver");
MODULE_LICENSE("GPL");

#define REQUEST_MODEL_AND_ROM_VERSION	"~#"
#define REQUEST_MAX_COORDINATES		"~C\r"
#define REQUEST_CONFIGURATION_STRING	"~R\r"
#define REQUEST_RESET_TO_PROTOCOL_IV	"\r#"
/*
 * Note: sending "\r$\r" causes at least the Digitizer II to send
 * packets in ASCII instead of binary.  "\r#" seems to undo that.
 */

#define COMMAND_START_SENDING_PACKETS		"ST\r"
#define COMMAND_STOP_SENDING_PACKETS		"SP\r"
#define COMMAND_MULTI_MODE_INPUT		"MU1\r"
#define COMMAND_ORIGIN_IN_UPPER_LEFT		"OC1\r"
#define COMMAND_ENABLE_ALL_MACRO_BUTTONS	"~M0\r"
#define COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS	"~M1\r"
#define COMMAND_TRANSMIT_AT_MAX_RATE		"IT0\r"
#define COMMAND_DISABLE_INCREMENTAL_MODE	"IN0\r"
#define COMMAND_ENABLE_CONTINUOUS_MODE		"SR\r"
#define COMMAND_ENABLE_PRESSURE_MODE		"PH1\r"
#define COMMAND_Z_FILTER			"ZF1\r"

/* Note that this is a protocol 4 packet without tilt information. */
#define PACKET_LENGTH		7
#define DATA_SIZE		32

/* flags */
#define F_COVERS_SCREEN		0x01
#define F_HAS_STYLUS2		0x02
#define F_HAS_SCROLLWHEEL	0x04

/* device IDs */
#define STYLUS_DEVICE_ID	0x02
#define CURSOR_DEVICE_ID	0x06
#define ERASER_DEVICE_ID	0x0A

enum { STYLUS = 1, ERASER, CURSOR };

static const struct {
	int device_id;
	int input_id;
} tools[] = {
	{ 0, 0 },
	{ STYLUS_DEVICE_ID, BTN_TOOL_PEN },
	{ ERASER_DEVICE_ID, BTN_TOOL_RUBBER },
	{ CURSOR_DEVICE_ID, BTN_TOOL_MOUSE },
};

struct wacom {
	struct input_dev *dev;
	struct completion cmd_done;
	int result;
	u8 expect;
	u8 eraser_mask;
	unsigned int extra_z_bits;
	unsigned int flags;
	unsigned int res_x, res_y;
	unsigned int max_x, max_y;
	unsigned int tool;
	unsigned int idx;
	u8 data[DATA_SIZE];
	char phys[32];
};

enum {
	MODEL_CINTIQ		= 0x504C, /* PL */
	MODEL_CINTIQ2		= 0x4454, /* DT */
	MODEL_DIGITIZER_II	= 0x5544, /* UD */
	MODEL_GRAPHIRE		= 0x4554, /* ET */
	MODEL_PENPARTNER	= 0x4354, /* CT */
};

static void wacom_handle_model_response(struct wacom *wacom)
{
	int major_v, minor_v, r = 0;
	char *p;

	p = strrchr(wacom->data, 'V');
	if (p)
		r = sscanf(p + 1, "%u.%u", &major_v, &minor_v);
	if (r != 2)
		major_v = minor_v = 0;

	switch (wacom->data[2] << 8 | wacom->data[3]) {
	case MODEL_CINTIQ:	/* UNTESTED */
	case MODEL_CINTIQ2:
		if ((wacom->data[2] << 8 | wacom->data[3]) == MODEL_CINTIQ) {
			wacom->dev->name = "Wacom Cintiq";
			wacom->dev->id.version = MODEL_CINTIQ;
		} else {
			wacom->dev->name = "Wacom Cintiq II";
			wacom->dev->id.version = MODEL_CINTIQ2;
		}
		wacom->res_x = 508;
		wacom->res_y = 508;

		switch (wacom->data[5] << 8 | wacom->data[6]) {
		case 0x3731: /* PL-710 */
			wacom->res_x = 2540;
			wacom->res_y = 2540;
			/* fall through */
		case 0x3535: /* PL-550 */
		case 0x3830: /* PL-800 */
			wacom->extra_z_bits = 2;
		}

		wacom->flags = F_COVERS_SCREEN;
		break;

	case MODEL_PENPARTNER:
		wacom->dev->name = "Wacom Penpartner";
		wacom->dev->id.version = MODEL_PENPARTNER;
		wacom->res_x = 1000;
		wacom->res_y = 1000;
		break;

	case MODEL_GRAPHIRE:
		wacom->dev->name = "Wacom Graphire";
		wacom->dev->id.version = MODEL_GRAPHIRE;
		wacom->res_x = 1016;
		wacom->res_y = 1016;
		wacom->max_x = 5103;
		wacom->max_y = 3711;
		wacom->extra_z_bits = 2;
		wacom->eraser_mask = 0x08;
		wacom->flags = F_HAS_STYLUS2 | F_HAS_SCROLLWHEEL;
		break;

	case MODEL_DIGITIZER_II:
		wacom->dev->name = "Wacom Digitizer II";
		wacom->dev->id.version = MODEL_DIGITIZER_II;
		if (major_v == 1 && minor_v <= 2)
			wacom->extra_z_bits = 0; /* UNTESTED */
		break;

	default:
		dev_err(&wacom->dev->dev, "Unsupported Wacom model %s\n",
			wacom->data);
		wacom->result = -ENODEV;
		return;
	}

	dev_info(&wacom->dev->dev, "%s tablet, version %u.%u\n",
		 wacom->dev->name, major_v, minor_v);
}

static void wacom_handle_configuration_response(struct wacom *wacom)
{
	int r, skip;

	dev_dbg(&wacom->dev->dev, "Configuration string: %s\n", wacom->data);
	r = sscanf(wacom->data, "~R%x,%u,%u,%u,%u", &skip, &skip, &skip,
		   &wacom->res_x, &wacom->res_y);
	if (r != 5)
		dev_warn(&wacom->dev->dev, "could not get resolution\n");
}

static void wacom_handle_coordinates_response(struct wacom *wacom)
{
	int r;

	dev_dbg(&wacom->dev->dev, "Coordinates string: %s\n", wacom->data);
	r = sscanf(wacom->data, "~C%u,%u", &wacom->max_x, &wacom->max_y);
	if (r != 2)
		dev_warn(&wacom->dev->dev, "could not get max coordinates\n");
}

static void wacom_handle_response(struct wacom *wacom)
{
	if (wacom->data[0] != '~' || wacom->data[1] != wacom->expect) {
		dev_err(&wacom->dev->dev,
			"Wacom got an unexpected response: %s\n", wacom->data);
		wacom->result = -EIO;
	} else {
		wacom->result = 0;

		switch (wacom->data[1]) {
		case '#':
			wacom_handle_model_response(wacom);
			break;
		case 'R':
			wacom_handle_configuration_response(wacom);
			break;
		case 'C':
			wacom_handle_coordinates_response(wacom);
			break;
		}
	}

	complete(&wacom->cmd_done);
}

static void wacom_handle_packet(struct wacom *wacom)
{
	u8 in_proximity_p, stylus_p, button;
	unsigned int tool;
	int x, y, z;

	in_proximity_p = wacom->data[0] & 0x40;
	stylus_p = wacom->data[0] & 0x20;
	button = (wacom->data[3] & 0x78) >> 3;
	x = (wacom->data[0] & 3) << 14 | wacom->data[1]<<7 | wacom->data[2];
	y = (wacom->data[3] & 3) << 14 | wacom->data[4]<<7 | wacom->data[5];

	if (in_proximity_p && stylus_p) {
		z = wacom->data[6] & 0x7f;
		if (wacom->extra_z_bits >= 1)
			z = z << 1 | (wacom->data[3] & 0x4) >> 2;
		if (wacom->extra_z_bits > 1)
			z = z << 1 | (wacom->data[0] & 0x4) >> 2;
		z = z ^ (0x40 << wacom->extra_z_bits);
	} else {
		z = -1;
	}

	if (stylus_p)
		tool = (button & wacom->eraser_mask) ? ERASER : STYLUS;
	else
		tool = CURSOR;

	if (tool != wacom->tool && wacom->tool != 0) {
		input_report_key(wacom->dev, tools[wacom->tool].input_id, 0);
		input_sync(wacom->dev);
	}
	wacom->tool = tool;

	input_report_key(wacom->dev, tools[tool].input_id, in_proximity_p);
	input_report_abs(wacom->dev, ABS_MISC,
			 in_proximity_p ? tools[tool].device_id : 0);
	input_report_abs(wacom->dev, ABS_X, x);
	input_report_abs(wacom->dev, ABS_Y, y);
	input_report_abs(wacom->dev, ABS_PRESSURE, z);
	if (stylus_p) {
		input_report_key(wacom->dev, BTN_TOUCH, button & 1);
		input_report_key(wacom->dev, BTN_STYLUS, button & 2);
		input_report_key(wacom->dev, BTN_STYLUS2, button & 4);
	} else {
		input_report_key(wacom->dev, BTN_LEFT, button & 1);
		input_report_key(wacom->dev, BTN_RIGHT, button & 2);
		input_report_key(wacom->dev, BTN_MIDDLE, button & 4);
		/* handle relative wheel for non-stylus device */
		z = (wacom->data[6] & 0x30) >> 4;
		if (wacom->data[6] & 0x40)
			z = -z;
		input_report_rel(wacom->dev, REL_WHEEL, z);
	}
	input_sync(wacom->dev);
}

static void wacom_clear_data_buf(struct wacom *wacom)
{
	memset(wacom->data, 0, DATA_SIZE);
	wacom->idx = 0;
}

static irqreturn_t wacom_interrupt(struct serio *serio, unsigned char data,
				   unsigned int flags)
{
	struct wacom *wacom = serio_get_drvdata(serio);

	if (data & 0x80)
		wacom->idx = 0;

	/*
	 * We're either expecting a carriage return-terminated ASCII
	 * response string, or a seven-byte packet with the MSB set on
	 * the first byte.
	 *
	 * Note however that some tablets (the PenPartner, for
	 * example) don't send a carriage return at the end of a
	 * command.  We handle these by waiting for timeout.
	 */
	if (data == '\r' && !(wacom->data[0] & 0x80)) {
		wacom_handle_response(wacom);
		wacom_clear_data_buf(wacom);
		return IRQ_HANDLED;
	}

	/* Leave place for 0 termination */
	if (wacom->idx > (DATA_SIZE - 2)) {
		dev_dbg(&wacom->dev->dev,
			"throwing away %d bytes of garbage\n", wacom->idx);
		wacom_clear_data_buf(wacom);
	}
	wacom->data[wacom->idx++] = data;

	if (wacom->idx == PACKET_LENGTH && (wacom->data[0] & 0x80)) {
		wacom_handle_packet(wacom);
		wacom_clear_data_buf(wacom);
	}

	return IRQ_HANDLED;
}

static void wacom_disconnect(struct serio *serio)
{
	struct wacom *wacom = serio_get_drvdata(serio);

	serio_close(serio);
	serio_set_drvdata(serio, NULL);
	input_unregister_device(wacom->dev);
	kfree(wacom);
}

static int wacom_send(struct serio *serio, const u8 *command)
{
	int err = 0;

	for (; !err && *command; command++)
		err = serio_write(serio, *command);

	return err;
}

static int wacom_send_setup_string(struct wacom *wacom, struct serio *serio)
{
	const u8 *cmd;

	switch (wacom->dev->id.version) {
	case MODEL_CINTIQ:	/* UNTESTED */
		cmd = COMMAND_ORIGIN_IN_UPPER_LEFT
			COMMAND_TRANSMIT_AT_MAX_RATE
			COMMAND_ENABLE_CONTINUOUS_MODE
			COMMAND_START_SENDING_PACKETS;
		break;

	case MODEL_PENPARTNER:
		cmd = COMMAND_ENABLE_PRESSURE_MODE
			COMMAND_START_SENDING_PACKETS;
		break;

	default:
		cmd = COMMAND_MULTI_MODE_INPUT
			COMMAND_ORIGIN_IN_UPPER_LEFT
			COMMAND_ENABLE_ALL_MACRO_BUTTONS
			COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS
			COMMAND_TRANSMIT_AT_MAX_RATE
			COMMAND_DISABLE_INCREMENTAL_MODE
			COMMAND_ENABLE_CONTINUOUS_MODE
			COMMAND_Z_FILTER
			COMMAND_START_SENDING_PACKETS;
		break;
	}

	return wacom_send(serio, cmd);
}

static int wacom_send_and_wait(struct wacom *wacom, struct serio *serio,
			       const u8 *cmd, const char *desc)
{
	int err;
	unsigned long u;

	wacom->expect = cmd[1];
	init_completion(&wacom->cmd_done);

	err = wacom_send(serio, cmd);
	if (err)
		return err;

	u = wait_for_completion_timeout(&wacom->cmd_done, HZ);
	if (u == 0) {
		/* Timeout, process what we've received. */
		wacom_handle_response(wacom);
	}

	wacom->expect = 0;
	return wacom->result;
}

static int wacom_setup(struct wacom *wacom, struct serio *serio)
{
	int err;

	/* Note that setting the link speed is the job of inputattach.
	 * We assume that reset negotiation has already happened,
	 * here. */
	err = wacom_send_and_wait(wacom, serio, REQUEST_MODEL_AND_ROM_VERSION,
				  "model and version");
	if (err)
		return err;

	if (!(wacom->res_x && wacom->res_y)) {
		err = wacom_send_and_wait(wacom, serio,
					  REQUEST_CONFIGURATION_STRING,
					  "configuration string");
		if (err)
			return err;
	}

	if (!(wacom->max_x && wacom->max_y)) {
		err = wacom_send_and_wait(wacom, serio,
					  REQUEST_MAX_COORDINATES,
					  "coordinates string");
		if (err)
			return err;
	}

	return wacom_send_setup_string(wacom, serio);
}

static int wacom_connect(struct serio *serio, struct serio_driver *drv)
{
	struct wacom *wacom;
	struct input_dev *input_dev;
	int err = -ENOMEM;

	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!wacom || !input_dev)
		goto free_device;

	wacom->dev = input_dev;
	wacom->extra_z_bits = 1;
	wacom->eraser_mask = 0x04;
	wacom->tool = wacom->idx = 0;
	snprintf(wacom->phys, sizeof(wacom->phys), "%s/input0", serio->phys);
	input_dev->phys = wacom->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor  = SERIO_WACOM_IV;
	input_dev->id.product = serio->id.extra;
	input_dev->dev.parent = &serio->dev;

	input_dev->evbit[0] =
		BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_REL);
	set_bit(ABS_MISC, input_dev->absbit);
	set_bit(BTN_TOOL_PEN, input_dev->keybit);
	set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
	set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
	set_bit(BTN_TOUCH, input_dev->keybit);
	set_bit(BTN_STYLUS, input_dev->keybit);
	set_bit(BTN_LEFT, input_dev->keybit);
	set_bit(BTN_RIGHT, input_dev->keybit);
	set_bit(BTN_MIDDLE, input_dev->keybit);

	serio_set_drvdata(serio, wacom);

	err = serio_open(serio, drv);
	if (err)
		goto free_device;

	err = wacom_setup(wacom, serio);
	if (err)
		goto close_serio;

	set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
	if (!(wacom->flags & F_COVERS_SCREEN))
		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);

	if (wacom->flags & F_HAS_STYLUS2)
		__set_bit(BTN_STYLUS2, input_dev->keybit);

	if (wacom->flags & F_HAS_SCROLLWHEEL)
		__set_bit(REL_WHEEL, input_dev->relbit);

	input_abs_set_res(wacom->dev, ABS_X, wacom->res_x);
	input_abs_set_res(wacom->dev, ABS_Y, wacom->res_y);
	input_set_abs_params(wacom->dev, ABS_X, 0, wacom->max_x, 0, 0);
	input_set_abs_params(wacom->dev, ABS_Y, 0, wacom->max_y, 0, 0);
	input_set_abs_params(wacom->dev, ABS_PRESSURE, -1,
			     (1 << (7 + wacom->extra_z_bits)) - 1, 0, 0);

	err = input_register_device(wacom->dev);
	if (err)
		goto close_serio;

	return 0;

close_serio:
	serio_close(serio);
free_device:
	serio_set_drvdata(serio, NULL);
	input_free_device(input_dev);
	kfree(wacom);
	return err;
}

static struct serio_device_id wacom_serio_ids[] = {
	{
		.type	= SERIO_RS232,
		.proto	= SERIO_WACOM_IV,
		.id	= SERIO_ANY,
		.extra	= SERIO_ANY,
	},
	{ 0 }
};

MODULE_DEVICE_TABLE(serio, wacom_serio_ids);

static struct serio_driver wacom_drv = {
	.driver		= {
		.name	= "wacom_serial4",
	},
	.description	= "Wacom protocol 4 serial tablet driver",
	.id_table	= wacom_serio_ids,
	.interrupt	= wacom_interrupt,
	.connect	= wacom_connect,
	.disconnect	= wacom_disconnect,
};

module_serio_driver(wacom_drv);
