/*
 * 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>
#include <linux/init.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 - 1, 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 */
	if (packet_len > 1) {
		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)? 1: 0;
	middle	= (buf[0] & 0x02)? 1: 0;
	right	= (buf[0] & 0x01)? 1: 0;

	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)? 1: 0;
	middle	= (buf[0] & 0x04)? 1: 0;
	right	= (buf[0] & 0x08)? 1: 0;
	touch	= (buf[0] & 0x10)? 1: 0;

	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 occured. 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)? 1: 0;
	middle	= (buf[0] & 0x02)? 1: 0;
	right	= (buf[0] & 0x01)? 1: 0;

	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: Forceing standard packet format, "
			"incremental streaming mode and 72 samples/sec\n",
			mouse->name, mouse->phys);
	mouse->serio->write (mouse->serio, 'S');	/* Standard format */
	mdelay (50);
	mouse->serio->write (mouse->serio, 'R');	/* Incremental */
	mdelay (50);
	mouse->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 > 0) {
				printk (KERN_ERR "Dropping %d bytes now...\n",
						stray_bytes);
				vsxxxaa_drop_bytes (mouse, stray_bytes);
				continue;
			}

			vsxxxaa_handle_REL_packet (mouse);
			continue; /* More to parse? */
		}

		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
			/* Check for broken packet */
			stray_bytes = vsxxxaa_check_packet (mouse, 5);
			if (stray_bytes > 0) {
				printk (KERN_ERR "Dropping %d bytes now...\n",
						stray_bytes);
				vsxxxaa_drop_bytes (mouse, stray_bytes);
				continue;
			}

			vsxxxaa_handle_ABS_packet (mouse);
			continue; /* More to parse? */
		}

		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
			/* Check for broken packet */
			stray_bytes = vsxxxaa_check_packet (mouse, 4);
			if (stray_bytes > 0) {
				printk (KERN_ERR "Dropping %d bytes now...\n",
						stray_bytes);
				vsxxxaa_drop_bytes (mouse, stray_bytes);
				continue;
			}

			vsxxxaa_handle_POR_packet (mouse);
			continue; /* More to parse? */
		}

		break; /* No REL, ABS or POR packet found */
	} 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,
};

static int __init
vsxxxaa_init (void)
{
	return serio_register_driver(&vsxxxaa_drv);
}

static void __exit
vsxxxaa_exit (void)
{
	serio_unregister_driver(&vsxxxaa_drv);
}

module_init (vsxxxaa_init);
module_exit (vsxxxaa_exit);

