/*
 * lirc_parallel.c
 *
 * lirc_parallel - device driver for infra-red signal receiving and
 *                 transmitting unit built by the author
 *
 * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
 *
 *  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
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

/*** Includes ***/

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/ktime.h>
#include <linux/mm.h>
#include <linux/delay.h>

#include <linux/io.h>
#include <linux/irq.h>
#include <linux/uaccess.h>
#include <asm/div64.h>

#include <linux/poll.h>
#include <linux/parport.h>
#include <linux/platform_device.h>

#include <media/lirc.h>
#include <media/lirc_dev.h>

#include "lirc_parallel.h"

#define LIRC_DRIVER_NAME "lirc_parallel"

#ifndef LIRC_IRQ
#define LIRC_IRQ 7
#endif
#ifndef LIRC_PORT
#define LIRC_PORT 0x378
#endif
#ifndef LIRC_TIMER
#define LIRC_TIMER 65536
#endif

/*** Global Variables ***/

static bool debug;
static bool check_pselecd;

static unsigned int irq = LIRC_IRQ;
static unsigned int io = LIRC_PORT;
#ifdef LIRC_TIMER
static unsigned int timer;
static unsigned int default_timer = LIRC_TIMER;
#endif

#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */

static int rbuf[RBUF_SIZE];

static DECLARE_WAIT_QUEUE_HEAD(lirc_wait);

static unsigned int rptr;
static unsigned int wptr;
static unsigned int lost_irqs;
static int is_open;

static struct parport *pport;
static struct pardevice *ppdevice;
static int is_claimed;

static unsigned int tx_mask = 1;

/*** Internal Functions ***/

static unsigned int in(int offset)
{
	switch (offset) {
	case LIRC_LP_BASE:
		return parport_read_data(pport);
	case LIRC_LP_STATUS:
		return parport_read_status(pport);
	case LIRC_LP_CONTROL:
		return parport_read_control(pport);
	}
	return 0; /* make compiler happy */
}

static void out(int offset, int value)
{
	switch (offset) {
	case LIRC_LP_BASE:
		parport_write_data(pport, value);
		break;
	case LIRC_LP_CONTROL:
		parport_write_control(pport, value);
		break;
	case LIRC_LP_STATUS:
		pr_info("attempt to write to status register\n");
		break;
	}
}

static unsigned int lirc_get_timer(void)
{
	return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
}

static unsigned int lirc_get_signal(void)
{
	return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
}

static void lirc_on(void)
{
	out(LIRC_PORT_DATA, tx_mask);
}

static void lirc_off(void)
{
	out(LIRC_PORT_DATA, 0);
}

static unsigned int init_lirc_timer(void)
{
	ktime_t kt, now, timeout;
	unsigned int level, newlevel, timeelapsed, newtimer;
	int count = 0;

	kt = ktime_get();
	/* wait max. 1 sec. */
	timeout = ktime_add_ns(kt, NSEC_PER_SEC);
	level = lirc_get_timer();
	do {
		newlevel = lirc_get_timer();
		if (level == 0 && newlevel != 0)
			count++;
		level = newlevel;
		now = ktime_get();
	} while (count < 1000 && (ktime_before(now, timeout)));
	timeelapsed = ktime_us_delta(now, kt);
	if (count >= 1000 && timeelapsed > 0) {
		if (default_timer == 0) {
			/* autodetect timer */
			newtimer = (1000000*count)/timeelapsed;
			pr_info("%u Hz timer detected\n", newtimer);
			return newtimer;
		}
		newtimer = (1000000*count)/timeelapsed;
		if (abs(newtimer - default_timer) > default_timer/10) {
			/* bad timer */
			pr_notice("bad timer: %u Hz\n", newtimer);
			pr_notice("using default timer: %u Hz\n",
				  default_timer);
			return default_timer;
		}
		pr_info("%u Hz timer detected\n", newtimer);
		return newtimer; /* use detected value */
	}

	pr_notice("no timer detected\n");
	return 0;
}

static int lirc_claim(void)
{
	if (parport_claim(ppdevice) != 0) {
		pr_warn("could not claim port\n");
		pr_warn("waiting for port becoming available\n");
		if (parport_claim_or_block(ppdevice) < 0) {
			pr_notice("could not claim port, giving up\n");
			return 0;
		}
	}
	out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);
	is_claimed = 1;
	return 1;
}

