/*
 * 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;

struct IR_rx {
	struct kref ref;
	struct IR *ir;

	/* RX device */
	struct mutex client_lock;
	struct i2c_client *c;

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

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

struct IR_tx {
	struct kref ref;
	struct IR *ir;

	/* TX device */
	struct mutex client_lock;
	struct i2c_client *c;

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

struct IR {
	struct kref ref;
	struct list_head list;

	/* FIXME spinlock access to l.features */
	struct lirc_driver l;
	struct lirc_buffer rbuf;

	struct mutex ir_lock;
	atomic_t open_count;

	struct i2c_adapter *adapter;

	spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
	struct IR_rx *rx;

	spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
	struct IR_tx *tx;
};

/* IR transceiver instance object list */
/*
 * This lock is used for the following:
 * a. ir_devices_list access, insertions, deletions
 * b. struct IR kref get()s and put()s
 * c. serialization of ir_probe() for the two i2c_clients for a Z8
 */
static DEFINE_MUTEX(ir_devices_lock);
static LIST_HEAD(ir_devices_list);

/* 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)


/* struct IR reference counting */
static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
{
	if (ir_devices_lock_held) {
		kref_get(&ir->ref);
	} else {
		mutex_lock(&ir_devices_lock);
		kref_get(&ir->ref);
		mutex_unlock(&ir_devices_lock);
	}
	return ir;
}

static void release_ir_device(struct kref *ref)
{
	struct IR *ir = container_of(ref, struct IR, ref);

	/*
	 * Things should be in this state by now:
	 * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
	 * ir->rx->task kthread stopped - happens before ir->rx->ir put()
	 * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
	 * ir->open_count ==  0 - happens on final close()
	 * ir_lock, tx_ref_lock, rx_ref_lock, all released
	 */
	if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) {
		lirc_unregister_driver(ir->l.minor);
		ir->l.minor = MAX_IRCTL_DEVICES;
	}
	if (ir->rbuf.fifo_initialized)
		lirc_buffer_free(&ir->rbuf);
	list_del(&ir->list);
	kfree(ir);
}

static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
{
	int released;

	if (ir_devices_lock_held)
		return kref_put(&ir->ref, release_ir_device);

	mutex_lock(&ir_devices_lock);
	released = kref_put(&ir->ref, release_ir_device);
	mutex_unlock(&ir_devices_lock);

	return released;
}

/* struct IR_rx reference counting */
static struct IR_rx *get_ir_rx(struct IR *ir)
{
	struct IR_rx *rx;

	spin_lock(&ir->rx_ref_lock);
	rx = ir->rx;
	if (rx != NULL)
		kref_get(&rx->ref);
	spin_unlock(&ir->rx_ref_lock);
	return rx;
}

static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
{
	/* end up polling thread */
	if (!IS_ERR_OR_NULL(rx->task)) {
		kthread_stop(rx->task);
		rx->task = NULL;
		/* Put the ir ptr that ir_probe() gave to the rx poll thread */
		put_ir_device(rx->ir, ir_devices_lock_held);
	}
}

static void release_ir_rx(struct kref *ref)
{
	struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
	struct IR *ir = rx->ir;

	/*
	 * This release function can't do all the work, as we want
	 * to keep the rx_ref_lock a spinlock, and killing the poll thread
	 * and releasing the ir reference can cause a sleep.  That work is
	 * performed by put_ir_rx()
	 */
	ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
	/* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
	ir->rx = NULL;
	/* Don't do the kfree(rx) here; we still need to kill the poll thread */
	return;
}

static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
{
	int released;
	struct IR *ir = rx->ir;

	spin_lock(&ir->rx_ref_lock);
	released = kref_put(&rx->ref, release_ir_rx);
	spin_unlock(&ir->rx_ref_lock);
	/* Destroy the rx kthread while not holding the spinlock */
	if (released) {
		destroy_rx_kthread(rx, ir_devices_lock_held);
		kfree(rx);
		/* Make sure we're not still in a poll_table somewhere */
		wake_up_interruptible(&ir->rbuf.wait_poll);
	}
	/* Do a reference put() for the rx->ir reference, if we released rx */
	if (released)
		put_ir_device(ir, ir_devices_lock_held);
	return released;
}

/* struct IR_tx reference counting */
static struct IR_tx *get_ir_tx(struct IR *ir)
{
	struct IR_tx *tx;

	spin_lock(&ir->tx_ref_lock);
	tx = ir->tx;
	if (tx != NULL)
		kref_get(&tx->ref);
	spin_unlock(&ir->tx_ref_lock);
	return tx;
}

