/*
 * Driver for	DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers)
 *		DEC VSXXX-GA mouse (rectangular mouse, with ball)
 *		DEC VSXXX-AB tablet (digitizer with hair cross or stylus)
 *
 * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
 *
 * The packet format was initially taken from a patch to GPM which is (C) 2001
 * by	Karsten Merker <merker@linuxtag.org>
 * and	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
 * Later on, I had access to the device's documentation (referenced below).
 */

/*
 * 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*
 * Building an adaptor to DE9 / DB25 RS232
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for
 * anything if you break your mouse, your computer or whatever!
 *
 * In theory, this mouse is a simple RS232 device. In practice, it has got
 * a quite uncommon plug and the requirement to additionally get a power
 * supply at +5V and -12V.
 *
 * If you look at the socket/jack (_not_ at the plug), we use this pin
 * numbering:
 *    _______
 *   / 7 6 5 \
 *  | 4 --- 3 |
 *   \  2 1  /
 *    -------
 *
 *	DEC socket	DE9	DB25	Note
 *	1 (GND)		5	7	-
 *	2 (RxD)		2	3	-
 *	3 (TxD)		3	2	-
 *	4 (-12V)	-	-	Somewhere from the PSU. At ATX, it's
 *					the thin blue wire at pin 12 of the
 *					ATX power connector. Only required for
 *					VSXXX-AA/-GA mice.
 *	5 (+5V)		-	-	PSU (red wires of ATX power connector
 *					on pin 4, 6, 19 or 20) or HDD power
 *					connector (also red wire).
 *	6 (+12V)	-	-	HDD power connector, yellow wire. Only
 *					required for VSXXX-AB digitizer.
 *	7 (dev. avail.)	-	-	The mouse shorts this one to pin 1.
 *					This way, the host computer can detect
 *					the mouse. To use it with the adaptor,
 *					simply don't connect this pin.
 *
 * So to get a working adaptor, you need to connect the mouse with three
 * wires to a RS232 port and two or three additional wires for +5V, +12V and
 * -12V to the PSU.
 *
 * Flow specification for the link is 4800, 8o1.
 *
 * The mice and tablet are described in "VCB02 Video Subsystem - Technical
 * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
 * specific for DEC documentation. Try
 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
 */

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/serio.h>

#define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"

MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#undef VSXXXAA_DEBUG
#ifdef VSXXXAA_DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...) do {} while (0)
#endif

#define VSXXXAA_INTRO_MASK	0x80
#define VSXXXAA_INTRO_HEAD	0x80
#define IS_HDR_BYTE(x)			\
	(((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD)

#define VSXXXAA_PACKET_MASK	0xe0
#define VSXXXAA_PACKET_REL	0x80
#define VSXXXAA_PACKET_ABS	0xc0
#define VSXXXAA_PACKET_POR	0xa0
#define MATCH_PACKET_TYPE(data, type)	\
	(((data) & VSXXXAA_PACKET_MASK) == (type))



struct vsxxxaa {
	struct input_dev *dev;
	struct serio *serio;
#define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
	unsigned char buf[BUFLEN];
	unsigned char count;
	unsigned char version;
	unsigned char country;
	unsigned char type;
	char name[64];
	char phys[32];
};

static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num)
{
	if (num >= mouse->count) {
		mouse->count = 0;
	} else {
		memmove(mouse->buf, mouse->buf + num, BUFLEN - num);
		mouse->count -= num;
	}
}

static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte)
{
	if (mouse->count == BUFLEN) {
		printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
			mouse->name, mouse->phys);
		vsxxxaa_drop_bytes(mouse, 1);
	}

	DBG(KERN_INFO "Queueing byte 0x%02x\n", byte);

	mouse->buf[mouse->count++] = byte;
}

static void vsxxxaa_detection_done(struct vsxxxaa *mouse)
{
	switch (mouse->type) {
	case 0x02:
		strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse",
			sizeof(mouse->name));
		break;

	case 0x04:
		strlcpy(mouse->name, "DEC VSXXX-AB digitizer",
			sizeof(mouse->name));
		break;

	default:
		snprintf(mouse->name, sizeof(mouse->name),
			 "unknown DEC pointer device (type = 0x%02x)",
			 mouse->type);
		break;
	}

	printk(KERN_INFO
		"Found %s version 0x%02x from country 0x%02x on port %s\n",
		mouse->name, mouse->version, mouse->country, mouse->phys);
}

/*
 * Returns number of bytes to be dropped, 0 if packet is okay.
 */
static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len)
{
	int i;

	/* First byte must be a header byte */
	if (!IS_HDR_BYTE(mouse->buf[0])) {
		DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
		return 1;
	}

	/* Check all following bytes */
	for (i = 1; i < packet_len; i++) {
		if (IS_HDR_BYTE(mouse->buf[i])) {
			printk(KERN_ERR
				"Need to drop %d bytes of a broken packet.\n",
				i - 1);
			DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
			    packet_len, i, mouse->buf[i]);
			return i - 1;
		}
	}

	return 0;
}

static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse,
					     unsigned char type, size_t len)
{
	return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type);
}