/*** interrupt handler ***/

static void rbuf_write(int signal)
{
	unsigned int nwptr;

	nwptr = (wptr + 1) & (RBUF_SIZE - 1);
	if (nwptr == rptr) {
		/* no new signals will be accepted */
		lost_irqs++;
		pr_notice("buffer overrun\n");
		return;
	}
	rbuf[wptr] = signal;
	wptr = nwptr;
}

static void lirc_lirc_irq_handler(void *blah)
{
	ktime_t kt, delkt;
	static ktime_t lastkt;
	static int init;
	long signal;
	int data;
	unsigned int level, newlevel;
	unsigned int timeout;

	if (!is_open)
		return;

	if (!is_claimed)
		return;

#if 0
	/* disable interrupt */
	  disable_irq(irq);
	  out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN));
#endif
	if (check_pselecd && (in(1) & LP_PSELECD))
		return;

#ifdef LIRC_TIMER
	if (init) {
		kt = ktime_get();

		delkt = ktime_sub(kt, lastkt);
		if (ktime_compare(delkt, ktime_set(15, 0)) > 0)
			/* really long time */
			data = PULSE_MASK;
		else
			data = (int)(ktime_to_us(delkt) + LIRC_SFH506_DELAY);

		rbuf_write(data); /* space */
	} else {
		if (timer == 0) {
			/*
			 * wake up; we'll lose this signal, but it will be
			 * garbage if the device is turned on anyway
			 */
			timer = init_lirc_timer();
			/* enable_irq(irq); */
			return;
		}
		init = 1;
	}

	timeout = timer / 10;	/* timeout after 1/10 sec. */
	signal = 1;
	level = lirc_get_timer();
	do {
		newlevel = lirc_get_timer();
		if (level == 0 && newlevel != 0)
			signal++;
		level = newlevel;

		/* giving up */
		if (signal > timeout
		    || (check_pselecd && (in(1) & LP_PSELECD))) {
			signal = 0;
			pr_notice("timeout\n");
			break;
		}
	} while (lirc_get_signal());

	if (signal != 0) {
		/* adjust value to usecs */
		__u64 helper;

		helper = ((__u64)signal) * 1000000;
		do_div(helper, timer);
		signal = (long)helper;

		if (signal > LIRC_SFH506_DELAY)
			data = signal - LIRC_SFH506_DELAY;
		else
			data = 1;
		rbuf_write(PULSE_BIT | data); /* pulse */
	}
	lastkt = ktime_get();
#else
	/* add your code here */
#endif

	wake_up_interruptible(&lirc_wait);

	/* enable interrupt */
	/*
	  enable_irq(irq);
	  out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
	*/
}

/*** file operations ***/

static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
{
	return -ESPIPE;
}

static ssize_t lirc_read(struct file *filep, char __user *buf, size_t n,
			 loff_t *ppos)
{
	int result = 0;
	int count = 0;
	DECLARE_WAITQUEUE(wait, current);

	if (n % sizeof(int))
		return -EINVAL;

	add_wait_queue(&lirc_wait, &wait);
	set_current_state(TASK_INTERRUPTIBLE);
	while (count < n) {
		if (rptr != wptr) {
			if (copy_to_user(buf + count, &rbuf[rptr],
					 sizeof(int))) {
				result = -EFAULT;
				break;
			}
			rptr = (rptr + 1) & (RBUF_SIZE - 1);
			count += sizeof(int);
		} else {
			if (filep->f_flags & O_NONBLOCK) {
				result = -EAGAIN;
				break;
			}
			if (signal_pending(current)) {
				result = -ERESTARTSYS;
				break;
			}
			schedule();
			set_current_state(TASK_INTERRUPTIBLE);
		}
	}
	remove_wait_queue(&lirc_wait, &wait);
	set_current_state(TASK_RUNNING);
	return count ? count : result;
}

