/*
 * Touchwindow serial touchscreen driver
 *
 * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
 *
 * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
 * Copyright (c) 2004 Vojtech Pavlik
 * and Dan Streetman <ddstreet@ieee.org>
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

/*
 * 2005/02/19 Rick Koch:
 *   The Touchwindow I used is made by Edmark Corp. and
 *   constantly outputs a stream of 0's unless it is touched.
 *   It then outputs 3 bytes: X, Y, and a copy of Y.
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>

#define DRIVER_DESC	"Touchwindow serial touchscreen driver"

MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
 * Definitions & global arrays.
 */

#define TW_LENGTH 3

#define TW_MIN_XC 0
#define TW_MAX_XC 0xff
#define TW_MIN_YC 0
#define TW_MAX_YC 0xff

/*
 * Per-touchscreen data.
 */

struct tw {
	struct input_dev *dev;
	struct serio *serio;
	int idx;
	int touched;
	unsigned char data[TW_LENGTH];
	char phys[32];
};

static irqreturn_t tw_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct tw *tw = serio_get_drvdata(serio);
	struct input_dev *dev = tw->dev;

	if (data) {		/* touch */
		tw->touched = 1;
		tw->data[tw->idx++] = data;
		/* verify length and that the two Y's are the same */
		if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) {
			input_report_abs(dev, ABS_X, tw->data[0]);
			input_report_abs(dev, ABS_Y, tw->data[1]);
			input_report_key(dev, BTN_TOUCH, 1);
			input_sync(dev);
			tw->idx = 0;
		}
	} else if (tw->touched) {	/* untouch */
		input_report_key(dev, BTN_TOUCH, 0);
		input_sync(dev);
		tw->idx = 0;
		tw->touched = 0;
	}

	return IRQ_HANDLED;
}

/*
 * tw_disconnect() is the opposite of tw_connect()
 */

static void tw_disconnect(struct serio *serio)
{
	struct tw *tw = serio_get_drvdata(serio);

	input_get_device(tw->dev);
	input_unregister_device(tw->dev);
	serio_close(serio);
	serio_set_drvdata(serio, NULL);
	input_put_device(tw->dev);
	kfree(tw);
}

/*
 * tw_connect() is the routine that is called when someone adds a
 * new serio device that supports the Touchwin protocol and registers it as
 * an input device.
 */

static int tw_connect(struct serio *serio, struct serio_driver *drv)
{
	struct tw *tw;
	struct input_dev *input_dev;
	int err;

	tw = kzalloc(sizeof(struct tw), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!tw || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

	tw->serio = serio;
	tw->dev = input_dev;
	snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys);

	input_dev->private = tw;
	input_dev->name = "Touchwindow Serial TouchScreen";
	input_dev->phys = tw->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_TOUCHWIN;
	input_dev->id.product = 0;
	input_dev->id.version = 0x0100;
	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
	input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
	input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);

	serio_set_drvdata(serio, tw);

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

	err = input_register_device(tw->dev);
	if (err)
		goto fail3;

	return 0;

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

/*
 * The serio driver structure.
 */

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

MODULE_DEVICE_TABLE(serio, tw_serio_ids);

static struct serio_driver tw_drv = {
	.driver		= {
		.name	= "touchwin",
	},
	.description	= DRIVER_DESC,
	.id_table	= tw_serio_ids,
	.interrupt	= tw_interrupt,
	.connect	= tw_connect,
	.disconnect	= tw_disconnect,
};

/*
 * The functions for inserting/removing us as a module.
 */

static int __init tw_init(void)
{
	serio_register_driver(&tw_drv);
	return 0;
}

static void __exit tw_exit(void)
{
	serio_unregister_driver(&tw_drv);
}

module_init(tw_init);
module_exit(tw_exit);
