/******************************************************************************
 * itmtouch.c  --  Driver for ITM touchscreen panel
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Based upon original work by Chris Collins <xfire-itmtouch@xware.cx>.
 *
 * Kudos to ITM for providing me with the datasheet for the panel,
 * even though it was a day later than I had finished writing this
 * driver.
 *
 * It has meant that I've been able to correct my interpretation of the
 * protocol packets however.
 *
 * CC -- 2003/9/29
 *
 * History
 * 1.0 & 1.1  2003 (CC) vojtech@suse.cz
 *   Original version for 2.4.x kernels
 *
 * 1.2  02/03/2005 (HCE) hc@mivu.no
 *   Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints.
 *   Unfortunately no calibration support at this time.
 *
 * 1.2.1  09/03/2005 (HCE) hc@mivu.no
 *   Code cleanup and adjusting syntax to start matching kernel standards
 *
 *****************************************************************************/

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

/* only an 8 byte buffer necessary for a single packet */
#define ITM_BUFSIZE			8
#define PATH_SIZE			64

#define USB_VENDOR_ID_ITMINC		0x0403
#define USB_PRODUCT_ID_TOUCHPANEL	0xf9e9

#define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>"
#define DRIVER_VERSION "v1.2.1"
#define DRIVER_DESC "USB ITM Inc Touch Panel Driver"
#define DRIVER_LICENSE "GPL"

MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE( DRIVER_LICENSE );

struct itmtouch_dev {
	struct usb_device	*usbdev; /* usb device */
	struct input_dev	*inputdev; /* input device */
	struct urb		*readurb; /* urb */
	char			rbuf[ITM_BUFSIZE]; /* data */
	int			users;
	char name[128];
	char phys[64];
};

static struct usb_device_id itmtouch_ids [] = {
	{ USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) },
	{ }
};

static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
{
	struct itmtouch_dev *itmtouch = urb->context;
	unsigned char *data = urb->transfer_buffer;
	struct input_dev *dev = itmtouch->inputdev;
	int retval;

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ETIME:
		/* this urb is timing out */
		dbg("%s - urb timed out - was the device unplugged?",
		    __FUNCTION__);
		return;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d",
		    __FUNCTION__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d",
		    __FUNCTION__, urb->status);
		goto exit;
	}

	input_regs(dev, regs);

	/* if pressure has been released, then don't report X/Y */
	if (data[7] & 0x20) {
		input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F));
		input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F));
	}

	input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F));
	input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20);
	input_sync(dev);

exit:
	retval = usb_submit_urb (urb, GFP_ATOMIC);
	if (retval)
		printk(KERN_ERR "%s - usb_submit_urb failed with result: %d",
				__FUNCTION__, retval);
}

static int itmtouch_open(struct input_dev *input)
{
	struct itmtouch_dev *itmtouch = input->private;

	itmtouch->readurb->dev = itmtouch->usbdev;

	if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL))
		return -EIO;

	return 0;
}

static void itmtouch_close(struct input_dev *input)
{
	struct itmtouch_dev *itmtouch = input->private;

	usb_kill_urb(itmtouch->readurb);
}

static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct itmtouch_dev *itmtouch;
	struct input_dev *input_dev;
	struct usb_host_interface *interface;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_device *udev = interface_to_usbdev(intf);
	unsigned int pipe;
	unsigned int maxp;

	interface = intf->cur_altsetting;
	endpoint = &interface->endpoint[0].desc;

	itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!itmtouch || !input_dev) {
		err("%s - Out of memory.", __FUNCTION__);
		goto fail;
	}

	itmtouch->usbdev = udev;
	itmtouch->inputdev = input_dev;

	if (udev->manufacturer)
		strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));

	if (udev->product) {
		if (udev->manufacturer)
			strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
		strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
	}

	if (!strlen(itmtouch->name))
		sprintf(itmtouch->name, "USB ITM touchscreen");

	usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
	strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));

	input_dev->name = itmtouch->name;
	input_dev->phys = itmtouch->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->cdev.dev = &intf->dev;
	input_dev->private = itmtouch;

	input_dev->open = itmtouch_open;
	input_dev->close = itmtouch_close;

	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);

	/* device limits */
	/* as specified by the ITM datasheet, X and Y are 12bit,
	 * Z (pressure) is 8 bit. However, the fields are defined up
	 * to 14 bits for future possible expansion.
	 */
	input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);

	/* initialise the URB so we can read from the transport stream */
	pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));

	if (maxp > ITM_BUFSIZE)
		maxp = ITM_BUFSIZE;

	itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!itmtouch->readurb) {
		dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
		goto fail;
	}

	usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
			 maxp, itmtouch_irq, itmtouch, endpoint->bInterval);

	input_register_device(itmtouch->inputdev);

	usb_set_intfdata(intf, itmtouch);

	return 0;

 fail:	input_free_device(input_dev);
	kfree(itmtouch);
	return -ENOMEM;
}

static void itmtouch_disconnect(struct usb_interface *intf)
{
	struct itmtouch_dev *itmtouch = usb_get_intfdata(intf);

	usb_set_intfdata(intf, NULL);

	if (itmtouch) {
		input_unregister_device(itmtouch->inputdev);
		usb_kill_urb(itmtouch->readurb);
		usb_free_urb(itmtouch->readurb);
		kfree(itmtouch);
	}
}

MODULE_DEVICE_TABLE(usb, itmtouch_ids);

static struct usb_driver itmtouch_driver = {
	.name =         "itmtouch",
	.probe =        itmtouch_probe,
	.disconnect =   itmtouch_disconnect,
	.id_table =     itmtouch_ids,
};

static int __init itmtouch_init(void)
{
	info(DRIVER_DESC " " DRIVER_VERSION);
	info(DRIVER_AUTHOR);
	return usb_register(&itmtouch_driver);
}

static void __exit itmtouch_exit(void)
{
	usb_deregister(&itmtouch_driver);
}

module_init(itmtouch_init);
module_exit(itmtouch_exit);