static void release_ir_tx(struct kref *ref)
{
	struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
	struct IR *ir = tx->ir;

	ir->l.features &= ~LIRC_CAN_SEND_PULSE;
	/* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
	ir->tx = NULL;
	kfree(tx);
}

static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
{
	int released;
	struct IR *ir = tx->ir;

	spin_lock(&ir->tx_ref_lock);
	released = kref_put(&tx->ref, release_ir_tx);
	spin_unlock(&ir->tx_ref_lock);
	/* Do a reference put() for the tx->ir reference, if we released tx */
	if (released)
		put_ir_device(ir, ir_devices_lock_held);
	return released;
}

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 lirc_buffer *rbuf = ir->l.rbuf;
	struct IR_rx *rx;
	struct IR_tx *tx;

	if (lirc_buffer_full(rbuf)) {
		dprintk("buffer overflow\n");
		return -EOVERFLOW;
	}

	rx = get_ir_rx(ir);
	if (rx == NULL)
		return -ENXIO;

	/* Ensure our rx->c i2c_client remains valid for the duration */
	mutex_lock(&rx->client_lock);
	if (rx->c == NULL) {
		mutex_unlock(&rx->client_lock);
		put_ir_rx(rx, false);
		return -ENXIO;
	}

	tx = get_ir_tx(ir);

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

		/*
		 * 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);
			ret = -ENODATA;
			break;
		}

		/*
		 * 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");
				break;
			}

			/* 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);
				ret = -ENODATA;
				break;
			}
			schedule_timeout((100 * HZ + 999) / 1000);
			if (tx != NULL)
				tx->need_boot = 1;

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

		if (kthread_should_stop()) {
			mutex_unlock(&ir->ir_lock);
			ret = -ENODATA;
			break;
		}
		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)) {
				ret = 0;
				break;
			} else if (got_data && (keybuf[0] == 0x00)) {
				ret = -ENODATA;
				break;
			}
		} else if ((rx->b[0] & 0x80) == 0) {
			ret = got_data ? 0 : -ENODATA;
			break;
		}

		/* 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(rbuf, codes);
		++got_data;
		ret = 0;
	} while (!lirc_buffer_full(rbuf));

	mutex_unlock(&rx->client_lock);
	if (tx != NULL)
		put_ir_tx(tx, false);
	put_ir_rx(rx, false);
	return ret;
}

/*
 * 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 lirc_buffer *rbuf = ir->l.rbuf;

	dprintk("poll thread started\n");

	while (!kthread_should_stop()) {
		/* if device not opened, we can sleep half a second */
		if (atomic_read(&ir->open_count) == 0) {
			schedule_timeout(HZ/2);
			continue;
		}

		set_current_state(TASK_INTERRUPTIBLE);

		/*
		 * 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(&rbuf->wait_poll);
	}

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

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

static void set_use_dec(void *data)
{
	return;
}

/* 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->ir->l.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;
}

/* 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;
	struct lirc_buffer *rbuf = ir->l.rbuf;
	int ret = 0, written = 0, retries = 0;
	unsigned int m;
	DECLARE_WAITQUEUE(wait, current);

	dprintk("read called\n");
	if (n % rbuf->chunk_size) {
		dprintk("read result = -EINVAL\n");
		return -EINVAL;
	}

	rx = get_ir_rx(ir);
	if (rx == NULL)
		return -ENXIO;

	/*
	 * 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(&rbuf->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(rbuf)) {
			/*
			 * 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[rbuf->chunk_size];
			m = lirc_buffer_read(rbuf, buf);
			if (m == rbuf->chunk_size) {
				ret = copy_to_user((void *)outbuf+written, buf,
						   rbuf->chunk_size);
				written += rbuf->chunk_size;
			} else {
				retries++;
			}
			if (retries >= 5) {
				zilog_error("Buffer read failed!\n");
				ret = -EIO;
			}
		}
	}

	remove_wait_queue(&rbuf->wait_poll, &wait);
	put_ir_rx(rx, false);
	set_current_state(TASK_RUNNING);

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

	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;
	size_t i;
	int failures = 0;

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

	/* Get a struct IR_tx reference */
	tx = get_ir_tx(ir);
	if (tx == NULL)
		return -ENXIO;

	/* Ensure our tx->c i2c_client remains valid for the duration */
	mutex_lock(&tx->client_lock);
	if (tx->c == NULL) {
		mutex_unlock(&tx->client_lock);
		put_ir_tx(tx, false);
		return -ENXIO;
	}

	/* 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);
			mutex_unlock(&tx->client_lock);
			put_ir_tx(tx, false);
			return -EFAULT;
		}

		/* Send boot data first if required */
		if (tx->need_boot == 1) {
			/* Make sure we have the 'firmware' loaded, first */
			ret = fw_load(tx);
			if (ret != 0) {
				mutex_unlock(&ir->ir_lock);
				mutex_unlock(&tx->client_lock);
				put_ir_tx(tx, false);
				if (ret != -ENOMEM)
					ret = -EIO;
				return ret;
			}
			/* Prep the chip for transmitting codes */
			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);
				mutex_unlock(&tx->client_lock);
				put_ir_tx(tx, false);
				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);
				mutex_unlock(&tx->client_lock);
				put_ir_tx(tx, false);
				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);

	mutex_unlock(&tx->client_lock);

	/* Give back our struct IR_tx reference */
	put_ir_tx(tx, false);

	/* 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;
	struct lirc_buffer *rbuf = ir->l.rbuf;
	unsigned int ret;

	dprintk("poll called\n");

	rx = get_ir_rx(ir);
	if (rx == NULL) {
		/*
		 * Revisit this, if our poll function ever reports writeable
		 * status for Tx
		 */
		dprintk("poll result = POLLERR\n");
		return POLLERR;
	}

	/*
	 * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
	 * that buffer's wait queue indicates we may have a new poll status.
	 */
	poll_wait(filep, &rbuf->wait_poll, wait);

	/* Indicate what ops could happen immediately without blocking */
	ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM);

	dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none");
	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;

	features = ir->l.features;

	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:
		if (!(features&LIRC_CAN_SEND_MASK))
			return -ENOSYS;

		result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
		break;
	case LIRC_SET_SEND_MODE:
		if (!(features&LIRC_CAN_SEND_MASK))
			return -ENOSYS;

		result = get_user(mode, (unsigned long *) arg);
		if (!result && mode != LIRC_MODE_PULSE)
			return -EINVAL;
		break;
	default:
		return -EINVAL;
	}
	return result;
}

