/*
 *
 * keyboard input driver for i2c IR remote controls
 *
 * Copyright (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
 * 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 em2820 based USB TV tuners by
 *      Markus Rechberger <mrechberger@gmail.com>
 * modified for DViCO Fusion HDTV 5 RT GOLD by
 *      Chaogui Zhang <czhang1974@gmail.com>
 * modified for MSI TV@nywhere Plus by
 *      Henry Wong <henry@stuffedcow.net>
 *      Mark Schultz <n9xmj@yahoo.com>
 *      Brian Rogers <brian_rogers@comcast.net>
 * modified for AVerMedia Cardbus by
 *      Oldrich Jedlicka <oldium.pro@seznam.cz>
 * Zilog Transmitter portions/ideas were derived from GPLv2+ sources:
 *  - drivers/char/pctv_zilogir.[ch] from Hauppauge Broadway product
 *	Copyright 2011 Hauppauge Computer works
 *  - drivers/staging/media/lirc/lirc_zilog.c
 *	Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
 *	Michal Kochanowicz <mkochano@pld.org.pl>
 *	Christoph Bartelmus <lirc@bartelmus.de>
 *	Ulrich Mueller <ulrich.mueller42@web.de>
 *	Stefan Jahn <stefan@lkcc.org>
 *	Jerome Brock <jbrock@users.sourceforge.net>
 *	Thomas Reitmayr (treitmayr@yahoo.com)
 *	Mark Weaver <mark@npsl.co.uk>
 *	Jarod Wilson <jarod@redhat.com>
 *	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.
 *
 */

#include <asm/unaligned.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>

#include <media/rc-core.h>
#include <media/i2c/ir-kbd-i2c.h>

#define FLAG_TX		1
#define FLAG_HDPVR	2

static bool enable_hdpvr;
module_param(enable_hdpvr, bool, 0644);

static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
			       u32 *scancode, u8 *ptoggle, int size)
{
	unsigned char buf[6];
	int start, range, toggle, dev, code, ircode, vendor;

	/* poll IR chip */
	if (size != i2c_master_recv(ir->c, buf, size))
		return -EIO;

	if (buf[0] & 0x80) {
		int offset = (size == 6) ? 3 : 0;

		/* split rc5 data block ... */
		start  = (buf[offset] >> 7) &    1;
		range  = (buf[offset] >> 6) &    1;
		toggle = (buf[offset] >> 5) &    1;
		dev    =  buf[offset]       & 0x1f;
		code   = (buf[offset+1] >> 2) & 0x3f;

		/* rc5 has two start bits
		 * the first bit must be one
		 * the second bit defines the command range:
		 * 1 = 0-63, 0 = 64 - 127
		 */
		if (!start)
			/* no key pressed */
			return 0;

		/* filter out invalid key presses */
		ircode = (start << 12) | (toggle << 11) | (dev << 6) | code;
		if ((ircode & 0x1fff) == 0x1fff)
			return 0;

		if (!range)
			code += 64;

		dev_dbg(&ir->rc->dev,
			"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
			start, range, toggle, dev, code);

		*protocol = RC_PROTO_RC5;
		*scancode = RC_SCANCODE_RC5(dev, code);
		*ptoggle = toggle;

		return 1;
	} else if (size == 6 && (buf[0] & 0x40)) {
		code = buf[4];
		dev = buf[3];
		vendor = get_unaligned_be16(buf + 1);

		if (vendor == 0x800f) {
			*ptoggle = (dev & 0x80) != 0;
			*protocol = RC_PROTO_RC6_MCE;
			dev &= 0x7f;
			dev_dbg(&ir->rc->dev,
				"ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n",
				*ptoggle, vendor, dev, code);
		} else {
			*ptoggle = 0;
			*protocol = RC_PROTO_RC6_6A_32;
			dev_dbg(&ir->rc->dev,
				"ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n",
				vendor, dev, code);
		}

		*scancode = RC_SCANCODE_RC6_6A(vendor, dev, code);

		return 1;
	}

	return 0;
}

