/*
 * $Id: tsdev.c,v 1.15 2002/04/10 16:50:19 jsimmons Exp $
 *
 *  Copyright (c) 2001 "Crazy" james Simmons
 *
 *  Compaq touchscreen protocol driver. The protocol emulated by this driver
 *  is obsolete; for new programs use the tslib library which can read directly
 *  from evdev and perform dejittering, variance filtering and calibration -
 *  all in user space, not at kernel level. The meaning of this driver is
 *  to allow usage of newer input drivers with old applications that use the
 *  old /dev/h3600_ts and /dev/h3600_tsraw devices.
 *
 *  09-Apr-2004: Andrew Zabolotny <zap@homelink.ru>
 *      Fixed to actually work, not just output random numbers.
 *      Added support for both h3600_ts and h3600_tsraw protocol
 *      emulation.
 */

/*
 * 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
 *
 * Should you need to contact me, the author, you can do so either by
 * e-mail - mail your message to <jsimmons@infradead.org>.
 */

#define TSDEV_MINOR_BASE 	128
#define TSDEV_MINORS		32
/* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */
#define TSDEV_MINOR_MASK	15
#define TSDEV_BUFFER_SIZE	64

#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/major.h>
#include <linux/config.h>
#include <linux/smp_lock.h>
#include <linux/random.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>

#ifndef CONFIG_INPUT_TSDEV_SCREEN_X
#define CONFIG_INPUT_TSDEV_SCREEN_X	240
#endif
#ifndef CONFIG_INPUT_TSDEV_SCREEN_Y
#define CONFIG_INPUT_TSDEV_SCREEN_Y	320
#endif

/* This driver emulates both protocols of the old h3600_ts and h3600_tsraw
 * devices. The first one must output X/Y data in 'cooked' format, e.g.
 * filtered, dejittered and calibrated. Second device just outputs raw
 * data received from the hardware.
 *
 * This driver doesn't support filtering and dejittering; it supports only
 * calibration. Filtering and dejittering must be done in the low-level
 * driver, if needed, because it may gain additional benefits from knowing
 * the low-level details, the nature of noise and so on.
 *
 * The driver precomputes a calibration matrix given the initial xres and
 * yres values (quite innacurate for most touchscreens) that will result
 * in a more or less expected range of output values. The driver supports
 * the TS_SET_CAL ioctl, which will replace the calibration matrix with a
 * new one, supposedly generated from the values taken from the raw device.
 */

MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
MODULE_DESCRIPTION("Input driver to touchscreen converter");
MODULE_LICENSE("GPL");

static int xres = CONFIG_INPUT_TSDEV_SCREEN_X;
module_param(xres, uint, 0);
MODULE_PARM_DESC(xres, "Horizontal screen resolution (can be negative for X-mirror)");

static int yres = CONFIG_INPUT_TSDEV_SCREEN_Y;
module_param(yres, uint, 0);
MODULE_PARM_DESC(yres, "Vertical screen resolution (can be negative for Y-mirror)");

/* From Compaq's Touch Screen Specification version 0.2 (draft) */
struct ts_event {
	short pressure;
	short x;
	short y;
	short millisecs;
};

struct ts_calibration {
	int xscale;
	int xtrans;
	int yscale;
	int ytrans;
	int xyswap;
};

struct tsdev {
	int exist;
	int open;
	int minor;
	char name[8];
	wait_queue_head_t wait;
	struct list_head list;
	struct input_handle handle;
	int x, y, pressure;
	struct ts_calibration cal;
};

struct tsdev_list {
	struct fasync_struct *fasync;
	struct list_head node;
	struct tsdev *tsdev;
	int head, tail;
	struct ts_event event[TSDEV_BUFFER_SIZE];
	int raw;
};

/* The following ioctl codes are defined ONLY for backward compatibility.
 * Don't use tsdev for new developement; use the tslib library instead.
 * Touchscreen calibration is a fully userspace task.
 */
/* Use 'f' as magic number */
#define IOC_H3600_TS_MAGIC  'f'
#define TS_GET_CAL	_IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
#define TS_SET_CAL	_IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)

static struct input_handler tsdev_handler;

static struct tsdev *tsdev_table[TSDEV_MINORS/2];

static int tsdev_fasync(int fd, struct file *file, int on)
{
	struct tsdev_list *list = file->private_data;
	int retval;

	retval = fasync_helper(fd, file, on, &list->fasync);
	return retval < 0 ? retval : 0;
}