static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse)
{
	struct input_dev *dev = mouse->dev;
	unsigned char *buf = mouse->buf;
	int left, middle, right;
	int dx, dy;

	/*
	 * Check for normal stream packets. This is three bytes,
	 * with the first byte's 3 MSB set to 100.
	 *
	 * [0]:	1	0	0	SignX	SignY	Left	Middle	Right
	 * [1]: 0	dx	dx	dx	dx	dx	dx	dx
	 * [2]:	0	dy	dy	dy	dy	dy	dy	dy
	 */

	/*
	 * Low 7 bit of byte 1 are abs(dx), bit 7 is
	 * 0, bit 4 of byte 0 is direction.
	 */
	dx = buf[1] & 0x7f;
	dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1;

	/*
	 * Low 7 bit of byte 2 are abs(dy), bit 7 is
	 * 0, bit 3 of byte 0 is direction.
	 */
	dy = buf[2] & 0x7f;
	dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1;

	/*
	 * Get button state. It's the low three bits
	 * (for three buttons) of byte 0.
	 */
	left	= buf[0] & 0x04;
	middle	= buf[0] & 0x02;
	right	= buf[0] & 0x01;

	vsxxxaa_drop_bytes(mouse, 3);

	DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
	    mouse->name, mouse->phys, dx, dy,
	    left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r");

	/*
	 * Report what we've found so far...
	 */
	input_report_key(dev, BTN_LEFT, left);
	input_report_key(dev, BTN_MIDDLE, middle);
	input_report_key(dev, BTN_RIGHT, right);
	input_report_key(dev, BTN_TOUCH, 0);
	input_report_rel(dev, REL_X, dx);
	input_report_rel(dev, REL_Y, dy);
	input_sync(dev);
}

static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse)
{
	struct input_dev *dev = mouse->dev;
	unsigned char *buf = mouse->buf;
	int left, middle, right, touch;
	int x, y;

	/*
	 * Tablet position / button packet
	 *
	 * [0]:	1	1	0	B4	B3	B2	B1	Pr
	 * [1]:	0	0	X5	X4	X3	X2	X1	X0
	 * [2]:	0	0	X11	X10	X9	X8	X7	X6
	 * [3]:	0	0	Y5	Y4	Y3	Y2	Y1	Y0
	 * [4]:	0	0	Y11	Y10	Y9	Y8	Y7	Y6
	 */

	/*
	 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
	 * counts down->top while monitor counts top->bottom.
	 */
	x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
	y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
	y = 1023 - y;

	/*
	 * Get button state. It's bits <4..1> of byte 0.
	 */
	left	= buf[0] & 0x02;
	middle	= buf[0] & 0x04;
	right	= buf[0] & 0x08;
	touch	= buf[0] & 0x10;

	vsxxxaa_drop_bytes(mouse, 5);

	DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
	    mouse->name, mouse->phys, x, y,
	    left ? "L" : "l", middle ? "M" : "m",
	    right ? "R" : "r", touch ? "T" : "t");

	/*
	 * Report what we've found so far...
	 */
	input_report_key(dev, BTN_LEFT, left);
	input_report_key(dev, BTN_MIDDLE, middle);
	input_report_key(dev, BTN_RIGHT, right);
	input_report_key(dev, BTN_TOUCH, touch);
	input_report_abs(dev, ABS_X, x);
	input_report_abs(dev, ABS_Y, y);
	input_sync(dev);
}

static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse)
{
	struct input_dev *dev = mouse->dev;
	unsigned char *buf = mouse->buf;
	int left, middle, right;
	unsigned char error;

	/*
	 * Check for Power-On-Reset packets. These are sent out
	 * after plugging the mouse in, or when explicitly
	 * requested by sending 'T'.
	 *
	 * [0]:	1	0	1	0	R3	R2	R1	R0
	 * [1]:	0	M2	M1	M0	D3	D2	D1	D0
	 * [2]:	0	E6	E5	E4	E3	E2	E1	E0
	 * [3]:	0	0	0	0	0	Left	Middle	Right
	 *
	 * M: manufacturer location code
	 * R: revision code
	 * E: Error code. If it's in the range of 0x00..0x1f, only some
	 *    minor problem occurred. Errors >= 0x20 are considered bad
	 *    and the device may not work properly...
	 * D: <0010> == mouse, <0100> == tablet
	 */

	mouse->version = buf[0] & 0x0f;
	mouse->country = (buf[1] >> 4) & 0x07;
	mouse->type = buf[1] & 0x0f;
	error = buf[2] & 0x7f;

	/*
	 * Get button state. It's the low three bits
	 * (for three buttons) of byte 0. Maybe even the bit <3>
	 * has some meaning if a tablet is attached.
	 */
	left	= buf[0] & 0x04;
	middle	= buf[0] & 0x02;
	right	= buf[0] & 0x01;

	vsxxxaa_drop_bytes(mouse, 4);
	vsxxxaa_detection_done(mouse);

	if (error <= 0x1f) {
		/* No (serious) error. Report buttons */
		input_report_key(dev, BTN_LEFT, left);
		input_report_key(dev, BTN_MIDDLE, middle);
		input_report_key(dev, BTN_RIGHT, right);
		input_report_key(dev, BTN_TOUCH, 0);
		input_sync(dev);

		if (error != 0)
			printk(KERN_INFO "Your %s on %s reports error=0x%02x\n",
				mouse->name, mouse->phys, error);

	}

	/*
	 * If the mouse was hot-plugged, we need to force differential mode
	 * now... However, give it a second to recover from it's reset.
	 */
	printk(KERN_NOTICE
		"%s on %s: Forcing standard packet format, "
		"incremental streaming mode and 72 samples/sec\n",
		mouse->name, mouse->phys);
	serio_write(mouse->serio, 'S');	/* Standard format */
	mdelay(50);
	serio_write(mouse->serio, 'R');	/* Incremental */
	mdelay(50);
	serio_write(mouse->serio, 'L');	/* 72 samples/sec */
}

