/*
 * i2c IR lirc driver for devices with zilog IR processors
 *
 * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
 * modified for PixelView (BT878P+W/FM) by
 *      Michal Kochanowicz <mkochano@pld.org.pl>
 *      Christoph Bartelmus <lirc@bartelmus.de>
 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
 *      Ulrich Mueller <ulrich.mueller42@web.de>
 * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
 *      Stefan Jahn <stefan@lkcc.org>
 * modified for inclusion into kernel sources by
 *      Jerome Brock <jbrock@users.sourceforge.net>
 * modified for Leadtek Winfast PVR2000 by
 *      Thomas Reitmayr (treitmayr@yahoo.com)
 * modified for Hauppauge PVR-150 IR TX device by
 *      Mark Weaver <mark@npsl.co.uk>
 * changed name from lirc_pvr150 to lirc_zilog, works on more than pvr-150
 *	Jarod Wilson <jarod@redhat.com>
 *
 * parts are cut&pasted from the lirc_i2c.c driver
 *
 * Numerous changes updating lirc_zilog.c in kernel 2.6.38 and later are
 * Copyright (C) 2011 Andy Walls <awalls@md.metrocast.net>
 *
 *  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
 *
 */


#include <linux/version.h>
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>

#include <linux/mutex.h>
#include <linux/kthread.h>

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

struct IR_rx {
	/* RX device */
	struct i2c_client *c;

	/* RX device buffer & lock */
	struct lirc_buffer buf;
	struct mutex buf_lock;

	/* RX polling thread data */
	struct task_struct *task;

	/* RX read data */
	unsigned char b[3];
	bool hdpvr_data_fmt;
};

struct IR_tx {
	/* TX device */
	struct i2c_client *c;

	/* TX additional actions needed */
	int need_boot;
	bool post_tx_ready_poll;
};

struct IR {
	struct lirc_driver l;

	struct mutex ir_lock;
	int open;

	struct i2c_adapter *adapter;
	struct IR_rx *rx;
	struct IR_tx *tx;
};

/* Minor -> data mapping */
static struct mutex ir_devices_lock;
static struct IR *ir_devices[MAX_IRCTL_DEVICES];

/* Block size for IR transmitter */
#define TX_BLOCK_SIZE	99

/* Hauppauge IR transmitter data */
struct tx_data_struct {
	/* Boot block */
	unsigned char *boot_data;

	/* Start of binary data block */
	unsigned char *datap;

	/* End of binary data block */
	unsigned char *endp;

	/* Number of installed codesets */
	unsigned int num_code_sets;

	/* Pointers to codesets */
	unsigned char **code_sets;

	/* Global fixed data template */
	int fixed[TX_BLOCK_SIZE];
};

static struct tx_data_struct *tx_data;
static struct mutex tx_data_lock;

#define zilog_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, \
					## args)
#define zilog_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
#define zilog_info(s, args...) printk(KERN_INFO KBUILD_MODNAME ": " s, ## args)

/* module parameters */
static int debug;	/* debug output */
static int tx_only;	/* only handle the IR Tx function */
static int minor = -1;	/* minor number */

