/*
 * $Id: pc110pad.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
 *
 *  Copyright (c) 2000-2001 Vojtech Pavlik
 *
 *  Based on the work of:
 *	Alan Cox	Robin O'Leary
 */

/*
 * IBM PC110 touchpad driver for Linux
 */

/*
 * 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 <vojtech@ucw.cz>, or by paper mail:
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>

#include <asm/io.h>
#include <asm/irq.h>

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("IBM PC110 touchpad driver");
MODULE_LICENSE("GPL");

#define PC110PAD_OFF	0x30
#define PC110PAD_ON	0x38

static int pc110pad_irq = 10;
static int pc110pad_io = 0x15e0;

static struct input_dev *pc110pad_dev;
static int pc110pad_data[3];
static int pc110pad_count;

static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
{
	int value     = inb_p(pc110pad_io);
	int handshake = inb_p(pc110pad_io + 2);

	outb_p(handshake |  1, pc110pad_io + 2);
	outb_p(handshake & ~1, pc110pad_io + 2);
	inb_p(0x64);

	pc110pad_data[pc110pad_count++] = value;

	if (pc110pad_count < 3)
		return IRQ_HANDLED;

	input_regs(pc110pad_dev, regs);
	input_report_key(pc110pad_dev, BTN_TOUCH,
		pc110pad_data[0] & 0x01);
	input_report_abs(pc110pad_dev, ABS_X,
		pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100));
	input_report_abs(pc110pad_dev, ABS_Y,
		pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80));
	input_sync(pc110pad_dev);

	pc110pad_count = 0;
	return IRQ_HANDLED;
}

static void pc110pad_close(struct input_dev *dev)
{
	outb(PC110PAD_OFF, pc110pad_io + 2);
}

static int pc110pad_open(struct input_dev *dev)
{
	pc110pad_interrupt(0, NULL, NULL);
	pc110pad_interrupt(0, NULL, NULL);
	pc110pad_interrupt(0, NULL, NULL);
	outb(PC110PAD_ON, pc110pad_io + 2);
	pc110pad_count = 0;

	return 0;
}

/*
 * We try to avoid enabling the hardware if it's not
 * there, but we don't know how to test. But we do know
 * that the PC110 is not a PCI system. So if we find any
 * PCI devices in the machine, we don't have a PC110.
 */
static int __init pc110pad_init(void)
{
	struct pci_dev *dev;

	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
	if (dev) {
		pci_dev_put(dev);
		return -ENOENT;
	}

	if (!request_region(pc110pad_io, 4, "pc110pad")) {
		printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n",
				pc110pad_io, pc110pad_io + 4);
		return -EBUSY;
	}

	outb(PC110PAD_OFF, pc110pad_io + 2);

	if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) {
		release_region(pc110pad_io, 4);
		printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq);
		return -EBUSY;
	}

	if (!(pc110pad_dev = input_allocate_device())) {
		free_irq(pc110pad_irq, NULL);
		release_region(pc110pad_io, 4);
		printk(KERN_ERR "pc110pad: Not enough memory.\n");
		return -ENOMEM;
	}

	pc110pad_dev->name = "IBM PC110 TouchPad";
	pc110pad_dev->phys = "isa15e0/input0";
	pc110pad_dev->id.bustype = BUS_ISA;
	pc110pad_dev->id.vendor = 0x0003;
	pc110pad_dev->id.product = 0x0001;
	pc110pad_dev->id.version = 0x0100;

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

	pc110pad_dev->absmax[ABS_X] = 0x1ff;
	pc110pad_dev->absmax[ABS_Y] = 0x0ff;

	pc110pad_dev->open = pc110pad_open;
	pc110pad_dev->close = pc110pad_close;

	input_register_device(pc110pad_dev);

	return 0;
}

static void __exit pc110pad_exit(void)
{
	outb(PC110PAD_OFF, pc110pad_io + 2);
	free_irq(pc110pad_irq, NULL);
	input_unregister_device(pc110pad_dev);
	release_region(pc110pad_io, 4);
}

module_init(pc110pad_init);
module_exit(pc110pad_exit);