static int get_key_haup(struct IR_i2c *ir, enum rc_proto *protocol,
			u32 *scancode, u8 *toggle)
{
	return get_key_haup_common(ir, protocol, scancode, toggle, 3);
}

static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_proto *protocol,
			    u32 *scancode, u8 *toggle)
{
	int ret;
	unsigned char buf[1] = { 0 };

	/*
	 * This is the same apparent "are you ready?" poll command observed
	 * watching Windows driver traffic and implemented in lirc_zilog. With
	 * this added, we get far saner remote behavior with z8 chips on usb
	 * connected devices, even with the default polling interval of 100ms.
	 */
	ret = i2c_master_send(ir->c, buf, 1);
	if (ret != 1)
		return (ret < 0) ? ret : -EINVAL;

	return get_key_haup_common(ir, protocol, scancode, toggle, 6);
}

static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol,
			     u32 *scancode, u8 *toggle)
{
	int rc;
	unsigned char b;

	/* poll IR chip */
	rc = i2c_master_recv(ir->c, &b, 1);
	if (rc != 1) {
		dev_dbg(&ir->rc->dev, "read error\n");
		if (rc < 0)
			return rc;
		return -EIO;
	}

	*protocol = RC_PROTO_OTHER;
	*scancode = b;
	*toggle = 0;
	return 1;
}

static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol,
			      u32 *scancode, u8 *toggle)
{
	int rc;
	unsigned char buf[4];

	/* poll IR chip */
	rc = i2c_master_recv(ir->c, buf, 4);
	if (rc != 4) {
		dev_dbg(&ir->rc->dev, "read error\n");
		if (rc < 0)
			return rc;
		return -EIO;
	}

	if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0 || buf[3] != 0)
		dev_dbg(&ir->rc->dev, "%s: %*ph\n", __func__, 4, buf);

	/* no key pressed or signal from other ir remote */
	if(buf[0] != 0x1 ||  buf[1] != 0xfe)
		return 0;

	*protocol = RC_PROTO_UNKNOWN;
	*scancode = buf[2];
	*toggle = 0;
	return 1;
}

static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
			u32 *scancode, u8 *toggle)
{
	int rc;
	unsigned char b;

	/* poll IR chip */
	rc = i2c_master_recv(ir->c, &b, 1);
	if (rc != 1) {
		dev_dbg(&ir->rc->dev, "read error\n");
		if (rc < 0)
			return rc;
		return -EIO;
	}

	/* it seems that 0xFE indicates that a button is still hold
	   down, while 0xff indicates that no button is hold
	   down. 0xfe sequences are sometimes interrupted by 0xFF */

	dev_dbg(&ir->rc->dev, "key %02x\n", b);

	if (b == 0xff)
		return 0;

	if (b == 0xfe)
		/* keep old data */
		return 1;

	*protocol = RC_PROTO_UNKNOWN;
	*scancode = b;
	*toggle = 0;
	return 1;
}

static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
				     u32 *scancode, u8 *toggle)
{
	unsigned char subaddr, key, keygroup;
	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
				   .buf = &subaddr, .len = 1},
				 { .addr = ir->c->addr, .flags = I2C_M_RD,
				  .buf = &key, .len = 1} };
	subaddr = 0x0d;
	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
		dev_dbg(&ir->rc->dev, "read error\n");
		return -EIO;
	}

	if (key == 0xff)
		return 0;

	subaddr = 0x0b;
	msg[1].buf = &keygroup;
	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
		dev_dbg(&ir->rc->dev, "read error\n");
		return -EIO;
	}

	if (keygroup == 0xff)
		return 0;

	dev_dbg(&ir->rc->dev, "read key 0x%02x/0x%02x\n", key, keygroup);
	if (keygroup < 2 || keygroup > 4) {
		dev_warn(&ir->rc->dev, "warning: invalid key group 0x%02x for key 0x%02x\n",
			 keygroup, key);
	}
	key |= (keygroup & 1) << 6;

	*protocol = RC_PROTO_UNKNOWN;
	*scancode = key;
	if (ir->c->addr == 0x41) /* AVerMedia EM78P153 */
		*scancode |= keygroup << 8;
	*toggle = 0;
	return 1;
}

