/*
 *  Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
 *
 *  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.
 *
 *  You need a userspace library to cooperate with this driver. It (and other
 *  info) may be obtained here:
 *  http://www.fi.muni.cz/~xslaby/phantom.html
 *  or alternatively, you might use OpenHaptics provided by Sensable.
 */

#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/phantom.h>
#include <linux/smp_lock.h>

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

#define PHANTOM_VERSION		"n0.9.8"

#define PHANTOM_MAX_MINORS	8

#define PHN_IRQCTL		0x4c    /* irq control in caddr space */

#define PHB_RUNNING		1
#define PHB_NOT_OH		2

static struct class *phantom_class;
static int phantom_major;

struct phantom_device {
	unsigned int opened;
	void __iomem *caddr;
	u32 __iomem *iaddr;
	u32 __iomem *oaddr;
	unsigned long status;
	atomic_t counter;

	wait_queue_head_t wait;
	struct cdev cdev;

	struct mutex open_lock;
	spinlock_t regs_lock;

	/* used in NOT_OH mode */
	struct phm_regs oregs;
	u32 ctl_reg;
};

static unsigned char phantom_devices[PHANTOM_MAX_MINORS];

static int phantom_status(struct phantom_device *dev, unsigned long newstat)
{
	pr_debug("phantom_status %lx %lx\n", dev->status, newstat);

	if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
		atomic_set(&dev->counter, 0);
		iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
		iowrite32(0x43, dev->caddr + PHN_IRQCTL);
		ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
	} else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) {
		iowrite32(0, dev->caddr + PHN_IRQCTL);
		ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
	}

	dev->status = newstat;

	return 0;
}

/*
 * File ops
 */

static long phantom_ioctl(struct file *file, unsigned int cmd,
		unsigned long arg)
{
	struct phantom_device *dev = file->private_data;
	struct phm_regs rs;
	struct phm_reg r;
	void __user *argp = (void __user *)arg;
	unsigned long flags;
	unsigned int i;

	switch (cmd) {
	case PHN_SETREG:
	case PHN_SET_REG:
		if (copy_from_user(&r, argp, sizeof(r)))
			return -EFAULT;

		if (r.reg > 7)
			return -EINVAL;

		spin_lock_irqsave(&dev->regs_lock, flags);
		if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
				phantom_status(dev, dev->status | PHB_RUNNING)){
			spin_unlock_irqrestore(&dev->regs_lock, flags);
			return -ENODEV;
		}

		pr_debug("phantom: writing %x to %u\n", r.value, r.reg);

		/* preserve amp bit (don't allow to change it when in NOT_OH) */
		if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) {
			r.value &= ~PHN_CTL_AMP;
			r.value |= dev->ctl_reg & PHN_CTL_AMP;
			dev->ctl_reg = r.value;
		}

		iowrite32(r.value, dev->iaddr + r.reg);
		ioread32(dev->iaddr); /* PCI posting */

		if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
			phantom_status(dev, dev->status & ~PHB_RUNNING);
		spin_unlock_irqrestore(&dev->regs_lock, flags);
		break;
	case PHN_SETREGS:
	case PHN_SET_REGS:
		if (copy_from_user(&rs, argp, sizeof(rs)))
			return -EFAULT;

		pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
		spin_lock_irqsave(&dev->regs_lock, flags);
		if (dev->status & PHB_NOT_OH)
			memcpy(&dev->oregs, &rs, sizeof(rs));
		else {
			u32 m = min(rs.count, 8U);
			for (i = 0; i < m; i++)
				if (rs.mask & BIT(i))
					iowrite32(rs.values[i], dev->oaddr + i);
			ioread32(dev->iaddr); /* PCI posting */
		}
		spin_unlock_irqrestore(&dev->regs_lock, flags);
		break;
	case PHN_GETREG:
	case PHN_GET_REG:
		if (copy_from_user(&r, argp, sizeof(r)))
			return -EFAULT;

		if (r.reg > 7)
			return -EINVAL;

		r.value = ioread32(dev->iaddr + r.reg);

		if (copy_to_user(argp, &r, sizeof(r)))
			return -EFAULT;
		break;
	case PHN_GETREGS:
	case PHN_GET_REGS: {
		u32 m;

		if (copy_from_user(&rs, argp, sizeof(rs)))
			return -EFAULT;

		m = min(rs.count, 8U);

		pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
		spin_lock_irqsave(&dev->regs_lock, flags);
		for (i = 0; i < m; i++)
			if (rs.mask & BIT(i))
				rs.values[i] = ioread32(dev->iaddr + i);
		atomic_set(&dev->counter, 0);
		spin_unlock_irqrestore(&dev->regs_lock, flags);

		if (copy_to_user(argp, &rs, sizeof(rs)))
			return -EFAULT;
		break;
	} case PHN_NOT_OH:
		spin_lock_irqsave(&dev->regs_lock, flags);
		if (dev->status & PHB_RUNNING) {
			printk(KERN_ERR "phantom: you need to set NOT_OH "
					"before you start the device!\n");
			spin_unlock_irqrestore(&dev->regs_lock, flags);
			return -EINVAL;
		}
		dev->status |= PHB_NOT_OH;
		spin_unlock_irqrestore(&dev->regs_lock, flags);
		break;
	default:
		return -ENOTTY;
	}

	return 0;
}

