/*
 * 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/config.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 pt_regs *regs)
{
	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_regs (dev, regs);
	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 pt_regs *regs)
{
	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_regs (dev, regs);
	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 pt_regs *regs)
{
	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 explicitely
	 * 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_regs (dev, regs);
		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, struct pt_regs *regs)
{
	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, regs);
			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, regs);
			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, regs);
			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 pt_regs *regs)
{
	struct vsxxxaa *mouse = serio_get_drvdata (serio);

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

	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 fail;

	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->cdev.dev = &serio->dev;
	input_dev->private = mouse;

	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 fail;

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

	input_register_device (input_dev);

	return 0;

 fail:	serio_set_drvdata (serio, NULL);
	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)
{
	serio_register_driver(&vsxxxaa_drv);
	return 0;
}

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

module_init (vsxxxaa_init);
module_exit (vsxxxaa_exit);

