/*
 * Generic linux-input device driver for axis-bearing devices
 *
 * Copyright (c) 2001 Brian S. Julin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL").
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *
 * References:
 * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
 *
 */

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

#define PREFIX "HIL PTR: "
#define HIL_GENERIC_NAME "HIL pointer device"

MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
MODULE_LICENSE("Dual BSD/GPL");


#define TABLET_SIMULATES_MOUSE	/* allow tablet to be used as mouse */
#undef  TABLET_AUTOADJUST	/* auto-adjust valid tablet ranges */


#define HIL_PTR_MAX_LENGTH 16

struct hil_ptr {
	struct input_dev *dev;
	struct serio *serio;

	/* Input buffer and index for packets from HIL bus. */
	hil_packet data[HIL_PTR_MAX_LENGTH];
	int idx4; /* four counts per packet */

	/* Raw device info records from HIL bus, see hil.h for fields. */
	char	idd[HIL_PTR_MAX_LENGTH];	/* DID byte and IDD record */
	char	rsc[HIL_PTR_MAX_LENGTH];	/* RSC record */
	char	exd[HIL_PTR_MAX_LENGTH];	/* EXD record */
	char	rnm[HIL_PTR_MAX_LENGTH + 1];	/* RNM record + NULL term. */

	/* Extra device details not contained in struct input_dev. */
	unsigned int nbtn, naxes;
	unsigned int btnmap[7];

	/* Something to sleep around with. */
	struct semaphore sem;
};

/* Process a complete packet after transfer from the HIL */
static void hil_ptr_process_record(struct hil_ptr *ptr)
{
	struct input_dev *dev = ptr->dev;
	hil_packet *data = ptr->data;
	hil_packet p;
	int idx, i, cnt, laxis;
	int ax16, absdev;

	idx = ptr->idx4/4;
	p = data[idx - 1];

	if ((p & ~HIL_CMDCT_POL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
		goto report;
	if ((p & ~HIL_CMDCT_RPL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
		goto report;

	/* Not a poll response.  See if we are loading config records. */
	switch (p & HIL_PKT_DATA_MASK) {
	case HIL_CMD_IDD:
		for (i = 0; i < idx; i++)
			ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->idd[i] = 0;
		break;

	case HIL_CMD_RSC:
		for (i = 0; i < idx; i++)
			ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->rsc[i] = 0;
		break;

	case HIL_CMD_EXD:
		for (i = 0; i < idx; i++)
			ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->exd[i] = 0;
		break;

	case HIL_CMD_RNM:
		for (i = 0; i < idx; i++)
			ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
			ptr->rnm[i] = 0;
		break;

	default:
		/* These occur when device isn't present */
		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
			break;
		/* Anything else we'd like to know about. */
		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
		break;
	}
	goto out;

 report:
	if ((p & HIL_CMDCT_POL) != idx - 1) {
		printk(KERN_WARNING PREFIX
			"Malformed poll packet %x (idx = %i)\n", p, idx);
		goto out;
	}

	i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0;
	laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK;
	laxis += i;

	ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
	absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;

	for (cnt = 1; i < laxis; i++) {
		unsigned int lo,hi,val;
		lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
		hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
		if (absdev) {
			val = lo + (hi<<8);
#ifdef TABLET_AUTOADJUST
			if (val < dev->absmin[ABS_X + i])
				dev->absmin[ABS_X + i] = val;
			if (val > dev->absmax[ABS_X + i])
				dev->absmax[ABS_X + i] = val;
#endif
			if (i%3) val = dev->absmax[ABS_X + i] - val;
			input_report_abs(dev, ABS_X + i, val);
		} else {
			val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
			if (i%3)
				val *= -1;
			input_report_rel(dev, REL_X + i, val);
		}
	}

	while (cnt < idx - 1) {
		unsigned int btn;
		int up;
		btn = ptr->data[cnt++];
		up = btn & 1;
		btn &= 0xfe;
		if (btn == 0x8e)
			continue; /* TODO: proximity == touch? */
		else
			if ((btn > 0x8c) || (btn < 0x80))
				continue;
		btn = (btn - 0x80) >> 1;
		btn = ptr->btnmap[btn];
		input_report_key(dev, btn, !up);
	}
	input_sync(dev);
 out:
	ptr->idx4 = 0;
	up(&ptr->sem);
}

static void hil_ptr_process_err(struct hil_ptr *ptr)
{
	printk(KERN_WARNING PREFIX "errored HIL packet\n");
	ptr->idx4 = 0;
	up(&ptr->sem);
}

static irqreturn_t hil_ptr_interrupt(struct serio *serio,
        unsigned char data, unsigned int flags)
{
	struct hil_ptr *ptr;
	hil_packet packet;
	int idx;

	ptr = serio_get_drvdata(serio);
	BUG_ON(ptr == NULL);

	if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
		hil_ptr_process_err(ptr);
		return IRQ_HANDLED;
	}
	idx = ptr->idx4/4;
	if (!(ptr->idx4 % 4))
		ptr->data[idx] = 0;
	packet = ptr->data[idx];
	packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
	ptr->data[idx] = packet;

	/* Records of N 4-byte hil_packets must terminate with a command. */
	if ((++(ptr->idx4)) % 4)
		return IRQ_HANDLED;
	if ((packet & 0xffff0000) != HIL_ERR_INT) {
		hil_ptr_process_err(ptr);
		return IRQ_HANDLED;
	}
	if (packet & HIL_PKT_CMD)
		hil_ptr_process_record(ptr);

	return IRQ_HANDLED;
}

static void hil_ptr_disconnect(struct serio *serio)
{
	struct hil_ptr *ptr;

	ptr = serio_get_drvdata(serio);
	BUG_ON(ptr == NULL);

	serio_close(serio);
	input_unregister_device(ptr->dev);
	kfree(ptr);
}

static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
{
	struct hil_ptr	*ptr;
	const char	*txt;
	unsigned int	i, naxsets, btntype;
	uint8_t		did, *idd;
	int		error;

	ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ptr->dev = input_allocate_device();
	if (!ptr->dev) {
		error = -ENOMEM;
		goto bail0;
	}

	error = serio_open(serio, driver);
	if (error)
		goto bail1;

	serio_set_drvdata(serio, ptr);
	ptr->serio = serio;

	init_MUTEX_LOCKED(&ptr->sem);

	/* Get device info.  MLC driver supplies devid/status/etc. */
	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_IDD);
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RSC);
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RNM);
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EXD);
	down(&ptr->sem);

	up(&ptr->sem);

	did = ptr->idd[0];
	idd = ptr->idd + 1;
	txt = "unknown";

	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
		ptr->dev->evbit[0] = BIT_MASK(EV_REL);
		txt = "relative";
	}

	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
		ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
		txt = "absolute";
	}

	if (!ptr->dev->evbit[0]) {
		error = -ENODEV;
		goto bail2;
	}

	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
	if (ptr->nbtn)
		ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);

	naxsets = HIL_IDD_NUM_AXSETS(*idd);
	ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);

	printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n",
			did, txt);
	printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
			ptr->nbtn, naxsets, ptr->naxes);

	btntype = BTN_MISC;
	if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
