/*
 * $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/smp_lock.h>
#include <linux/random.h>
#include <linux/time.h>
#include <linux/device.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 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 = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
		return -ENOMEM;

	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 const 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,
					  const struct input_device_id *id)
{
	struct tsdev *tsdev;
	struct class_device *cdev;
	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 = kzalloc(sizeof(struct tsdev), GFP_KERNEL)))
		return NULL;

	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;

	cdev = class_device_create(&input_class, &dev->cdev,
			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
			dev->cdev.dev, tsdev->name);

	/* temporary symlink to keep userspace happy */
	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
			  tsdev->name);

	return &tsdev->handle;
}

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

	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
	class_device_destroy(&input_class,
			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + 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 const 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)
{
	return input_register_handler(&tsdev_handler);
}

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

module_init(tsdev_init);
module_exit(tsdev_exit);
