// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 * 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>
 */

#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_geniatech(struct IR_i2c *ir, enum rc_proto *protocol,
			     u32 *scancode, u8 *toggle)
{
	int i, rc;
	unsigned char b;

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

	/* don't repeat the key */
	if (ir->old == b)
		return 0;
	ir->old = b;

	/* decode to RC5 */
	b &= 0x7f;
	b = (b - 1) / 2;

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

	*protocol = RC_PROTO_RC5;
	*scancode = b;
	*toggle = ir->old >> 7;
	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;
	}

	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);
		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 0x33:
		name        = "Geniatech";
		ir->get_key = get_key_geniatech;
		rc_proto    = RC_PROTO_BIT_RC5;
		ir_codes    = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
		ir->old     = 0xfc;
		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;
		ir->polling_interval = 125;
		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_GENIATECH:
			ir->get_key = get_key_geniatech;
			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_device(client->adapter, 0x70);
		if (IS_ERR(ir->tx_c)) {
			dev_err(&client->dev, "failed to setup tx i2c address");
			err = PTR_ERR(ir->tx_c);
			goto err_out_free;
		} 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 (!IS_ERR(ir->tx_c))
		i2c_unregister_device(ir->tx_c);

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

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

	cancel_delayed_work_sync(&ir->work);

	i2c_unregister_device(ir->tx_c);

	rc_unregister_device(ir->rc);
}

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