static struct IR *get_ir_device_by_minor(unsigned int minor)
{
	struct IR *ir;
	struct IR *ret = NULL;

	mutex_lock(&ir_devices_lock);

	if (!list_empty(&ir_devices_list)) {
		list_for_each_entry(ir, &ir_devices_list, list) {
			if (ir->l.minor == minor) {
				ret = get_ir_device(ir, true);
				break;
			}
		}
	}

	mutex_unlock(&ir_devices_lock);
	return ret;
}

/*
 * 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;
	unsigned int minor = MINOR(node->i_rdev);

	/* find our IR struct */
	ir = get_ir_device_by_minor(minor);

	if (ir == NULL)
		return -ENODEV;

	atomic_inc(&ir->open_count);

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

	nonseekable_open(node, filep);
	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;
	}

	atomic_dec(&ir->open_count);

	put_ir_device(ir, false);
	return 0;
}

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		= no_llseek,
	.read		= read,
	.write		= write,
	.poll		= poll,
	.unlocked_ioctl	= ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= ioctl,
#endif
	.open		= open,
	.release	= close
};

static struct lirc_driver lirc_template = {
	.name		= "lirc_zilog",
	.minor		= -1,
	.code_length	= 13,
	.buffer_size	= BUFLEN / 2,
	.sample_rate	= 0, /* tell lirc_dev to not start its own kthread */
	.chunk_size	= 2,
	.set_use_inc	= set_use_inc,
	.set_use_dec	= set_use_dec,
	.fops		= &lirc_fops,
	.owner		= THIS_MODULE,
};

static int ir_remove(struct i2c_client *client)
{
	if (strncmp("ir_tx_z8", client->name, 8) == 0) {
		struct IR_tx *tx = i2c_get_clientdata(client);
		if (tx != NULL) {
			mutex_lock(&tx->client_lock);
			tx->c = NULL;
			mutex_unlock(&tx->client_lock);
			put_ir_tx(tx, false);
		}
	} else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
		struct IR_rx *rx = i2c_get_clientdata(client);
		if (rx != NULL) {
			mutex_lock(&rx->client_lock);
			rx->c = NULL;
			mutex_unlock(&rx->client_lock);
			put_ir_rx(rx, false);
		}
	}
	return 0;
}


/* ir_devices_lock must be held */
static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
{
	struct IR *ir;

	if (list_empty(&ir_devices_list))
		return NULL;

	list_for_each_entry(ir, &ir_devices_list, list)
		if (ir->adapter == adapter) {
			get_ir_device(ir, true);
			return ir;
		}

	return NULL;
}