#define dprintk(fmt, args...)						\
	do {								\
		if (debug)						\
			printk(KERN_DEBUG KBUILD_MODNAME ": " fmt,	\
				 ## args);				\
	} while (0)

static int add_to_buf(struct IR *ir)
{
	__u16 code;
	unsigned char codes[2];
	unsigned char keybuf[6];
	int got_data = 0;
	int ret;
	int failures = 0;
	unsigned char sendbuf[1] = { 0 };
	struct IR_rx *rx = ir->rx;

	if (rx == NULL)
		return -ENXIO;

	if (lirc_buffer_full(&rx->buf)) {
		dprintk("buffer overflow\n");
		return -EOVERFLOW;
	}

	/*
	 * service the device as long as it is returning
	 * data and we have space
	 */
	do {
		if (kthread_should_stop())
			return -ENODATA;

		/*
		 * Lock i2c bus for the duration.  RX/TX chips interfere so
		 * this is worth it
		 */
		mutex_lock(&ir->ir_lock);

		if (kthread_should_stop()) {
			mutex_unlock(&ir->ir_lock);
			return -ENODATA;
		}

		/*
		 * Send random "poll command" (?)  Windows driver does this
		 * and it is a good point to detect chip failure.
		 */
		ret = i2c_master_send(rx->c, sendbuf, 1);
		if (ret != 1) {
			zilog_error("i2c_master_send failed with %d\n",	ret);
			if (failures >= 3) {
				mutex_unlock(&ir->ir_lock);
				zilog_error("unable to read from the IR chip "
					    "after 3 resets, giving up\n");
				return ret;
			}

			/* Looks like the chip crashed, reset it */
			zilog_error("polling the IR receiver chip failed, "
				    "trying reset\n");

			set_current_state(TASK_UNINTERRUPTIBLE);
			if (kthread_should_stop()) {
				mutex_unlock(&ir->ir_lock);
				return -ENODATA;
			}
			schedule_timeout((100 * HZ + 999) / 1000);
			ir->tx->need_boot = 1;

			++failures;
			mutex_unlock(&ir->ir_lock);
			continue;
		}

		if (kthread_should_stop()) {
			mutex_unlock(&ir->ir_lock);
			return -ENODATA;
		}
		ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
		mutex_unlock(&ir->ir_lock);
		if (ret != sizeof(keybuf)) {
			zilog_error("i2c_master_recv failed with %d -- "
				    "keeping last read buffer\n", ret);
		} else {
			rx->b[0] = keybuf[3];
			rx->b[1] = keybuf[4];
			rx->b[2] = keybuf[5];
			dprintk("key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]);
		}

		/* key pressed ? */
		if (rx->hdpvr_data_fmt) {
			if (got_data && (keybuf[0] == 0x80))
				return 0;
			else if (got_data && (keybuf[0] == 0x00))
				return -ENODATA;
		} else if ((rx->b[0] & 0x80) == 0)
			return got_data ? 0 : -ENODATA;

		/* look what we have */
		code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);

		codes[0] = (code >> 8) & 0xff;
		codes[1] = code & 0xff;

		/* return it */
		lirc_buffer_write(&rx->buf, codes);
		++got_data;
	} while (!lirc_buffer_full(&rx->buf));

	return 0;
}

/*
 * Main function of the polling thread -- from lirc_dev.
 * We don't fit the LIRC model at all anymore.  This is horrible, but
 * basically we have a single RX/TX device with a nasty failure mode
 * that needs to be accounted for across the pair.  lirc lets us provide
 * fops, but prevents us from using the internal polling, etc. if we do
 * so.  Hence the replication.  Might be neater to extend the LIRC model
 * to account for this but I'd think it's a very special case of seriously
 * messed up hardware.
 */
static int lirc_thread(void *arg)
{
	struct IR *ir = arg;
	struct IR_rx *rx = ir->rx;

	dprintk("poll thread started\n");

	while (!kthread_should_stop()) {
		set_current_state(TASK_INTERRUPTIBLE);

		/* if device not opened, we can sleep half a second */
		if (!ir->open) {
			schedule_timeout(HZ/2);
			continue;
		}

		/*
		 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
		 * We use this interval as the chip resets every time you poll
		 * it (bad!).  This is therefore just sufficient to catch all
		 * of the button presses.  It makes the remote much more
		 * responsive.  You can see the difference by running irw and
		 * holding down a button.  With 100ms, the old polling
		 * interval, you'll notice breaks in the repeat sequence
		 * corresponding to lost keypresses.
		 */
		schedule_timeout((260 * HZ) / 1000);
		if (kthread_should_stop())
			break;
		if (!add_to_buf(ir))
			wake_up_interruptible(&rx->buf.wait_poll);
	}

	dprintk("poll thread ended\n");
	return 0;
}

static int set_use_inc(void *data)
{
	struct IR *ir = data;

	if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0)
		return -ENODEV;

	/* lock bttv in memory while /dev/lirc is in use  */
	/*
	 * this is completely broken code. lirc_unregister_driver()
	 * must be possible even when the device is open
	 */
	if (ir->rx != NULL)
		i2c_use_client(ir->rx->c);
	if (ir->tx != NULL)
		i2c_use_client(ir->tx->c);

	return 0;
}

static void set_use_dec(void *data)
{
	struct IR *ir = data;

	if (ir->rx)
		i2c_release_client(ir->rx->c);
	if (ir->tx)
		i2c_release_client(ir->tx->c);
	if (ir->l.owner != NULL)
		module_put(ir->l.owner);
}

/* safe read of a uint32 (always network byte order) */
static int read_uint32(unsigned char **data,
				     unsigned char *endp, unsigned int *val)
{
	if (*data + 4 > endp)
		return 0;
	*val = ((*data)[0] << 24) | ((*data)[1] << 16) |
	       ((*data)[2] << 8) | (*data)[3];
	*data += 4;
	return 1;
}

/* safe read of a uint8 */
static int read_uint8(unsigned char **data,
				    unsigned char *endp, unsigned char *val)
{
	if (*data + 1 > endp)
		return 0;
	*val = *((*data)++);
	return 1;
}

/* safe skipping of N bytes */
static int skip(unsigned char **data,
			      unsigned char *endp, unsigned int distance)
{
	if (*data + distance > endp)
		return 0;
	*data += distance;
	return 1;
}