static int tsdev_open(struct inode *inode, struct file *file)
{
	int i = iminor(inode) - TSDEV_MINOR_BASE;
	struct tsdev_list *list;

	if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
		return -ENODEV;

	if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
		return -ENOMEM;
	memset(list, 0, sizeof(struct tsdev_list));

	list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0;

	i &= TSDEV_MINOR_MASK;
	list->tsdev = tsdev_table[i];
	list_add_tail(&list->node, &tsdev_table[i]->list);
	file->private_data = list;

	if (!list->tsdev->open++)
		if (list->tsdev->exist)
			input_open_device(&list->tsdev->handle);
	return 0;
}

static void tsdev_free(struct tsdev *tsdev)
{
	tsdev_table[tsdev->minor] = NULL;
	kfree(tsdev);
}

static int tsdev_release(struct inode *inode, struct file *file)
{
	struct tsdev_list *list = file->private_data;

	tsdev_fasync(-1, file, 0);
	list_del(&list->node);

	if (!--list->tsdev->open) {
		if (list->tsdev->exist)
			input_close_device(&list->tsdev->handle);
		else
			tsdev_free(list->tsdev);
	}
	kfree(list);
	return 0;
}

static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count,
			  loff_t * ppos)
{
	struct tsdev_list *list = file->private_data;
	int retval = 0;

	if (list->head == list->tail && list->tsdev->exist && (file->f_flags & O_NONBLOCK))
		return -EAGAIN;

	retval = wait_event_interruptible(list->tsdev->wait,
			list->head != list->tail || !list->tsdev->exist);

	if (retval)
		return retval;

	if (!list->tsdev->exist)
		return -ENODEV;

	while (list->head != list->tail &&
	       retval + sizeof (struct ts_event) <= count) {
		if (copy_to_user (buffer + retval, list->event + list->tail,
				  sizeof (struct ts_event)))
			return -EFAULT;
		list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
		retval += sizeof (struct ts_event);
	}

	return retval;
}

/* No kernel lock - fine */
static unsigned int tsdev_poll(struct file *file, poll_table * wait)
{
	struct tsdev_list *list = file->private_data;
	poll_wait(file, &list->tsdev->wait, wait);
	return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) |
		(list->tsdev->exist ? 0 : (POLLHUP | POLLERR));
}

static int tsdev_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	struct tsdev_list *list = file->private_data;
	struct tsdev *tsdev = list->tsdev;
	int retval = 0;

	switch (cmd) {
	case TS_GET_CAL:
		if (copy_to_user ((void __user *)arg, &tsdev->cal,
				  sizeof (struct ts_calibration)))
			retval = -EFAULT;
		break;
	case TS_SET_CAL:
		if (copy_from_user (&tsdev->cal, (void __user *)arg,
				    sizeof (struct ts_calibration)))
			retval = -EFAULT;
		break;
	default:
		retval = -EINVAL;
		break;
	}

	return retval;
}

static struct file_operations tsdev_fops = {
	.owner =	THIS_MODULE,
	.open =		tsdev_open,
	.release =	tsdev_release,
	.read =		tsdev_read,
	.poll =		tsdev_poll,
	.fasync =	tsdev_fasync,
	.ioctl =	tsdev_ioctl,
};

static void tsdev_event(struct input_handle *handle, unsigned int type,
			unsigned int code, int value)
{
	struct tsdev *tsdev = handle->private;
	struct tsdev_list *list;
	struct timeval time;

	switch (type) {
	case EV_ABS:
		switch (code) {
		case ABS_X:
			tsdev->x = value;
			break;
		case ABS_Y:
			tsdev->y = value;
			break;
		case ABS_PRESSURE:
			if (value > handle->dev->absmax[ABS_PRESSURE])
				value = handle->dev->absmax[ABS_PRESSURE];
			value -= handle->dev->absmin[ABS_PRESSURE];
			if (value < 0)
				value = 0;
			tsdev->pressure = value;
			break;
		}
		break;

	case EV_REL:
		switch (code) {
		case REL_X:
			tsdev->x += value;
			if (tsdev->x < 0)
				tsdev->x = 0;
			else if (tsdev->x > xres)
				tsdev->x = xres;
			break;
		case REL_Y:
			tsdev->y += value;
			if (tsdev->y < 0)
				tsdev->y = 0;
			else if (tsdev->y > yres)
				tsdev->y = yres;
			break;
		}
		break;

	case EV_KEY:
		if (code == BTN_TOUCH || code == BTN_MOUSE) {
			switch (value) {
			case 0:
				tsdev->pressure = 0;
				break;
			case 1:
				if (!tsdev->pressure)
					tsdev->pressure = 1;
				break;
			}
		}
		break;
	}

	if (type != EV_SYN || code != SYN_REPORT)
		return;

	list_for_each_entry(list, &tsdev->list, node) {
		int x, y, tmp;

		do_gettimeofday(&time);
		list->event[list->head].millisecs = time.tv_usec / 100;
		list->event[list->head].pressure = tsdev->pressure;

		x = tsdev->x;
		y = tsdev->y;

		/* Calibration */
		if (!list->raw) {
			x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans;
			y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans;
			if (tsdev->cal.xyswap) {
				tmp = x; x = y; y = tmp;
			}
		}

		list->event[list->head].x = x;
		list->event[list->head].y = y;
		list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
		kill_fasync(&list->fasync, SIGIO, POLL_IN);
	}
	wake_up_interruptible(&tsdev->wait);
}