#ifdef CONFIG_COMPAT
static long phantom_compat_ioctl(struct file *filp, unsigned int cmd,
		unsigned long arg)
{
	if (_IOC_NR(cmd) <= 3 && _IOC_SIZE(cmd) == sizeof(compat_uptr_t)) {
		cmd &= ~(_IOC_SIZEMASK << _IOC_SIZESHIFT);
		cmd |= sizeof(void *) << _IOC_SIZESHIFT;
	}
	return phantom_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#else
#define phantom_compat_ioctl NULL
#endif

static int phantom_open(struct inode *inode, struct file *file)
{
	struct phantom_device *dev = container_of(inode->i_cdev,
			struct phantom_device, cdev);

	lock_kernel();
	nonseekable_open(inode, file);

	if (mutex_lock_interruptible(&dev->open_lock)) {
		unlock_kernel();
		return -ERESTARTSYS;
	}

	if (dev->opened) {
		mutex_unlock(&dev->open_lock);
		unlock_kernel();
		return -EINVAL;
	}

	WARN_ON(dev->status & PHB_NOT_OH);

	file->private_data = dev;

	atomic_set(&dev->counter, 0);
	dev->opened++;
	mutex_unlock(&dev->open_lock);
	unlock_kernel();
	return 0;
}

static int phantom_release(struct inode *inode, struct file *file)
{
	struct phantom_device *dev = file->private_data;

	mutex_lock(&dev->open_lock);

	dev->opened = 0;
	phantom_status(dev, dev->status & ~PHB_RUNNING);
	dev->status &= ~PHB_NOT_OH;

	mutex_unlock(&dev->open_lock);

	return 0;
}

static unsigned int phantom_poll(struct file *file, poll_table *wait)
{
	struct phantom_device *dev = file->private_data;
	unsigned int mask = 0;

	pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter));
	poll_wait(file, &dev->wait, wait);

	if (!(dev->status & PHB_RUNNING))
		mask = POLLERR;
	else if (atomic_read(&dev->counter))
		mask = POLLIN | POLLRDNORM;

	pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter));

	return mask;
}

static struct file_operations phantom_file_ops = {
	.open = phantom_open,
	.release = phantom_release,
	.unlocked_ioctl = phantom_ioctl,
	.compat_ioctl = phantom_compat_ioctl,
	.poll = phantom_poll,
};

static irqreturn_t phantom_isr(int irq, void *data)
{
	struct phantom_device *dev = data;
	unsigned int i;
	u32 ctl;

	spin_lock(&dev->regs_lock);
	ctl = ioread32(dev->iaddr + PHN_CONTROL);
	if (!(ctl & PHN_CTL_IRQ)) {
		spin_unlock(&dev->regs_lock);
		return IRQ_NONE;
	}

	iowrite32(0, dev->iaddr);
	iowrite32(0xc0, dev->iaddr);

	if (dev->status & PHB_NOT_OH) {
		struct phm_regs *r = &dev->oregs;
		u32 m = min(r->count, 8U);

		for (i = 0; i < m; i++)
			if (r->mask & BIT(i))
				iowrite32(r->values[i], dev->oaddr + i);

		dev->ctl_reg ^= PHN_CTL_AMP;
		iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL);
	}
	spin_unlock(&dev->regs_lock);

	ioread32(dev->iaddr); /* PCI posting */

	atomic_inc(&dev->counter);
	wake_up_interruptible(&dev->wait);

	return IRQ_HANDLED;
}

/*
 * Init and deinit driver
 */

static unsigned int __devinit phantom_get_free(void)
{
	unsigned int i;

	for (i = 0; i < PHANTOM_MAX_MINORS; i++)
		if (phantom_devices[i] == 0)
			break;

	return i;
}