/* decompress key data into the given buffer */
static int get_key_data(unsigned char *buf,
			     unsigned int codeset, unsigned int key)
{
	unsigned char *data, *endp, *diffs, *key_block;
	unsigned char keys, ndiffs, id;
	unsigned int base, lim, pos, i;

	/* Binary search for the codeset */
	for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) {
		pos = base + (lim >> 1);
		data = tx_data->code_sets[pos];

		if (!read_uint32(&data, tx_data->endp, &i))
			goto corrupt;

		if (i == codeset)
			break;
		else if (codeset > i) {
			base = pos + 1;
			--lim;
		}
	}
	/* Not found? */
	if (!lim)
		return -EPROTO;

	/* Set end of data block */
	endp = pos < tx_data->num_code_sets - 1 ?
		tx_data->code_sets[pos + 1] : tx_data->endp;

	/* Read the block header */
	if (!read_uint8(&data, endp, &keys) ||
	    !read_uint8(&data, endp, &ndiffs) ||
	    ndiffs > TX_BLOCK_SIZE || keys == 0)
		goto corrupt;

	/* Save diffs & skip */
	diffs = data;
	if (!skip(&data, endp, ndiffs))
		goto corrupt;

	/* Read the id of the first key */
	if (!read_uint8(&data, endp, &id))
		goto corrupt;

	/* Unpack the first key's data */
	for (i = 0; i < TX_BLOCK_SIZE; ++i) {
		if (tx_data->fixed[i] == -1) {
			if (!read_uint8(&data, endp, &buf[i]))
				goto corrupt;
		} else {
			buf[i] = (unsigned char)tx_data->fixed[i];
		}
	}

	/* Early out key found/not found */
	if (key == id)
		return 0;
	if (keys == 1)
		return -EPROTO;

	/* Sanity check */
	key_block = data;
	if (!skip(&data, endp, (keys - 1) * (ndiffs + 1)))
		goto corrupt;

	/* Binary search for the key */
	for (base = 0, lim = keys - 1; lim; lim >>= 1) {
		/* Seek to block */
		unsigned char *key_data;
		pos = base + (lim >> 1);
		key_data = key_block + (ndiffs + 1) * pos;

		if (*key_data == key) {
			/* skip key id */
			++key_data;

			/* found, so unpack the diffs */
			for (i = 0; i < ndiffs; ++i) {
				unsigned char val;
				if (!read_uint8(&key_data, endp, &val) ||
				    diffs[i] >= TX_BLOCK_SIZE)
					goto corrupt;
				buf[diffs[i]] = val;
			}

			return 0;
		} else if (key > *key_data) {
			base = pos + 1;
			--lim;
		}
	}
	/* Key not found */
	return -EPROTO;

corrupt:
	zilog_error("firmware is corrupt\n");
	return -EFAULT;
}

/* send a block of data to the IR TX device */
static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
{
	int i, j, ret;
	unsigned char buf[5];

	for (i = 0; i < TX_BLOCK_SIZE;) {
		int tosend = TX_BLOCK_SIZE - i;
		if (tosend > 4)
			tosend = 4;
		buf[0] = (unsigned char)(i + 1);
		for (j = 0; j < tosend; ++j)
			buf[1 + j] = data_block[i + j];
		dprintk("%02x %02x %02x %02x %02x",
			buf[0], buf[1], buf[2], buf[3], buf[4]);
		ret = i2c_master_send(tx->c, buf, tosend + 1);
		if (ret != tosend + 1) {
			zilog_error("i2c_master_send failed with %d\n", ret);
			return ret < 0 ? ret : -EFAULT;
		}
		i += tosend;
	}
	return 0;
}