/* ----------------------------------------------------------------------- */

static int ir_key_poll(struct IR_i2c *ir)
{
	enum rc_proto protocol;
	u32 scancode;
	u8 toggle;
	int rc;

	dev_dbg(&ir->rc->dev, "%s\n", __func__);
	rc = ir->get_key(ir, &protocol, &scancode, &toggle);
	if (rc < 0) {
		dev_warn(&ir->rc->dev, "error %d\n", rc);
		return rc;
	}

	if (rc) {
		dev_dbg(&ir->rc->dev, "%s: proto = 0x%04x, scancode = 0x%08x\n",
			__func__, protocol, scancode);
		rc_keydown(ir->rc, protocol, scancode, toggle);
	}
	return 0;
}

static void ir_work(struct work_struct *work)
{
	int rc;
	struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);

	/*
	 * If the transmit code is holding the lock, skip polling for
	 * IR, we'll get it to it next time round
	 */
	if (mutex_trylock(&ir->lock)) {
		rc = ir_key_poll(ir);
		mutex_unlock(&ir->lock);
		if (rc == -ENODEV) {
			rc_unregister_device(ir->rc);
			ir->rc = NULL;
			return;
		}
	}

	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval));
}

static int ir_open(struct rc_dev *dev)
{
	struct IR_i2c *ir = dev->priv;

	schedule_delayed_work(&ir->work, 0);

	return 0;
}

static void ir_close(struct rc_dev *dev)
{
	struct IR_i2c *ir = dev->priv;

	cancel_delayed_work_sync(&ir->work);
}

/* Zilog Transmit Interface */
#define XTAL_FREQ		18432000

#define ZILOG_SEND		0x80
#define ZILOG_UIR_END		0x40
#define ZILOG_INIT_END		0x20
#define ZILOG_LIR_END		0x10

#define ZILOG_STATUS_OK		0x80
#define ZILOG_STATUS_TX		0x40
#define ZILOG_STATUS_SET	0x20

/*
 * As you can see here, very few different lengths of pulse and space
 * can be encoded. This means that the hardware does not work well with
 * recorded IR. It's best to work with generated IR, like from ir-ctl or
 * the in-kernel encoders.
 */
struct code_block {
	u8	length;
	u16	pulse[7];	/* not aligned */
	u8	carrier_pulse;
	u8	carrier_space;
	u16	space[8];	/* not aligned */
	u8	codes[61];
	u8	csum[2];
} __packed;

static int send_data_block(struct IR_i2c *ir, int cmd,
			   struct code_block *code_block)
{
	int i, j, ret;
	u8 buf[5], *p;

	p = &code_block->length;
	for (i = 0; p < code_block->csum; i++)
		code_block->csum[i & 1] ^= *p++;

	p = &code_block->length;

	for (i = 0; i < sizeof(*code_block);) {
		int tosend = sizeof(*code_block) - i;

		if (tosend > 4)
			tosend = 4;
		buf[0] = i + 1;
		for (j = 0; j < tosend; ++j)
			buf[1 + j] = p[i + j];
		dev_dbg(&ir->rc->dev, "%*ph", tosend + 1, buf);
		ret = i2c_master_send(ir->tx_c, buf, tosend + 1);
		if (ret != tosend + 1) {
			dev_dbg(&ir->rc->dev,
				"i2c_master_send failed with %d\n", ret);
			return ret < 0 ? ret : -EIO;
		}
		i += tosend;
	}

	buf[0] = 0;
	buf[1] = cmd;
	ret = i2c_master_send(ir->tx_c, buf, 2);
	if (ret != 2) {
		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EIO;
	}

	usleep_range(2000, 5000);

	ret = i2c_master_send(ir->tx_c, buf, 1);
	if (ret != 1) {
		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
		return ret < 0 ? ret : -EIO;
	}

	return 0;
}