#ifdef TABLET_SIMULATES_MOUSE
		btntype = BTN_TOUCH;
#else
		btntype = BTN_DIGI;
#endif
	if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
		btntype = BTN_TOUCH;

	if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
		btntype = BTN_MOUSE;

	for (i = 0; i < ptr->nbtn; i++) {
		set_bit(btntype | i, ptr->dev->keybit);
		ptr->btnmap[i] = btntype | i;
	}

	if (btntype == BTN_MOUSE) {
		/* Swap buttons 2 and 3 */
		ptr->btnmap[1] = BTN_MIDDLE;
		ptr->btnmap[2] = BTN_RIGHT;
	}

	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
		for (i = 0; i < ptr->naxes; i++)
			set_bit(REL_X + i, ptr->dev->relbit);
		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
			set_bit(REL_X + i, ptr->dev->relbit);
	} else {
		for (i = 0; i < ptr->naxes; i++) {
			set_bit(ABS_X + i, ptr->dev->absbit);
			ptr->dev->absmin[ABS_X + i] = 0;
			ptr->dev->absmax[ABS_X + i] =
				HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
		}
		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
			set_bit(ABS_X + i, ptr->dev->absbit);
			ptr->dev->absmin[ABS_X + i] = 0;
			ptr->dev->absmax[ABS_X + i] =
				HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
		}
#ifdef TABLET_AUTOADJUST
		for (i = 0; i < ABS_MAX; i++) {
			int diff = ptr->dev->absmax[ABS_X + i] / 10;
			ptr->dev->absmin[ABS_X + i] += diff;
			ptr->dev->absmax[ABS_X + i] -= diff;
		}
#endif
	}

	ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;

	ptr->dev->id.bustype	= BUS_HIL;
	ptr->dev->id.vendor	= PCI_VENDOR_ID_HP;
	ptr->dev->id.product	= 0x0001; /* TODO: get from ptr->rsc */
	ptr->dev->id.version	= 0x0100; /* TODO: get from ptr->rsc */
	ptr->dev->dev.parent	= &serio->dev;

	error = input_register_device(ptr->dev);
	if (error) {
		printk(KERN_INFO PREFIX "Unable to register input device\n");
		goto bail2;
	}

	printk(KERN_INFO "input: %s (%s), ID: %d\n",
		ptr->dev->name,
		(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
		did);

	return 0;

 bail2:
	serio_close(serio);
 bail1:
	input_free_device(ptr->dev);
 bail0:
	kfree(ptr);
	serio_set_drvdata(serio, NULL);
	return error;
}

static struct serio_device_id hil_ptr_ids[] = {
	{
		.type = SERIO_HIL_MLC,
		.proto = SERIO_HIL,
		.id = SERIO_ANY,
		.extra = SERIO_ANY,
	},
	{ 0 }
};

static struct serio_driver hil_ptr_serio_driver = {
	.driver		= {
		.name	= "hil_ptr",
	},
	.description	= "HP HIL mouse/tablet driver",
	.id_table	= hil_ptr_ids,
	.connect	= hil_ptr_connect,
	.disconnect	= hil_ptr_disconnect,
	.interrupt	= hil_ptr_interrupt
};

static int __init hil_ptr_init(void)
{
	return serio_register_driver(&hil_ptr_serio_driver);
}

static void __exit hil_ptr_exit(void)
{
	serio_unregister_driver(&hil_ptr_serio_driver);
}

module_init(hil_ptr_init);
module_exit(hil_ptr_exit);