static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse)
{
	unsigned char *buf = mouse->buf;
	int stray_bytes;

	/*
	 * Parse buffer to death...
	 */
	do {
		/*
		 * Out of sync? Throw away what we don't understand. Each
		 * packet starts with a byte whose bit 7 is set. Unhandled
		 * packets (ie. which we don't know about or simply b0rk3d
		 * data...) will get shifted out of the buffer after some
		 * activity on the mouse.
		 */
		while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
			printk(KERN_ERR "%s on %s: Dropping a byte to regain "
				"sync with mouse data stream...\n",
				mouse->name, mouse->phys);
			vsxxxaa_drop_bytes(mouse, 1);
		}

		/*
		 * Check for packets we know about.
		 */

		if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) {
			/* Check for broken packet */
			stray_bytes = vsxxxaa_check_packet(mouse, 3);
			if (!stray_bytes)
				vsxxxaa_handle_REL_packet(mouse);

		} else if (vsxxxaa_smells_like_packet(mouse,
						      VSXXXAA_PACKET_ABS, 5)) {
			/* Check for broken packet */
			stray_bytes = vsxxxaa_check_packet(mouse, 5);
			if (!stray_bytes)
				vsxxxaa_handle_ABS_packet(mouse);

		} else if (vsxxxaa_smells_like_packet(mouse,
						      VSXXXAA_PACKET_POR, 4)) {
			/* Check for broken packet */
			stray_bytes = vsxxxaa_check_packet(mouse, 4);
			if (!stray_bytes)
				vsxxxaa_handle_POR_packet(mouse);

		} else {
			break; /* No REL, ABS or POR packet found */
		}

		if (stray_bytes > 0) {
			printk(KERN_ERR "Dropping %d bytes now...\n",
				stray_bytes);
			vsxxxaa_drop_bytes(mouse, stray_bytes);
		}

	} while (1);
}

static irqreturn_t vsxxxaa_interrupt(struct serio *serio,
				     unsigned char data, unsigned int flags)
{
	struct vsxxxaa *mouse = serio_get_drvdata(serio);

	vsxxxaa_queue_byte(mouse, data);
	vsxxxaa_parse_buffer(mouse);

	return IRQ_HANDLED;
}

static void vsxxxaa_disconnect(struct serio *serio)
{
	struct vsxxxaa *mouse = serio_get_drvdata(serio);

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

static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv)
{
	struct vsxxxaa *mouse;
	struct input_dev *input_dev;
	int err = -ENOMEM;

	mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!mouse || !input_dev)
		goto fail1;

	mouse->dev = input_dev;
	mouse->serio = serio;
	strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
		 sizeof(mouse->name));
	snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys);

	input_dev->name = mouse->name;
	input_dev->phys = mouse->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->dev.parent = &serio->dev;

	__set_bit(EV_KEY, input_dev->evbit);		/* We have buttons */
	__set_bit(EV_REL, input_dev->evbit);
	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
	__set_bit(BTN_MIDDLE, input_dev->keybit);
	__set_bit(BTN_RIGHT, input_dev->keybit);
	__set_bit(BTN_TOUCH, input_dev->keybit);	/* ...and Tablet */
	__set_bit(REL_X, input_dev->relbit);
	__set_bit(REL_Y, input_dev->relbit);
	input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);

	serio_set_drvdata(serio, mouse);

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

	/*
	 * Request selftest. Standard packet format and differential
	 * mode will be requested after the device ID'ed successfully.
	 */
	serio_write(serio, 'T'); /* Test */

	err = input_register_device(input_dev);
	if (err)
		goto fail3;

	return 0;

 fail3:	serio_close(serio);
 fail2:	serio_set_drvdata(serio, NULL);
 fail1:	input_free_device(input_dev);
	kfree(mouse);
	return err;
}

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

MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);

static struct serio_driver vsxxxaa_drv = {
	.driver		= {
		.name	= "vsxxxaa",
	},
	.description	= DRIVER_DESC,
	.id_table	= vsxxaa_serio_ids,
	.connect	= vsxxxaa_connect,
	.interrupt	= vsxxxaa_interrupt,
	.disconnect	= vsxxxaa_disconnect,
};

module_serio_driver(vsxxxaa_drv);