static int zilog_init(struct IR_i2c *ir)
{
	struct code_block code_block = { .length = sizeof(code_block) };
	u8 buf[4];
	int ret;

	put_unaligned_be16(0x1000, &code_block.pulse[3]);

	ret = send_data_block(ir, ZILOG_INIT_END, &code_block);
	if (ret)
		return ret;

	ret = i2c_master_recv(ir->tx_c, buf, 4);
	if (ret != 4) {
		dev_err(&ir->c->dev, "failed to retrieve firmware version: %d\n",
			ret);
		return ret < 0 ? ret : -EIO;
	}

	dev_info(&ir->c->dev, "Zilog/Hauppauge IR blaster firmware version %d.%d.%d\n",
		 buf[1], buf[2], buf[3]);

	return 0;
}

/*
 * If the last slot for pulse is the same as the current slot for pulse,
 * then use slot no 7.
 */
static void copy_codes(u8 *dst, u8 *src, unsigned int count)
{
	u8 c, last = 0xff;

	while (count--) {
		c = *src++;
		if ((c & 0xf0) == last) {
			*dst++ = 0x70 | (c & 0xf);
		} else {
			*dst++ = c;
			last = c & 0xf0;
		}
	}
}

/*
 * When looking for repeats, we don't care about the trailing space. This
 * is set to the shortest possible anyway.
 */
static int cmp_no_trail(u8 *a, u8 *b, unsigned int count)
{
	while (--count) {
		if (*a++ != *b++)
			return 1;
	}

	return (*a & 0xf0) - (*b & 0xf0);
}

static int find_slot(u16 *array, unsigned int size, u16 val)
{
	int i;

	for (i = 0; i < size; i++) {
		if (get_unaligned_be16(&array[i]) == val) {
			return i;
		} else if (!array[i]) {
			put_unaligned_be16(val, &array[i]);
			return i;
		}
	}

	return -1;
}

static int zilog_ir_format(struct rc_dev *rcdev, unsigned int *txbuf,
			   unsigned int count, struct code_block *code_block)
{
	struct IR_i2c *ir = rcdev->priv;
	int rep, i, l, p = 0, s, c = 0;
	bool repeating;
	u8 codes[174];

	code_block->carrier_pulse = DIV_ROUND_CLOSEST(
			ir->duty_cycle * XTAL_FREQ / 1000, ir->carrier);
	code_block->carrier_space = DIV_ROUND_CLOSEST(
			(100 - ir->duty_cycle) * XTAL_FREQ / 1000, ir->carrier);

	for (i = 0; i < count; i++) {
		if (c >= ARRAY_SIZE(codes) - 1) {
			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
			return -EINVAL;
		}

		/*
		 * Lengths more than 142220us cannot be encoded; also
		 * this checks for multiply overflow
		 */
		if (txbuf[i] > 142220)
			return -EINVAL;

		l = DIV_ROUND_CLOSEST((XTAL_FREQ / 1000) * txbuf[i], 40000);

		if (i & 1) {
			s = find_slot(code_block->space,
				      ARRAY_SIZE(code_block->space), l);
			if (s == -1) {
				dev_warn(&rcdev->dev, "Too many different lengths spaces, cannot transmit");
				return -EINVAL;
			}

			/* We have a pulse and space */
			codes[c++] = (p << 4) | s;
		} else {
			p = find_slot(code_block->pulse,
				      ARRAY_SIZE(code_block->pulse), l);
			if (p == -1) {
				dev_warn(&rcdev->dev, "Too many different lengths pulses, cannot transmit");
				return -EINVAL;
			}
		}
	}

	/* We have to encode the trailing pulse. Find the shortest space */
	s = 0;
	for (i = 1; i < ARRAY_SIZE(code_block->space); i++) {
		u16 d = get_unaligned_be16(&code_block->space[i]);

		if (get_unaligned_be16(&code_block->space[s]) > d)
			s = i;
	}

	codes[c++] = (p << 4) | s;

	dev_dbg(&rcdev->dev, "generated %d codes\n", c);

	/*
	 * Are the last N codes (so pulse + space) repeating 3 times?
	 * if so we can shorten the codes list and use code 0xc0 to repeat
	 * them.
	 */
	repeating = false;

	for (rep = c / 3; rep >= 1; rep--) {
		if (!memcmp(&codes[c - rep * 3], &codes[c - rep * 2], rep) &&
		    !cmp_no_trail(&codes[c - rep], &codes[c - rep * 2], rep)) {
			repeating = true;
			break;
		}
	}

	if (repeating) {
		/* first copy any leading non-repeating */
		int leading = c - rep * 3;

		if (leading >= ARRAY_SIZE(code_block->codes) - 3 - rep) {
			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
			return -EINVAL;
		}

		dev_dbg(&rcdev->dev, "found trailing %d repeat\n", rep);
		copy_codes(code_block->codes, codes, leading);
		code_block->codes[leading] = 0x82;
		copy_codes(code_block->codes + leading + 1, codes + leading,
			   rep);
		c = leading + 1 + rep;
		code_block->codes[c++] = 0xc0;
	} else {
		if (c >= ARRAY_SIZE(code_block->codes) - 3) {
			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
			return -EINVAL;
		}

		dev_dbg(&rcdev->dev, "found no trailing repeat\n");
		code_block->codes[0] = 0x82;
		copy_codes(code_block->codes + 1, codes, c);
		c++;
		code_block->codes[c++] = 0xc4;
	}

	while (c < ARRAY_SIZE(code_block->codes))
		code_block->codes[c++] = 0x83;

	return 0;
}