static int __devinit phantom_probe(struct pci_dev *pdev,
	const struct pci_device_id *pci_id)
{
	struct phantom_device *pht;
	unsigned int minor;
	int retval;

	retval = pci_enable_device(pdev);
	if (retval)
		goto err;

	minor = phantom_get_free();
	if (minor == PHANTOM_MAX_MINORS) {
		dev_err(&pdev->dev, "too many devices found!\n");
		retval = -EIO;
		goto err_dis;
	}

	phantom_devices[minor] = 1;

	retval = pci_request_regions(pdev, "phantom");
	if (retval)
		goto err_null;

	retval = -ENOMEM;
	pht = kzalloc(sizeof(*pht), GFP_KERNEL);
	if (pht == NULL) {
		dev_err(&pdev->dev, "unable to allocate device\n");
		goto err_reg;
	}

	pht->caddr = pci_iomap(pdev, 0, 0);
	if (pht->caddr == NULL) {
		dev_err(&pdev->dev, "can't remap conf space\n");
		goto err_fr;
	}
	pht->iaddr = pci_iomap(pdev, 2, 0);
	if (pht->iaddr == NULL) {
		dev_err(&pdev->dev, "can't remap input space\n");
		goto err_unmc;
	}
	pht->oaddr = pci_iomap(pdev, 3, 0);
	if (pht->oaddr == NULL) {
		dev_err(&pdev->dev, "can't remap output space\n");
		goto err_unmi;
	}

	mutex_init(&pht->open_lock);
	spin_lock_init(&pht->regs_lock);
	init_waitqueue_head(&pht->wait);
	cdev_init(&pht->cdev, &phantom_file_ops);
	pht->cdev.owner = THIS_MODULE;

	iowrite32(0, pht->caddr + PHN_IRQCTL);
	ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
	retval = request_irq(pdev->irq, phantom_isr,
			IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
	if (retval) {
		dev_err(&pdev->dev, "can't establish ISR\n");
		goto err_unmo;
	}

	retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1);
	if (retval) {
		dev_err(&pdev->dev, "chardev registration failed\n");
		goto err_irq;
	}

	if (IS_ERR(device_create(phantom_class, &pdev->dev,
				 MKDEV(phantom_major, minor), NULL,
				 "phantom%u", minor)))
		dev_err(&pdev->dev, "can't create device\n");

	pci_set_drvdata(pdev, pht);

	return 0;
err_irq:
	free_irq(pdev->irq, pht);
err_unmo:
	pci_iounmap(pdev, pht->oaddr);
err_unmi:
	pci_iounmap(pdev, pht->iaddr);
err_unmc:
	pci_iounmap(pdev, pht->caddr);
err_fr:
	kfree(pht);
err_reg:
	pci_release_regions(pdev);
err_null:
	phantom_devices[minor] = 0;
err_dis:
	pci_disable_device(pdev);
err:
	return retval;
}

static void __devexit phantom_remove(struct pci_dev *pdev)
{
	struct phantom_device *pht = pci_get_drvdata(pdev);
	unsigned int minor = MINOR(pht->cdev.dev);

	device_destroy(phantom_class, MKDEV(phantom_major, minor));

	cdev_del(&pht->cdev);

	iowrite32(0, pht->caddr + PHN_IRQCTL);
	ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
	free_irq(pdev->irq, pht);

	pci_iounmap(pdev, pht->oaddr);
	pci_iounmap(pdev, pht->iaddr);
	pci_iounmap(pdev, pht->caddr);

	kfree(pht);

	pci_release_regions(pdev);

	phantom_devices[minor] = 0;

	pci_disable_device(pdev);
}

#ifdef CONFIG_PM
static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct phantom_device *dev = pci_get_drvdata(pdev);

	iowrite32(0, dev->caddr + PHN_IRQCTL);
	ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */

	synchronize_irq(pdev->irq);

	return 0;
}

static int phantom_resume(struct pci_dev *pdev)
{
	struct phantom_device *dev = pci_get_drvdata(pdev);

	iowrite32(0, dev->caddr + PHN_IRQCTL);

	return 0;
}
#else
#define phantom_suspend	NULL
#define phantom_resume	NULL
#endif

static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
	{ .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050,
	  .subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050,
	  .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);

static struct pci_driver phantom_pci_driver = {
	.name = "phantom",
	.id_table = phantom_pci_tbl,
	.probe = phantom_probe,
	.remove = __devexit_p(phantom_remove),
	.suspend = phantom_suspend,
	.resume = phantom_resume
};

static ssize_t phantom_show_version(struct class *cls, char *buf)
{
	return sprintf(buf, PHANTOM_VERSION "\n");
}

static CLASS_ATTR(version, 0444, phantom_show_version, NULL);

static int __init phantom_init(void)
{
	int retval;
	dev_t dev;

	phantom_class = class_create(THIS_MODULE, "phantom");
	if (IS_ERR(phantom_class)) {
		retval = PTR_ERR(phantom_class);
		printk(KERN_ERR "phantom: can't register phantom class\n");
		goto err;
	}
	retval = class_create_file(phantom_class, &class_attr_version);
	if (retval) {
		printk(KERN_ERR "phantom: can't create sysfs version file\n");
		goto err_class;
	}

	retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom");
	if (retval) {
		printk(KERN_ERR "phantom: can't register character device\n");
		goto err_attr;
	}
	phantom_major = MAJOR(dev);

	retval = pci_register_driver(&phantom_pci_driver);
	if (retval) {
		printk(KERN_ERR "phantom: can't register pci driver\n");
		goto err_unchr;
	}

	printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", "
			"init OK\n");

	return 0;
err_unchr:
	unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
err_attr:
	class_remove_file(phantom_class, &class_attr_version);
err_class:
	class_destroy(phantom_class);
err:
	return retval;
}

static void __exit phantom_exit(void)
{
	pci_unregister_driver(&phantom_pci_driver);

	unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);

	class_remove_file(phantom_class, &class_attr_version);
	class_destroy(phantom_class);

	pr_debug("phantom: module successfully removed\n");
}

module_init(phantom_init);
module_exit(phantom_exit);

MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>");
MODULE_DESCRIPTION("Sensable Phantom driver (PCI devices)");
MODULE_LICENSE("GPL");
MODULE_VERSION(PHANTOM_VERSION);