static ssize_t lirc_write(struct file *filep, const char __user *buf, size_t n,
			  loff_t *ppos)
{
	int count;
	unsigned int i;
	unsigned int level, newlevel;
	unsigned long flags;
	int counttimer;
	int *wbuf;
	ssize_t ret;

	if (!is_claimed)
		return -EBUSY;

	count = n / sizeof(int);

	if (n % sizeof(int) || count % 2 == 0)
		return -EINVAL;

	wbuf = memdup_user(buf, n);
	if (IS_ERR(wbuf))
		return PTR_ERR(wbuf);

#ifdef LIRC_TIMER
	if (timer == 0) {
		/* try again if device is ready */
		timer = init_lirc_timer();
		if (timer == 0) {
			ret = -EIO;
			goto out;
		}
	}

	/* adjust values from usecs */
	for (i = 0; i < count; i++) {
		__u64 helper;

		helper = ((__u64)wbuf[i]) * timer;
		do_div(helper, 1000000);
		wbuf[i] = (int)helper;
	}

	local_irq_save(flags);
	i = 0;
	while (i < count) {
		level = lirc_get_timer();
		counttimer = 0;
		lirc_on();
		do {
			newlevel = lirc_get_timer();
			if (level == 0 && newlevel != 0)
				counttimer++;
			level = newlevel;
			if (check_pselecd && (in(1) & LP_PSELECD)) {
				lirc_off();
				local_irq_restore(flags);
				ret = -EIO;
				goto out;
			}
		} while (counttimer < wbuf[i]);
		i++;

		lirc_off();
		if (i == count)
			break;
		counttimer = 0;
		do {
			newlevel = lirc_get_timer();
			if (level == 0 && newlevel != 0)
				counttimer++;
			level = newlevel;
			if (check_pselecd && (in(1) & LP_PSELECD)) {
				local_irq_restore(flags);
				ret = -EIO;
				goto out;
			}
		} while (counttimer < wbuf[i]);
		i++;
	}
	local_irq_restore(flags);
#else
	/* place code that handles write without external timer here */
#endif
	ret = n;
out:
	kfree(wbuf);

	return ret;
}

static unsigned int lirc_poll(struct file *file, poll_table *wait)
{
	poll_wait(file, &lirc_wait, wait);
	if (rptr != wptr)
		return POLLIN | POLLRDNORM;
	return 0;
}