static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct IR *ir;
	struct IR_tx *tx;
	struct IR_rx *rx;
	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 = get_ir_device_by_adapter(adap);
	if (ir == NULL) {
		ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
		if (ir == NULL) {
			ret = -ENOMEM;
			goto out_no_ir;
		}
		kref_init(&ir->ref);

		/* store for use in ir_probe() again, and open() later on */
		INIT_LIST_HEAD(&ir->list);
		list_add_tail(&ir->list, &ir_devices_list);

		ir->adapter = adap;
		mutex_init(&ir->ir_lock);
		atomic_set(&ir->open_count, 0);
		spin_lock_init(&ir->tx_ref_lock);
		spin_lock_init(&ir->rx_ref_lock);

		/* set lirc_dev stuff */
		memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
		/*
		 * FIXME this is a pointer reference to us, but no refcount.
		 *
		 * This OK for now, since lirc_dev currently won't touch this
		 * buffer as we provide our own lirc_fops.
		 *
		 * Currently our own lirc_fops rely on this ir->l.rbuf pointer
		 */
		ir->l.rbuf = &ir->rbuf;
		ir->l.dev  = &adap->dev;
		ret = lirc_buffer_init(ir->l.rbuf,
				       ir->l.chunk_size, ir->l.buffer_size);
		if (ret)
			goto out_put_ir;
	}

	if (tx_probe) {
		/* Get the IR_rx instance for later, if already allocated */
		rx = get_ir_rx(ir);

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

		ir->l.features |= LIRC_CAN_SEND_PULSE;
		mutex_init(&tx->client_lock);
		tx->c = client;
		tx->need_boot = 1;
		tx->post_tx_ready_poll =
			       (id->driver_data & ID_FLAG_HDPVR) ? false : true;

		/* An ir ref goes to the struct IR_tx instance */
		tx->ir = get_ir_device(ir, true);

		/* A tx ref goes to the i2c_client */
		i2c_set_clientdata(client, get_ir_tx(ir));

		/*
		 * Load the 'firmware'.  We do this before registering with
		 * lirc_dev, so the first firmware load attempt does not happen
		 * after a open() or write() call on the device.
		 *
		 * Failure here is not deemed catastrophic, so the receiver will
		 * still be usable.  Firmware load will be retried in write(),
		 * if it is needed.
		 */
		fw_load(tx);

		/* Proceed only if the Rx client is also ready or not needed */
		if (rx == NULL && !tx_only) {
			zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting"
				   " on IR Rx.\n", adap->name, adap->nr);
			goto out_ok;
		}
	} else {
		/* Get the IR_tx instance for later, if already allocated */
		tx = get_ir_tx(ir);

		/* Set up a struct IR_rx instance */
		rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
		if (rx == NULL) {
			ret = -ENOMEM;
			goto out_put_xx;
		}
		kref_init(&rx->ref);
		ir->rx = rx;

		ir->l.features |= LIRC_CAN_REC_LIRCCODE;
		mutex_init(&rx->client_lock);
		rx->c = client;
		rx->hdpvr_data_fmt =
			       (id->driver_data & ID_FLAG_HDPVR) ? true : false;

		/* An ir ref goes to the struct IR_rx instance */
		rx->ir = get_ir_device(ir, true);

		/* An rx ref goes to the i2c_client */
		i2c_set_clientdata(client, get_ir_rx(ir));

		/*
		 * Start the polling thread.
		 * It will only perform an empty loop around schedule_timeout()
		 * until we register with lirc_dev and the first user open()
		 */
		/* An ir ref goes to the new rx polling kthread */
		rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
				       "zilog-rx-i2c-%d", adap->nr);
		if (IS_ERR(rx->task)) {
			ret = PTR_ERR(rx->task);
			zilog_error("%s: could not start IR Rx polling thread"
				    "\n", __func__);
			/* Failed kthread, so put back the ir ref */
			put_ir_device(ir, true);
			/* Failure exit, so put back rx ref from i2c_client */
			i2c_set_clientdata(client, NULL);
			put_ir_rx(rx, true);
			ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
			goto out_put_xx;
		}

		/* Proceed only if the Tx client is also ready */
		if (tx == NULL) {
			zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting"
				   " on IR Tx.\n", adap->name, adap->nr);
			goto out_ok;
		}
	}

	/* register with lirc */
	ir->l.minor = minor; /* module option: user requested minor number */
	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_put_xx;
	}
	zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
		   adap->name, adap->nr, ir->l.minor);

out_ok:
	if (rx != NULL)
		put_ir_rx(rx, true);
	if (tx != NULL)
		put_ir_tx(tx, true);
	put_ir_device(ir, true);
	zilog_info("probe of IR %s on %s (i2c-%d) done\n",
		   tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
	mutex_unlock(&ir_devices_lock);
	return 0;

out_put_xx:
	if (rx != NULL)
		put_ir_rx(rx, true);
	if (tx != NULL)
		put_ir_tx(tx, true);
out_put_ir:
	put_ir_device(ir, true);
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);

	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");