static struct input_handle *tsdev_connect(struct input_handler *handler,
					  struct input_dev *dev,
					  struct input_device_id *id)
{
	struct tsdev *tsdev;
	int minor, delta;

	for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
	     minor++);
	if (minor >= TSDEV_MINORS/2) {
		printk(KERN_ERR
		       "tsdev: You have way too many touchscreens\n");
		return NULL;
	}

	if (!(tsdev = kmalloc(sizeof(struct tsdev), GFP_KERNEL)))
		return NULL;
	memset(tsdev, 0, sizeof(struct tsdev));

	INIT_LIST_HEAD(&tsdev->list);
	init_waitqueue_head(&tsdev->wait);

	sprintf(tsdev->name, "ts%d", minor);

	tsdev->exist = 1;
	tsdev->minor = minor;
	tsdev->handle.dev = dev;
	tsdev->handle.name = tsdev->name;
	tsdev->handle.handler = handler;
	tsdev->handle.private = tsdev;

	/* Precompute the rough calibration matrix */
	delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
	if (delta == 0)
		delta = 1;
	tsdev->cal.xscale = (xres << 8) / delta;
	tsdev->cal.xtrans = - ((dev->absmin [ABS_X] * tsdev->cal.xscale) >> 8);

	delta = dev->absmax [ABS_Y] - dev->absmin [ABS_Y] + 1;
	if (delta == 0)
		delta = 1;
	tsdev->cal.yscale = (yres << 8) / delta;
	tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);

	tsdev_table[minor] = tsdev;

	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
	class_device_create(input_class,
			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
			dev->dev, "ts%d", minor);

	return &tsdev->handle;
}

static void tsdev_disconnect(struct input_handle *handle)
{
	struct tsdev *tsdev = handle->private;
	struct tsdev_list *list;

	class_device_destroy(input_class,
			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
	devfs_remove("input/ts%d", tsdev->minor);
	devfs_remove("input/tsraw%d", tsdev->minor);
	tsdev->exist = 0;

	if (tsdev->open) {
		input_close_device(handle);
		wake_up_interruptible(&tsdev->wait);
		list_for_each_entry(list, &tsdev->list, node)
			kill_fasync(&list->fasync, SIGIO, POLL_HUP);
	} else
		tsdev_free(tsdev);
}

static struct input_device_id tsdev_ids[] = {
	{
	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
	      .evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
	      .keybit	= { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
	      .relbit	= { BIT(REL_X) | BIT(REL_Y) },
	 },/* A mouse like device, at least one button, two relative axes */

	{
	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
	      .evbit	= { BIT(EV_KEY) | BIT(EV_ABS) },
	      .keybit	= { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) },
	 },/* A tablet like device, at least touch detection, two absolute axes */

	{
	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
	      .evbit	= { BIT(EV_ABS) },
	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
	 },/* A tablet like device with several gradations of pressure */

	{},/* Terminating entry */
};

MODULE_DEVICE_TABLE(input, tsdev_ids);

static struct input_handler tsdev_handler = {
	.event =	tsdev_event,
	.connect =	tsdev_connect,
	.disconnect =	tsdev_disconnect,
	.fops =		&tsdev_fops,
	.minor =	TSDEV_MINOR_BASE,
	.name =		"tsdev",
	.id_table =	tsdev_ids,
};

static int __init tsdev_init(void)
{
	input_register_handler(&tsdev_handler);
	printk(KERN_INFO "ts: Compaq touchscreen protocol output\n");
	return 0;
}

static void __exit tsdev_exit(void)
{
	input_unregister_handler(&tsdev_handler);
}

module_init(tsdev_init);
module_exit(tsdev_exit);
