/*
 * linux/drivers/input/serio/pcips2.c
 *
 *  Copyright (C) 2003 Russell King, All Rights Reserved.
 *
 * 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.
 *
 *  I'm not sure if this is a generic PS/2 PCI interface or specific to
 *  the Mobility Electronics docking station.
 */
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <asm/io.h>

#define PS2_CTRL		(0)
#define PS2_STATUS		(1)
#define PS2_DATA		(2)

#define PS2_CTRL_CLK		(1<<0)
#define PS2_CTRL_DAT		(1<<1)
#define PS2_CTRL_TXIRQ		(1<<2)
#define PS2_CTRL_ENABLE		(1<<3)
#define PS2_CTRL_RXIRQ		(1<<4)

#define PS2_STAT_CLK		(1<<0)
#define PS2_STAT_DAT		(1<<1)
#define PS2_STAT_PARITY		(1<<2)
#define PS2_STAT_RXFULL		(1<<5)
#define PS2_STAT_TXBUSY		(1<<6)
#define PS2_STAT_TXEMPTY	(1<<7)

struct pcips2_data {
	struct serio	*io;
	unsigned int	base;
	struct pci_dev	*dev;
};

static int pcips2_write(struct serio *io, unsigned char val)
{
	struct pcips2_data *ps2if = io->port_data;
	unsigned int stat;

	do {
		stat = inb(ps2if->base + PS2_STATUS);
		cpu_relax();
	} while (!(stat & PS2_STAT_TXEMPTY));

	outb(val, ps2if->base + PS2_DATA);

	return 0;
}

static irqreturn_t pcips2_interrupt(int irq, void *devid)
{
	struct pcips2_data *ps2if = devid;
	unsigned char status, scancode;
	int handled = 0;

	do {
		unsigned int flag;

		status = inb(ps2if->base + PS2_STATUS);
		if (!(status & PS2_STAT_RXFULL))
			break;
		handled = 1;
		scancode = inb(ps2if->base + PS2_DATA);
		if (status == 0xff && scancode == 0xff)
			break;

		flag = (status & PS2_STAT_PARITY) ? 0 : SERIO_PARITY;

		if (hweight8(scancode) & 1)
			flag ^= SERIO_PARITY;

		serio_interrupt(ps2if->io, scancode, flag);
	} while (1);
	return IRQ_RETVAL(handled);
}

static void pcips2_flush_input(struct pcips2_data *ps2if)
{
	unsigned char status, scancode;

	do {
		status = inb(ps2if->base + PS2_STATUS);
		if (!(status & PS2_STAT_RXFULL))
			break;
		scancode = inb(ps2if->base + PS2_DATA);
		if (status == 0xff && scancode == 0xff)
			break;
	} while (1);
}

static int pcips2_open(struct serio *io)
{
	struct pcips2_data *ps2if = io->port_data;
	int ret, val = 0;

	outb(PS2_CTRL_ENABLE, ps2if->base);
	pcips2_flush_input(ps2if);

	ret = request_irq(ps2if->dev->irq, pcips2_interrupt, IRQF_SHARED,
			  "pcips2", ps2if);
	if (ret == 0)
		val = PS2_CTRL_ENABLE | PS2_CTRL_RXIRQ;

	outb(val, ps2if->base);

	return ret;
}

static void pcips2_close(struct serio *io)
{
	struct pcips2_data *ps2if = io->port_data;

	outb(0, ps2if->base);

	free_irq(ps2if->dev->irq, ps2if);
}

static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct pcips2_data *ps2if;
	struct serio *serio;
	int ret;

	ret = pci_enable_device(dev);
	if (ret)
		goto out;

	ret = pci_request_regions(dev, "pcips2");
	if (ret)
		goto disable;

	ps2if = kzalloc(sizeof(struct pcips2_data), GFP_KERNEL);
	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!ps2if || !serio) {
		ret = -ENOMEM;
		goto release;
	}


	serio->id.type		= SERIO_8042;
	serio->write		= pcips2_write;
	serio->open		= pcips2_open;
	serio->close		= pcips2_close;
	strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
	serio->port_data	= ps2if;
	serio->dev.parent	= &dev->dev;
	ps2if->io		= serio;
	ps2if->dev		= dev;
	ps2if->base		= pci_resource_start(dev, 0);

	pci_set_drvdata(dev, ps2if);

	serio_register_port(ps2if->io);
	return 0;

 release:
	kfree(ps2if);
	kfree(serio);
	pci_release_regions(dev);
 disable:
	pci_disable_device(dev);
 out:
	return ret;
}

static void __devexit pcips2_remove(struct pci_dev *dev)
{
	struct pcips2_data *ps2if = pci_get_drvdata(dev);

	serio_unregister_port(ps2if->io);
	pci_set_drvdata(dev, NULL);
	kfree(ps2if);
	pci_release_regions(dev);
	pci_disable_device(dev);
}

static struct pci_device_id pcips2_ids[] = {
	{
		.vendor		= 0x14f2,	/* MOBILITY */
		.device		= 0x0123,	/* Keyboard */
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.class		= PCI_CLASS_INPUT_KEYBOARD << 8,
		.class_mask	= 0xffff00,
	},
	{
		.vendor		= 0x14f2,	/* MOBILITY */
		.device		= 0x0124,	/* Mouse */
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.class		= PCI_CLASS_INPUT_MOUSE << 8,
		.class_mask	= 0xffff00,
	},
	{ 0, }
};

static struct pci_driver pcips2_driver = {
	.name			= "pcips2",
	.id_table		= pcips2_ids,
	.probe			= pcips2_probe,
	.remove			= __devexit_p(pcips2_remove),
};

static int __init pcips2_init(void)
{
	return pci_register_driver(&pcips2_driver);
}

static void __exit pcips2_exit(void)
{
	pci_unregister_driver(&pcips2_driver);
}

module_init(pcips2_init);
module_exit(pcips2_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("PCI PS/2 keyboard/mouse driver");
MODULE_DEVICE_TABLE(pci, pcips2_ids);