static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf,
		    unsigned int count)
{
	struct IR_i2c *ir = rcdev->priv;
	struct code_block code_block = { .length = sizeof(code_block) };
	u8 buf[2];
	int ret, i;

	ret = zilog_ir_format(rcdev, txbuf, count, &code_block);
	if (ret)
		return ret;

	ret = mutex_lock_interruptible(&ir->lock);
	if (ret)
		return ret;

	ret = send_data_block(ir, ZILOG_UIR_END, &code_block);
	if (ret)
		goto out_unlock;

	ret = i2c_master_recv(ir->tx_c, buf, 1);
	if (ret != 1) {
		dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
		goto out_unlock;
	}

	dev_dbg(&ir->rc->dev, "code set status: %02x\n", buf[0]);

	if (buf[0] != (ZILOG_STATUS_OK | ZILOG_STATUS_SET)) {
		dev_err(&ir->rc->dev, "unexpected IR TX response %02x\n",
			buf[0]);
		ret = -EIO;
		goto out_unlock;
	}

	buf[0] = 0x00;
	buf[1] = ZILOG_SEND;

	ret = i2c_master_send(ir->tx_c, buf, 2);
	if (ret != 2) {
		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
		if (ret >= 0)
			ret = -EIO;
		goto out_unlock;
	}

	dev_dbg(&ir->rc->dev, "send command sent\n");

	/*
	 * 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(msecs_to_jiffies(50));
		ret = i2c_master_send(ir->tx_c, buf, 1);
		if (ret == 1)
			break;
		dev_dbg(&ir->rc->dev,
			"NAK expected: i2c_master_send failed with %d (try %d)\n",
			ret, i + 1);
	}

	if (ret != 1) {
		dev_err(&ir->rc->dev,
			"IR TX chip never got ready: last i2c_master_send failed with %d\n",
			ret);
		if (ret >= 0)
			ret = -EIO;
		goto out_unlock;
	}

	i = i2c_master_recv(ir->tx_c, buf, 1);
	if (i != 1) {
		dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
		ret = -EIO;
		goto out_unlock;
	} else if (buf[0] != ZILOG_STATUS_OK) {
		dev_err(&ir->rc->dev, "unexpected IR TX response #2: %02x\n",
			buf[0]);
		ret = -EIO;
		goto out_unlock;
	}
	dev_dbg(&ir->rc->dev, "transmit complete\n");

	/* Oh good, it worked */
	ret = count;
out_unlock:
	mutex_unlock(&ir->lock);

	return ret;
}