static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	int result;
	u32 __user *uptr = (u32 __user *)arg;
	u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
		       LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
	u32 mode;
	u32 value;

	switch (cmd) {
	case LIRC_GET_FEATURES:
		result = put_user(features, uptr);
		if (result)
			return result;
		break;
	case LIRC_GET_SEND_MODE:
		result = put_user(LIRC_MODE_PULSE, uptr);
		if (result)
			return result;
		break;
	case LIRC_GET_REC_MODE:
		result = put_user(LIRC_MODE_MODE2, uptr);
		if (result)
			return result;
		break;
	case LIRC_SET_SEND_MODE:
		result = get_user(mode, uptr);
		if (result)
			return result;
		if (mode != LIRC_MODE_PULSE)
			return -EINVAL;
		break;
	case LIRC_SET_REC_MODE:
		result = get_user(mode, uptr);
		if (result)
			return result;
		if (mode != LIRC_MODE_MODE2)
			return -ENOSYS;
		break;
	case LIRC_SET_TRANSMITTER_MASK:
		result = get_user(value, uptr);
		if (result)
			return result;
		if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
			return LIRC_PARALLEL_MAX_TRANSMITTERS;
		tx_mask = value;
		break;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static int lirc_open(struct inode *node, struct file *filep)
{
	if (is_open || !lirc_claim())
		return -EBUSY;

	parport_enable_irq(pport);

	/* init read ptr */
	rptr = 0;
	wptr = 0;
	lost_irqs = 0;

	is_open = 1;
	return 0;
}

static int lirc_close(struct inode *node, struct file *filep)
{
	if (is_claimed) {
		is_claimed = 0;
		parport_release(ppdevice);
	}
	is_open = 0;
	return 0;
}

static const struct file_operations lirc_fops = {
	.owner		= THIS_MODULE,
	.llseek		= lirc_lseek,
	.read		= lirc_read,
	.write		= lirc_write,
	.poll		= lirc_poll,
	.unlocked_ioctl	= lirc_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= lirc_ioctl,
#endif
	.open		= lirc_open,
	.release	= lirc_close
};

static int set_use_inc(void *data)
{
	return 0;
}

static void set_use_dec(void *data)
{
}

static struct lirc_driver driver = {
	.name		= LIRC_DRIVER_NAME,
	.minor		= -1,
	.code_length	= 1,
	.sample_rate	= 0,
	.data		= NULL,
	.add_to_buf	= NULL,
	.set_use_inc	= set_use_inc,
	.set_use_dec	= set_use_dec,
	.fops		= &lirc_fops,
	.dev		= NULL,
	.owner		= THIS_MODULE,
};

static struct platform_device *lirc_parallel_dev;

static int lirc_parallel_probe(struct platform_device *dev)
{
	return 0;
}

static int lirc_parallel_remove(struct platform_device *dev)
{
	return 0;
}

static int lirc_parallel_suspend(struct platform_device *dev,
					pm_message_t state)
{
	return 0;
}

static int lirc_parallel_resume(struct platform_device *dev)
{
	return 0;
}

static struct platform_driver lirc_parallel_driver = {
	.probe	= lirc_parallel_probe,
	.remove	= lirc_parallel_remove,
	.suspend	= lirc_parallel_suspend,
	.resume	= lirc_parallel_resume,
	.driver	= {
		.name	= LIRC_DRIVER_NAME,
	},
};

static int pf(void *handle)
{
	parport_disable_irq(pport);
	is_claimed = 0;
	return 0;
}

static void kf(void *handle)
{
	if (!is_open)
		return;
	if (!lirc_claim())
		return;
	parport_enable_irq(pport);
	lirc_off();
	/* this is a bit annoying when you actually print...*/
	/*
	printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
	*/
}

/*** module initialization and cleanup ***/

static int __init lirc_parallel_init(void)
{
	int result;

	result = platform_driver_register(&lirc_parallel_driver);
	if (result) {
		pr_notice("platform_driver_register returned %d\n", result);
		return result;
	}

	lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
	if (!lirc_parallel_dev) {
		result = -ENOMEM;
		goto exit_driver_unregister;
	}

	result = platform_device_add(lirc_parallel_dev);
	if (result)
		goto exit_device_put;

	pport = parport_find_base(io);
	if (!pport) {
		pr_notice("no port at %x found\n", io);
		result = -ENXIO;
		goto exit_device_put;
	}
	ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
					   pf, kf, lirc_lirc_irq_handler, 0,
					   NULL);
	parport_put_port(pport);
	if (!ppdevice) {
		pr_notice("parport_register_device() failed\n");
		result = -ENXIO;
		goto exit_device_put;
	}
	if (parport_claim(ppdevice) != 0)
		goto skip_init;
	is_claimed = 1;
	out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);

#ifdef LIRC_TIMER
	if (debug)
		out(LIRC_PORT_DATA, tx_mask);

	timer = init_lirc_timer();

#if 0	/* continue even if device is offline */
	if (timer == 0) {
		is_claimed = 0;
		parport_release(pport);
		parport_unregister_device(ppdevice);
		result = -EIO;
		goto exit_device_put;
	}

#endif
	if (debug)
		out(LIRC_PORT_DATA, 0);
#endif

	is_claimed = 0;
	parport_release(ppdevice);
 skip_init:
	driver.dev = &lirc_parallel_dev->dev;
	driver.minor = lirc_register_driver(&driver);
	if (driver.minor < 0) {
		pr_notice("register_chrdev() failed\n");
		parport_unregister_device(ppdevice);
		result = -EIO;
		goto exit_device_put;
	}
	pr_info("installed using port 0x%04x irq %d\n", io, irq);
	return 0;

exit_device_put:
	platform_device_put(lirc_parallel_dev);
exit_driver_unregister:
	platform_driver_unregister(&lirc_parallel_driver);
	return result;
}

static void __exit lirc_parallel_exit(void)
{
	parport_unregister_device(ppdevice);
	lirc_unregister_driver(driver.minor);

	platform_device_unregister(lirc_parallel_dev);
	platform_driver_unregister(&lirc_parallel_driver);
}

module_init(lirc_parallel_init);
module_exit(lirc_parallel_exit);

MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
MODULE_AUTHOR("Christoph Bartelmus");
MODULE_LICENSE("GPL");

module_param(io, int, S_IRUGO);
MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");

module_param(irq, int, S_IRUGO);
MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");

module_param(tx_mask, int, S_IRUGO);
MODULE_PARM_DESC(tx_mask, "Transmitter mask (default: 0x01)");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging messages");

module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");