/* send boot data to the IR TX device */
static int send_boot_data(struct IR_tx *tx)
{
	int ret, i;
	unsigned char buf[4];

	/* send the boot block */
	ret = send_data_block(tx, tx_data->boot_data);
	if (ret != 0)
		return ret;

	/* Hit the go button to activate the new boot data */
	buf[0] = 0x00;
	buf[1] = 0x20;
	ret = i2c_master_send(tx->c, buf, 2);
	if (ret != 2) {
		zilog_error("i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/*
	 * Wait for zilog to settle after hitting go post boot block upload.
	 * Without this delay, the HD-PVR and HVR-1950 both return an -EIO
	 * upon attempting to get firmware revision, and tx probe thus fails.
	 */
	for (i = 0; i < 10; i++) {
		ret = i2c_master_send(tx->c, buf, 1);
		if (ret == 1)
			break;
		udelay(100);
	}

	if (ret != 1) {
		zilog_error("i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/* Here comes the firmware version... (hopefully) */
	ret = i2c_master_recv(tx->c, buf, 4);
	if (ret != 4) {
		zilog_error("i2c_master_recv failed with %d\n", ret);
		return 0;
	}
	if ((buf[0] != 0x80) && (buf[0] != 0xa0)) {
		zilog_error("unexpected IR TX init response: %02x\n", buf[0]);
		return 0;
	}
	zilog_notify("Zilog/Hauppauge IR blaster firmware version "
		     "%d.%d.%d loaded\n", buf[1], buf[2], buf[3]);

	return 0;
}

/* unload "firmware", lock held */
static void fw_unload_locked(void)
{
	if (tx_data) {
		if (tx_data->code_sets)
			vfree(tx_data->code_sets);

		if (tx_data->datap)
			vfree(tx_data->datap);

		vfree(tx_data);
		tx_data = NULL;
		dprintk("successfully unloaded IR blaster firmware\n");
	}
}

/* unload "firmware" for the IR TX device */
static void fw_unload(void)
{
	mutex_lock(&tx_data_lock);
	fw_unload_locked();
	mutex_unlock(&tx_data_lock);
}

/* load "firmware" for the IR TX device */
static int fw_load(struct IR_tx *tx)
{
	int ret;
	unsigned int i;
	unsigned char *data, version, num_global_fixed;
	const struct firmware *fw_entry;

	/* Already loaded? */
	mutex_lock(&tx_data_lock);
	if (tx_data) {
		ret = 0;
		goto out;
	}

	/* Request codeset data file */
	ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c->dev);
	if (ret != 0) {
		zilog_error("firmware haup-ir-blaster.bin not available "
			    "(%d)\n", ret);
		ret = ret < 0 ? ret : -EFAULT;
		goto out;
	}
	dprintk("firmware of size %zu loaded\n", fw_entry->size);

	/* Parse the file */
	tx_data = vmalloc(sizeof(*tx_data));
	if (tx_data == NULL) {
		zilog_error("out of memory\n");
		release_firmware(fw_entry);
		ret = -ENOMEM;
		goto out;
	}
	tx_data->code_sets = NULL;

	/* Copy the data so hotplug doesn't get confused and timeout */
	tx_data->datap = vmalloc(fw_entry->size);
	if (tx_data->datap == NULL) {
		zilog_error("out of memory\n");
		release_firmware(fw_entry);
		vfree(tx_data);
		ret = -ENOMEM;
		goto out;
	}
	memcpy(tx_data->datap, fw_entry->data, fw_entry->size);
	tx_data->endp = tx_data->datap + fw_entry->size;
	release_firmware(fw_entry); fw_entry = NULL;

	/* Check version */
	data = tx_data->datap;
	if (!read_uint8(&data, tx_data->endp, &version))
		goto corrupt;
	if (version != 1) {
		zilog_error("unsupported code set file version (%u, expected"
			    "1) -- please upgrade to a newer driver",
			    version);
		fw_unload_locked();
		ret = -EFAULT;
		goto out;
	}

	/* Save boot block for later */
	tx_data->boot_data = data;
	if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE))
		goto corrupt;

	if (!read_uint32(&data, tx_data->endp,
			      &tx_data->num_code_sets))
		goto corrupt;

	dprintk("%u IR blaster codesets loaded\n", tx_data->num_code_sets);

	tx_data->code_sets = vmalloc(
		tx_data->num_code_sets * sizeof(char *));
	if (tx_data->code_sets == NULL) {
		fw_unload_locked();
		ret = -ENOMEM;
		goto out;
	}

	for (i = 0; i < TX_BLOCK_SIZE; ++i)
		tx_data->fixed[i] = -1;

	/* Read global fixed data template */
	if (!read_uint8(&data, tx_data->endp, &num_global_fixed) ||
	    num_global_fixed > TX_BLOCK_SIZE)
		goto corrupt;
	for (i = 0; i < num_global_fixed; ++i) {
		unsigned char pos, val;
		if (!read_uint8(&data, tx_data->endp, &pos) ||
		    !read_uint8(&data, tx_data->endp, &val) ||
		    pos >= TX_BLOCK_SIZE)
			goto corrupt;
		tx_data->fixed[pos] = (int)val;
	}

	/* Filch out the position of each code set */
	for (i = 0; i < tx_data->num_code_sets; ++i) {
		unsigned int id;
		unsigned char keys;
		unsigned char ndiffs;

		/* Save the codeset position */
		tx_data->code_sets[i] = data;

		/* Read header */
		if (!read_uint32(&data, tx_data->endp, &id) ||
		    !read_uint8(&data, tx_data->endp, &keys) ||
		    !read_uint8(&data, tx_data->endp, &ndiffs) ||
		    ndiffs > TX_BLOCK_SIZE || keys == 0)
			goto corrupt;

		/* skip diff positions */
		if (!skip(&data, tx_data->endp, ndiffs))
			goto corrupt;

		/*
		 * After the diffs we have the first key id + data -
		 * global fixed
		 */
		if (!skip(&data, tx_data->endp,
			       1 + TX_BLOCK_SIZE - num_global_fixed))
			goto corrupt;

		/* Then we have keys-1 blocks of key id+diffs */
		if (!skip(&data, tx_data->endp,
			       (ndiffs + 1) * (keys - 1)))
			goto corrupt;
	}
	ret = 0;
	goto out;

corrupt:
	zilog_error("firmware is corrupt\n");
	fw_unload_locked();
	ret = -EFAULT;

out:
	mutex_unlock(&tx_data_lock);
	return ret;
}

/* initialise the IR TX device */
static int tx_init(struct IR_tx *tx)
{
	int ret;

	/* Load 'firmware' */
	ret = fw_load(tx);
	if (ret != 0)
		return ret;

	/* Send boot block */
	ret = send_boot_data(tx);
	if (ret != 0)
		return ret;
	tx->need_boot = 0;

	/* Looks good */
	return 0;
}

/* do nothing stub to make LIRC happy */
static loff_t lseek(struct file *filep, loff_t offset, int orig)
{
	return -ESPIPE;
}

/* copied from lirc_dev */
static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
{
	struct IR *ir = filep->private_data;
	struct IR_rx *rx = ir->rx;
	int ret = 0, written = 0;
	DECLARE_WAITQUEUE(wait, current);

	dprintk("read called\n");
	if (rx == NULL)
		return -ENODEV;

	if (mutex_lock_interruptible(&rx->buf_lock))
		return -ERESTARTSYS;

	if (n % rx->buf.chunk_size) {
		dprintk("read result = -EINVAL\n");
		mutex_unlock(&rx->buf_lock);
		return -EINVAL;
	}

	/*
	 * we add ourselves to the task queue before buffer check
	 * to avoid losing scan code (in case when queue is awaken somewhere
	 * between while condition checking and scheduling)
	 */
	add_wait_queue(&rx->buf.wait_poll, &wait);
	set_current_state(TASK_INTERRUPTIBLE);

	/*
	 * while we didn't provide 'length' bytes, device is opened in blocking
	 * mode and 'copy_to_user' is happy, wait for data.
	 */
	while (written < n && ret == 0) {
		if (lirc_buffer_empty(&rx->buf)) {
			/*
			 * According to the read(2) man page, 'written' can be
			 * returned as less than 'n', instead of blocking
			 * again, returning -EWOULDBLOCK, or returning
			 * -ERESTARTSYS
			 */
			if (written)
				break;
			if (filep->f_flags & O_NONBLOCK) {
				ret = -EWOULDBLOCK;
				break;
			}
			if (signal_pending(current)) {
				ret = -ERESTARTSYS;
				break;
			}
			schedule();
			set_current_state(TASK_INTERRUPTIBLE);
		} else {
			unsigned char buf[rx->buf.chunk_size];
			lirc_buffer_read(&rx->buf, buf);
			ret = copy_to_user((void *)outbuf+written, buf,
					   rx->buf.chunk_size);
			written += rx->buf.chunk_size;
		}
	}

	remove_wait_queue(&rx->buf.wait_poll, &wait);
	set_current_state(TASK_RUNNING);
	mutex_unlock(&rx->buf_lock);

	dprintk("read result = %s (%d)\n",
		ret ? "-EFAULT" : "OK", ret);

	return ret ? ret : written;
}

/* send a keypress to the IR TX device */
static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key)
{
	unsigned char data_block[TX_BLOCK_SIZE];
	unsigned char buf[2];
	int i, ret;

	/* Get data for the codeset/key */
	ret = get_key_data(data_block, code, key);

	if (ret == -EPROTO) {
		zilog_error("failed to get data for code %u, key %u -- check "
			    "lircd.conf entries\n", code, key);
		return ret;
	} else if (ret != 0)
		return ret;

	/* Send the data block */
	ret = send_data_block(tx, data_block);
	if (ret != 0)
		return ret;

	/* Send data block length? */
	buf[0] = 0x00;
	buf[1] = 0x40;
	ret = i2c_master_send(tx->c, buf, 2);
	if (ret != 2) {
		zilog_error("i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/* Give the z8 a moment to process data block */
	for (i = 0; i < 10; i++) {
		ret = i2c_master_send(tx->c, buf, 1);
		if (ret == 1)
			break;
		udelay(100);
	}

	if (ret != 1) {
		zilog_error("i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/* Send finished download? */
	ret = i2c_master_recv(tx->c, buf, 1);
	if (ret != 1) {
		zilog_error("i2c_master_recv failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}
	if (buf[0] != 0xA0) {
		zilog_error("unexpected IR TX response #1: %02x\n",
			buf[0]);
		return -EFAULT;
	}

	/* Send prepare command? */
	buf[0] = 0x00;
	buf[1] = 0x80;
	ret = i2c_master_send(tx->c, buf, 2);
	if (ret != 2) {
		zilog_error("i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/*
	 * The sleep bits aren't necessary on the HD PVR, and in fact, the
	 * last i2c_master_recv always fails with a -5, so for now, we're
	 * going to skip this whole mess and say we're done on the HD PVR
	 */
	if (!tx->post_tx_ready_poll) {
		dprintk("sent code %u, key %u\n", code, key);
		return 0;
	}

	/*
	 * This bit NAKs until the device is ready, so we retry it
	 * sleeping a bit each time.  This seems to be what the windows
	 * driver does, approximately.
	 * Try for up to 1s.
	 */
	for (i = 0; i < 20; ++i) {
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout((50 * HZ + 999) / 1000);
		ret = i2c_master_send(tx->c, buf, 1);
		if (ret == 1)
			break;
		dprintk("NAK expected: i2c_master_send "
			"failed with %d (try %d)\n", ret, i+1);
	}
	if (ret != 1) {
		zilog_error("IR TX chip never got ready: last i2c_master_send "
			    "failed with %d\n", ret);
		return ret < 0 ? ret : -EFAULT;
	}

	/* Seems to be an 'ok' response */
	i = i2c_master_recv(tx->c, buf, 1);
	if (i != 1) {
		zilog_error("i2c_master_recv failed with %d\n", ret);
		return -EFAULT;
	}
	if (buf[0] != 0x80) {
		zilog_error("unexpected IR TX response #2: %02x\n", buf[0]);
		return -EFAULT;
	}

	/* Oh good, it worked */
	dprintk("sent code %u, key %u\n", code, key);
	return 0;
}

/*
 * Write a code to the device.  We take in a 32-bit number (an int) and then
 * decode this to a codeset/key index.  The key data is then decompressed and
 * sent to the device.  We have a spin lock as per i2c documentation to prevent
 * multiple concurrent sends which would probably cause the device to explode.
 */
static ssize_t write(struct file *filep, const char *buf, size_t n,
			  loff_t *ppos)
{
	struct IR *ir = filep->private_data;
	struct IR_tx *tx = ir->tx;
	size_t i;
	int failures = 0;

	if (tx == NULL)
		return -ENODEV;

	/* Validate user parameters */
	if (n % sizeof(int))
		return -EINVAL;

	/* Lock i2c bus for the duration */
	mutex_lock(&ir->ir_lock);

	/* Send each keypress */
	for (i = 0; i < n;) {
		int ret = 0;
		int command;

		if (copy_from_user(&command, buf + i, sizeof(command))) {
			mutex_unlock(&ir->ir_lock);
			return -EFAULT;
		}

		/* Send boot data first if required */
		if (tx->need_boot == 1) {
			ret = send_boot_data(tx);
			if (ret == 0)
				tx->need_boot = 0;
		}

		/* Send the code */
		if (ret == 0) {
			ret = send_code(tx, (unsigned)command >> 16,
					    (unsigned)command & 0xFFFF);
			if (ret == -EPROTO) {
				mutex_unlock(&ir->ir_lock);
				return ret;
			}
		}

		/*
		 * Hmm, a failure.  If we've had a few then give up, otherwise
		 * try a reset
		 */
		if (ret != 0) {
			/* Looks like the chip crashed, reset it */
			zilog_error("sending to the IR transmitter chip "
				    "failed, trying reset\n");

			if (failures >= 3) {
				zilog_error("unable to send to the IR chip "
					    "after 3 resets, giving up\n");
				mutex_unlock(&ir->ir_lock);
				return ret;
			}
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout((100 * HZ + 999) / 1000);
			tx->need_boot = 1;
			++failures;
		} else
			i += sizeof(int);
	}

	/* Release i2c bus */
	mutex_unlock(&ir->ir_lock);

	/* All looks good */
	return n;
}

/* copied from lirc_dev */
static unsigned int poll(struct file *filep, poll_table *wait)
{
	struct IR *ir = filep->private_data;
	struct IR_rx *rx = ir->rx;
	unsigned int ret;

	dprintk("poll called\n");
	if (rx == NULL)
		return -ENODEV;

	mutex_lock(&rx->buf_lock);

	poll_wait(filep, &rx->buf.wait_poll, wait);

	dprintk("poll result = %s\n",
		lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM");

	ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM);

	mutex_unlock(&rx->buf_lock);
	return ret;
}

static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	struct IR *ir = filep->private_data;
	int result;
	unsigned long mode, features = 0;

	features |= LIRC_CAN_SEND_PULSE;
	if (ir->rx != NULL)
		features |= LIRC_CAN_REC_LIRCCODE;

	switch (cmd) {
	case LIRC_GET_LENGTH:
		result = put_user((unsigned long)13,
				  (unsigned long *)arg);
		break;
	case LIRC_GET_FEATURES:
		result = put_user(features, (unsigned long *) arg);
		break;
	case LIRC_GET_REC_MODE:
		if (!(features&LIRC_CAN_REC_MASK))
			return -ENOSYS;

		result = put_user(LIRC_REC2MODE
				  (features&LIRC_CAN_REC_MASK),
				  (unsigned long *)arg);
		break;
	case LIRC_SET_REC_MODE:
		if (!(features&LIRC_CAN_REC_MASK))
			return -ENOSYS;

		result = get_user(mode, (unsigned long *)arg);
		if (!result && !(LIRC_MODE2REC(mode) & features))
			result = -EINVAL;
		break;
	case LIRC_GET_SEND_MODE:
		result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
		break;
	case LIRC_SET_SEND_MODE:
		result = get_user(mode, (unsigned long *) arg);
		if (!result && mode != LIRC_MODE_PULSE)
			return -EINVAL;
		break;
	default:
		return -EINVAL;
	}
	return result;
}

/* ir_devices_lock must be held */
static struct IR *find_ir_device_by_minor(unsigned int minor)
{
	if (minor >= MAX_IRCTL_DEVICES)
		return NULL;

	return ir_devices[minor];
}

/*
 * Open the IR device.  Get hold of our IR structure and
 * stash it in private_data for the file
 */
static int open(struct inode *node, struct file *filep)
{
	struct IR *ir;
	int ret;
	unsigned int minor = MINOR(node->i_rdev);

	/* find our IR struct */
	mutex_lock(&ir_devices_lock);
	ir = find_ir_device_by_minor(minor);
	mutex_unlock(&ir_devices_lock);

	if (ir == NULL)
		return -ENODEV;

	/* increment in use count */
	mutex_lock(&ir->ir_lock);
	++ir->open;
	ret = set_use_inc(ir);
	if (ret != 0) {
		--ir->open;
		mutex_unlock(&ir->ir_lock);
		return ret;
	}
	mutex_unlock(&ir->ir_lock);

	/* stash our IR struct */
	filep->private_data = ir;

	return 0;
}

/* Close the IR device */
static int close(struct inode *node, struct file *filep)
{
	/* find our IR struct */
	struct IR *ir = filep->private_data;
	if (ir == NULL) {
		zilog_error("close: no private_data attached to the file!\n");
		return -ENODEV;
	}

	/* decrement in use count */
	mutex_lock(&ir->ir_lock);
	--ir->open;
	set_use_dec(ir);
	mutex_unlock(&ir->ir_lock);

	return 0;
}

static struct lirc_driver lirc_template = {
	.name		= "lirc_zilog",
	.set_use_inc	= set_use_inc,
	.set_use_dec	= set_use_dec,
	.owner		= THIS_MODULE
};

static int ir_remove(struct i2c_client *client);
static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);

#define ID_FLAG_TX	0x01
#define ID_FLAG_HDPVR	0x02

static const struct i2c_device_id ir_transceiver_id[] = {
	{ "ir_tx_z8f0811_haup",  ID_FLAG_TX                 },
	{ "ir_rx_z8f0811_haup",  0                          },
	{ "ir_tx_z8f0811_hdpvr", ID_FLAG_HDPVR | ID_FLAG_TX },
	{ "ir_rx_z8f0811_hdpvr", ID_FLAG_HDPVR              },
	{ }
};

static struct i2c_driver driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "Zilog/Hauppauge i2c IR",
	},
	.probe		= ir_probe,
	.remove		= ir_remove,
	.id_table	= ir_transceiver_id,
};

static const struct file_operations lirc_fops = {
	.owner		= THIS_MODULE,
	.llseek		= lseek,
	.read		= read,
	.write		= write,
	.poll		= poll,
	.unlocked_ioctl	= ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= ioctl,
#endif
	.open		= open,
	.release	= close
};

static void destroy_rx_kthread(struct IR_rx *rx)
{
	/* end up polling thread */
	if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) {
		kthread_stop(rx->task);
		rx->task = NULL;
	}
}

/* ir_devices_lock must be held */
static int add_ir_device(struct IR *ir)
{
	int i;

	for (i = 0; i < MAX_IRCTL_DEVICES; i++)
		if (ir_devices[i] == NULL) {
			ir_devices[i] = ir;
			break;
		}

	return i == MAX_IRCTL_DEVICES ? -ENOMEM : i;
}

/* ir_devices_lock must be held */
static void del_ir_device(struct IR *ir)
{
	int i;

	for (i = 0; i < MAX_IRCTL_DEVICES; i++)
		if (ir_devices[i] == ir) {
			ir_devices[i] = NULL;
			break;
		}
}

static int ir_remove(struct i2c_client *client)
{
	struct IR *ir = i2c_get_clientdata(client);

	mutex_lock(&ir_devices_lock);

	if (ir == NULL) {
		/* We destroyed everything when the first client came through */
		mutex_unlock(&ir_devices_lock);
		return 0;
	}

	/* Good-bye LIRC */
	lirc_unregister_driver(ir->l.minor);

	/* Good-bye Rx */
	destroy_rx_kthread(ir->rx);
	if (ir->rx != NULL) {
		if (ir->rx->buf.fifo_initialized)
			lirc_buffer_free(&ir->rx->buf);
		i2c_set_clientdata(ir->rx->c, NULL);
		kfree(ir->rx);
	}

	/* Good-bye Tx */
	i2c_set_clientdata(ir->tx->c, NULL);
	kfree(ir->tx);

	/* Good-bye IR */
	del_ir_device(ir);
	kfree(ir);

	mutex_unlock(&ir_devices_lock);
	return 0;
}


/* ir_devices_lock must be held */
static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter)
{
	int i;
	struct IR *ir = NULL;

	for (i = 0; i < MAX_IRCTL_DEVICES; i++)
		if (ir_devices[i] != NULL &&
		    ir_devices[i]->adapter == adapter) {
			ir = ir_devices[i];
			break;
		}

	return ir;
}

static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct IR *ir;
	struct i2c_adapter *adap = client->adapter;
	int ret;
	bool tx_probe = false;

	dprintk("%s: %s on i2c-%d (%s), client addr=0x%02x\n",
		__func__, id->name, adap->nr, adap->name, client->addr);

	/*
	 * The IR receiver    is at i2c address 0x71.
	 * The IR transmitter is at i2c address 0x70.
	 */

	if (id->driver_data & ID_FLAG_TX)
		tx_probe = true;
	else if (tx_only) /* module option */
		return -ENXIO;

	zilog_info("probing IR %s on %s (i2c-%d)\n",
		   tx_probe ? "Tx" : "Rx", adap->name, adap->nr);

	mutex_lock(&ir_devices_lock);

	/* Use a single struct IR instance for both the Rx and Tx functions */
	ir = find_ir_device_by_adapter(adap);
	if (ir == NULL) {
		ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
		if (ir == NULL) {
			ret = -ENOMEM;
			goto out_no_ir;
		}
		/* store for use in ir_probe() again, and open() later on */
		ret = add_ir_device(ir);
		if (ret)
			goto out_free_ir;

		ir->adapter = adap;
		mutex_init(&ir->ir_lock);

		/* set lirc_dev stuff */
		memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
		ir->l.minor       = minor; /* module option */
		ir->l.code_length = 13;
		ir->l.rbuf	  = NULL;
		ir->l.fops	  = &lirc_fops;
		ir->l.data	  = ir;
		ir->l.dev         = &adap->dev;
		ir->l.sample_rate = 0;
	}

	if (tx_probe) {
		/* Set up a struct IR_tx instance */
		ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL);
		if (ir->tx == NULL) {
			ret = -ENOMEM;
			goto out_free_xx;
		}

		ir->tx->c = client;
		ir->tx->need_boot = 1;
		ir->tx->post_tx_ready_poll =
			       (id->driver_data & ID_FLAG_HDPVR) ? false : true;
	} else {
		/* Set up a struct IR_rx instance */
		ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
		if (ir->rx == NULL) {
			ret = -ENOMEM;
			goto out_free_xx;
		}

		ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2);
		if (ret)
			goto out_free_xx;

		mutex_init(&ir->rx->buf_lock);
		ir->rx->c = client;
		ir->rx->hdpvr_data_fmt =
			       (id->driver_data & ID_FLAG_HDPVR) ? true : false;

		/* set lirc_dev stuff */
		ir->l.rbuf = &ir->rx->buf;
	}

	i2c_set_clientdata(client, ir);

	/* Proceed only if we have the required Tx and Rx clients ready to go */
	if (ir->tx == NULL ||
	    (ir->rx == NULL && !tx_only)) {
		zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on "
			   "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name,
			   adap->nr, tx_probe ? "Rx" : "Tx");
		goto out_ok;
	}

	/* initialise RX device */
	if (ir->rx != NULL) {
		/* try to fire up polling thread */
		ir->rx->task = kthread_run(lirc_thread, ir,
					   "zilog-rx-i2c-%d", adap->nr);
		if (IS_ERR(ir->rx->task)) {
			ret = PTR_ERR(ir->rx->task);
			zilog_error("%s: could not start IR Rx polling thread"
				    "\n", __func__);
			goto out_free_xx;
		}
	}

	/* register with lirc */
	ir->l.minor = lirc_register_driver(&ir->l);
	if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) {
		zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n",
			    __func__, MAX_IRCTL_DEVICES-1, ir->l.minor);
		ret = -EBADRQC;
		goto out_free_thread;
	}

	/*
	 * if we have the tx device, load the 'firmware'.  We do this
	 * after registering with lirc as otherwise hotplug seems to take
	 * 10s to create the lirc device.
	 */
	ret = tx_init(ir->tx);
	if (ret != 0)
		goto out_unregister;

	zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n",
		   tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