static int zilog_tx_carrier(struct rc_dev *dev, u32 carrier)
{
	struct IR_i2c *ir = dev->priv;

	if (carrier > 500000 || carrier < 20000)
		return -EINVAL;

	ir->carrier = carrier;

	return 0;
}

static int zilog_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
{
	struct IR_i2c *ir = dev->priv;

	ir->duty_cycle = duty_cycle;

	return 0;
}

static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	char *ir_codes = NULL;
	const char *name = NULL;
	u64 rc_proto = RC_PROTO_BIT_UNKNOWN;
	struct IR_i2c *ir;
	struct rc_dev *rc = NULL;
	struct i2c_adapter *adap = client->adapter;
	unsigned short addr = client->addr;
	bool probe_tx = (id->driver_data & FLAG_TX) != 0;
	int err;

	if ((id->driver_data & FLAG_HDPVR) && !enable_hdpvr) {
		dev_err(&client->dev, "IR for HDPVR is known to cause problems during recording, use enable_hdpvr modparam to enable\n");
		return -ENODEV;
	}

	ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	ir->c = client;
	ir->polling_interval = DEFAULT_POLLING_INTERVAL;
	i2c_set_clientdata(client, ir);

	switch(addr) {
	case 0x64:
		name        = "Pixelview";
		ir->get_key = get_key_pixelview;
		rc_proto    = RC_PROTO_BIT_OTHER;
		ir_codes    = RC_MAP_EMPTY;
		break;
	case 0x18:
	case 0x1f:
	case 0x1a:
		name        = "Hauppauge";
		ir->get_key = get_key_haup;
		rc_proto    = RC_PROTO_BIT_RC5;
		ir_codes    = RC_MAP_HAUPPAUGE;
		break;
	case 0x30:
		name        = "KNC One";
		ir->get_key = get_key_knc1;
		rc_proto    = RC_PROTO_BIT_OTHER;
		ir_codes    = RC_MAP_EMPTY;
		break;
	case 0x6b:
		name        = "FusionHDTV";
		ir->get_key = get_key_fusionhdtv;
		rc_proto    = RC_PROTO_BIT_UNKNOWN;
		ir_codes    = RC_MAP_FUSIONHDTV_MCE;
		break;
	case 0x40:
		name        = "AVerMedia Cardbus remote";
		ir->get_key = get_key_avermedia_cardbus;
		rc_proto    = RC_PROTO_BIT_OTHER;
		ir_codes    = RC_MAP_AVERMEDIA_CARDBUS;
		break;
	case 0x41:
		name        = "AVerMedia EM78P153";
		ir->get_key = get_key_avermedia_cardbus;
		rc_proto    = RC_PROTO_BIT_OTHER;
		/* RM-KV remote, seems to be same as RM-K6 */
		ir_codes    = RC_MAP_AVERMEDIA_M733A_RM_K6;
		break;
	case 0x71:
		name        = "Hauppauge/Zilog Z8";
		ir->get_key = get_key_haup_xvr;
		rc_proto    = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
							RC_PROTO_BIT_RC6_6A_32;
		ir_codes    = RC_MAP_HAUPPAUGE;
		probe_tx = true;
		break;
	}

	/* Let the caller override settings */
	if (client->dev.platform_data) {
		const struct IR_i2c_init_data *init_data =
						client->dev.platform_data;

		ir_codes = init_data->ir_codes;
		rc = init_data->rc_dev;

		name = init_data->name;
		if (init_data->type)
			rc_proto = init_data->type;

		if (init_data->polling_interval)
			ir->polling_interval = init_data->polling_interval;

		switch (init_data->internal_get_key_func) {
		case IR_KBD_GET_KEY_CUSTOM:
			/* The bridge driver provided us its own function */
			ir->get_key = init_data->get_key;
			break;
		case IR_KBD_GET_KEY_PIXELVIEW:
			ir->get_key = get_key_pixelview;
			break;
		case IR_KBD_GET_KEY_HAUP:
			ir->get_key = get_key_haup;
			break;
		case IR_KBD_GET_KEY_KNC1:
			ir->get_key = get_key_knc1;
			break;
		case IR_KBD_GET_KEY_FUSIONHDTV:
			ir->get_key = get_key_fusionhdtv;
			break;
		case IR_KBD_GET_KEY_HAUP_XVR:
			ir->get_key = get_key_haup_xvr;
			break;
		case IR_KBD_GET_KEY_AVERMEDIA_CARDBUS:
			ir->get_key = get_key_avermedia_cardbus;
			break;
		}
	}

	if (!rc) {
		/*
		 * If platform_data doesn't specify rc_dev, initialize it
		 * internally
		 */
		rc = rc_allocate_device(RC_DRIVER_SCANCODE);
		if (!rc)
			return -ENOMEM;
	}
	ir->rc = rc;

	/* Make sure we are all setup before going on */
	if (!name || !ir->get_key || !rc_proto || !ir_codes) {
		dev_warn(&client->dev, "Unsupported device at address 0x%02x\n",
			 addr);
		err = -ENODEV;
		goto err_out_free;
	}

	ir->ir_codes = ir_codes;

	snprintf(ir->phys, sizeof(ir->phys), "%s/%s", dev_name(&adap->dev),
		 dev_name(&client->dev));

	/*
	 * Initialize input_dev fields
	 * It doesn't make sense to allow overriding them via platform_data
	 */
	rc->input_id.bustype = BUS_I2C;
	rc->input_phys       = ir->phys;
	rc->device_name	     = name;
	rc->dev.parent       = &client->dev;
	rc->priv             = ir;
	rc->open             = ir_open;
	rc->close            = ir_close;

	/*
	 * Initialize the other fields of rc_dev
	 */
	rc->map_name       = ir->ir_codes;
	rc->allowed_protocols = rc_proto;
	if (!rc->driver_name)
		rc->driver_name = KBUILD_MODNAME;

	mutex_init(&ir->lock);

	INIT_DELAYED_WORK(&ir->work, ir_work);

	if (probe_tx) {
		ir->tx_c = i2c_new_dummy(client->adapter, 0x70);
		if (!ir->tx_c) {
			dev_err(&client->dev, "failed to setup tx i2c address");
		} else if (!zilog_init(ir)) {
			ir->carrier = 38000;
			ir->duty_cycle = 40;
			rc->tx_ir = zilog_tx;
			rc->s_tx_carrier = zilog_tx_carrier;
			rc->s_tx_duty_cycle = zilog_tx_duty_cycle;
		}
	}

	err = rc_register_device(rc);
	if (err)
		goto err_out_free;

	return 0;

 err_out_free:
	if (ir->tx_c)
		i2c_unregister_device(ir->tx_c);

	/* Only frees rc if it were allocated internally */
	rc_free_device(rc);
	return err;
}

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

	/* kill outstanding polls */
	cancel_delayed_work_sync(&ir->work);

	if (ir->tx_c)
		i2c_unregister_device(ir->tx_c);

	/* unregister device */
	rc_unregister_device(ir->rc);

	/* free memory */
	return 0;
}

static const struct i2c_device_id ir_kbd_id[] = {
	/* Generic entry for any IR receiver */
	{ "ir_video", 0 },
	/* IR device specific entries should be added here */
	{ "ir_z8f0811_haup", FLAG_TX },
	{ "ir_z8f0811_hdpvr", FLAG_TX | FLAG_HDPVR },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ir_kbd_id);

static struct i2c_driver ir_kbd_driver = {
	.driver = {
		.name   = "ir-kbd-i2c",
	},
	.probe          = ir_probe,
	.remove         = ir_remove,
	.id_table       = ir_kbd_id,
};

module_i2c_driver(ir_kbd_driver);

/* ----------------------------------------------------------------------- */

MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
MODULE_DESCRIPTION("input driver for i2c IR remote controls");
MODULE_LICENSE("GPL");