out_ok:
	mutex_unlock(&ir_devices_lock);
	return 0;

out_unregister:
	lirc_unregister_driver(ir->l.minor);
out_free_thread:
	destroy_rx_kthread(ir->rx);
out_free_xx:
	if (ir->rx != NULL) {
		if (ir->rx->buf.fifo_initialized)
			lirc_buffer_free(&ir->rx->buf);
		if (ir->rx->c != NULL)
			i2c_set_clientdata(ir->rx->c, NULL);
		kfree(ir->rx);
	}
	if (ir->tx != NULL) {
		if (ir->tx->c != NULL)
			i2c_set_clientdata(ir->tx->c, NULL);
		kfree(ir->tx);
	}
out_free_ir:
	del_ir_device(ir);
	kfree(ir);
out_no_ir:
	zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n",
		    __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr,
		   ret);
	mutex_unlock(&ir_devices_lock);
	return ret;
}

static int __init zilog_init(void)
{
	int ret;

	zilog_notify("Zilog/Hauppauge IR driver initializing\n");

	mutex_init(&tx_data_lock);
	mutex_init(&ir_devices_lock);

	request_module("firmware_class");

	ret = i2c_add_driver(&driver);
	if (ret)
		zilog_error("initialization failed\n");
	else
		zilog_notify("initialization complete\n");

	return ret;
}

static void __exit zilog_exit(void)
{
	i2c_del_driver(&driver);
	/* if loaded */
	fw_unload();
	zilog_notify("Zilog/Hauppauge IR driver unloaded\n");
}

module_init(zilog_init);
module_exit(zilog_exit);

MODULE_DESCRIPTION("Zilog/Hauppauge infrared transmitter driver (i2c stack)");
MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, "
	      "Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver, "
	      "Andy Walls");
MODULE_LICENSE("GPL");
/* for compat with old name, which isn't all that accurate anymore */
MODULE_ALIAS("lirc_pvr150");

module_param(minor, int, 0444);
MODULE_PARM_DESC(minor, "Preferred minor device number");

module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Enable debugging messages");

module_param(tx_only, bool, 0644);
MODULE_PARM_DESC(tx_only, "Only handle the IR transmit function");
