/*
 *  tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
 *
 *  Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation version 2
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>

#include <linux/input.h>
#include <linux/usb.h>

#include <media/rc-core.h>

#include "tm6000.h"
#include "tm6000-regs.h"

static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "debug message level");

static unsigned int enable_ir = 1;
module_param(enable_ir, int, 0644);
MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");

static unsigned int ir_clock_mhz = 12;
module_param(ir_clock_mhz, int, 0644);
MODULE_PARM_DESC(enable_ir, "ir clock, in MHz");

#define URB_SUBMIT_DELAY	100	/* ms - Delay to submit an URB request on retrial and init */
#define URB_INT_LED_DELAY	100	/* ms - Delay to turn led on again on int mode */

#undef dprintk

#define dprintk(level, fmt, arg...) do {\
	if (ir_debug >= level) \
		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
	} while (0)

struct tm6000_ir_poll_result {
	u16 rc_data;
};

struct tm6000_IR {
	struct tm6000_core	*dev;
	struct rc_dev		*rc;
	char			name[32];
	char			phys[32];

	/* poll expernal decoder */
	int			polling;
	struct delayed_work	work;
	u8			wait:1;
	u8			pwled:2;
	u8			submit_urb:1;
	u16			key_addr;
	struct urb		*int_urb;

	/* IR device properties */
	u64			rc_type;
};

void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
{
	struct tm6000_IR *ir = dev->ir;

	if (!dev->ir)
		return;

	dprintk(2, "%s: %i\n",__func__, ir->wait);

	if (state)
		ir->wait = 1;
	else
		ir->wait = 0;
}

static int tm6000_ir_config(struct tm6000_IR *ir)
{
	struct tm6000_core *dev = ir->dev;
	u32 pulse = 0, leader = 0;

	dprintk(2, "%s\n",__func__);

	/*
	 * The IR decoder supports RC-5 or NEC, with a configurable timing.
	 * The timing configuration there is not that accurate, as it uses
	 * approximate values. The NEC spec mentions a 562.5 unit period,
	 * and RC-5 uses a 888.8 period.
	 * Currently, driver assumes a clock provided by a 12 MHz XTAL, but
	 * a modprobe parameter can adjust it.
	 * Adjustments are required for other timings.
	 * It seems that the 900ms timing for NEC is used to detect a RC-5
	 * IR, in order to discard such decoding
	 */

	switch (ir->rc_type) {
	case RC_TYPE_NEC:
		leader = 900;	/* ms */
		pulse  = 700;	/* ms - the actual value would be 562 */
		break;
	default:
	case RC_TYPE_RC5:
		leader = 900;	/* ms - from the NEC decoding */
		pulse  = 1780;	/* ms - The actual value would be 1776 */
		break;
	}

	pulse = ir_clock_mhz * pulse;
	leader = ir_clock_mhz * leader;
	if (ir->rc_type == RC_TYPE_NEC)
		leader = leader | 0x8000;

	dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
		__func__,
		(ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5",
		ir_clock_mhz, leader, pulse);

	/* Remote WAKEUP = enable, normal mode, from IR decoder output */
	tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);

	/* Enable IR reception on non-busrt mode */
	tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f);

	/* IR_WKUP_SEL = Low byte in decoded IR data */
	tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff);
	/* IR_WKU_ADD code */
	tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff);

	tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8);
	tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader);

	tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8);
	tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse);

	if (!ir->polling)
		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
	else
		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
	msleep(10);

	/* Shows that IR is working via the LED */
	tm6000_flash_led(dev, 0);
	msleep(100);
	tm6000_flash_led(dev, 1);
	ir->pwled = 1;

	return 0;
}

static void tm6000_ir_urb_received(struct urb *urb)
{
	struct tm6000_core *dev = urb->context;
	struct tm6000_IR *ir = dev->ir;
	struct tm6000_ir_poll_result poll_result;
	char *buf;
	int rc;

	dprintk(2, "%s\n",__func__);
	if (urb->status < 0 || urb->actual_length <= 0) {
		printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n",
		       urb->status, urb->actual_length);
		ir->submit_urb = 1;
		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
		return;
	}
	buf = urb->transfer_buffer;

	if (ir_debug)
		print_hex_dump(KERN_DEBUG, "tm6000: IR data: ",
			       DUMP_PREFIX_OFFSET,16, 1,
			       buf, urb->actual_length, false);

	poll_result.rc_data = buf[0];
	if (urb->actual_length > 1)
		poll_result.rc_data |= buf[1] << 8;

	dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
	rc_keydown(ir->rc, poll_result.rc_data, 0);

	rc = usb_submit_urb(urb, GFP_ATOMIC);
	/*
	 * Flash the led. We can't do it here, as it is running on IRQ context.
	 * So, use the scheduler to do it, in a few ms.
	 */
	ir->pwled = 2;
	schedule_delayed_work(&ir->work, msecs_to_jiffies(10));
}

static void tm6000_ir_handle_key(struct work_struct *work)
{
	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
	struct tm6000_core *dev = ir->dev;
	struct tm6000_ir_poll_result poll_result;
	int rc;
	u8 buf[2];

	if (ir->wait)
		return;

	dprintk(3, "%s\n",__func__);

	rc = tm6000_read_write_usb(dev, USB_DIR_IN |
		USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		REQ_02_GET_IR_CODE, 0, 0, buf, 2);
	if (rc < 0)
		return;

	if (rc > 1)
		poll_result.rc_data = buf[0] | buf[1] << 8;
	else
		poll_result.rc_data = buf[0];

	/* Check if something was read */
	if ((poll_result.rc_data & 0xff) == 0xff) {
		if (!ir->pwled) {
			tm6000_flash_led(dev, 1);
			ir->pwled = 1;
		}
		return;
	}

	dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
	rc_keydown(ir->rc, poll_result.rc_data, 0);
	tm6000_flash_led(dev, 0);
	ir->pwled = 0;

	/* Re-schedule polling */
	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}

static void tm6000_ir_int_work(struct work_struct *work)
{
	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
	struct tm6000_core *dev = ir->dev;
	int rc;

	dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb,
		ir->pwled);

	if (ir->submit_urb) {
		dprintk(3, "Resubmit urb\n");
		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);

		rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC);
		if (rc < 0) {
			printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n",
			       rc);
			/* Retry in 100 ms */
			schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
			return;
		}
		ir->submit_urb = 0;
	}

	/* Led is enabled only if USB submit doesn't fail */
	if (ir->pwled == 2) {
		tm6000_flash_led(dev, 0);
		ir->pwled = 0;
		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY));
	} else if (!ir->pwled) {
		tm6000_flash_led(dev, 1);
		ir->pwled = 1;
	}
}

static int tm6000_ir_start(struct rc_dev *rc)
{
	struct tm6000_IR *ir = rc->priv;

	dprintk(2, "%s\n",__func__);

	schedule_delayed_work(&ir->work, 0);

	return 0;
}

static void tm6000_ir_stop(struct rc_dev *rc)
{
	struct tm6000_IR *ir = rc->priv;

	dprintk(2, "%s\n",__func__);

	cancel_delayed_work_sync(&ir->work);
}

static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
	struct tm6000_IR *ir = rc->priv;

	if (!ir)
		return 0;

	dprintk(2, "%s\n",__func__);

	if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
		ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);

	ir->rc_type = rc_type;

	tm6000_ir_config(ir);
	/* TODO */
	return 0;
}

static int __tm6000_ir_int_start(struct rc_dev *rc)
{
	struct tm6000_IR *ir = rc->priv;
	struct tm6000_core *dev = ir->dev;
	int pipe, size;
	int err = -ENOMEM;

	if (!ir)
		return -ENODEV;

	dprintk(2, "%s\n",__func__);

	ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!ir->int_urb)
		return -ENOMEM;

	pipe = usb_rcvintpipe(dev->udev,
		dev->int_in.endp->desc.bEndpointAddress
		& USB_ENDPOINT_NUMBER_MASK);

	size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
	dprintk(1, "IR max size: %d\n", size);

	ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC);
	if (ir->int_urb->transfer_buffer == NULL) {
		usb_free_urb(ir->int_urb);
		return err;
	}
	dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval);

	usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
		ir->int_urb->transfer_buffer, size,
		tm6000_ir_urb_received, dev,
		dev->int_in.endp->desc.bInterval);

	ir->submit_urb = 1;
	schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));

	return 0;
}

static void __tm6000_ir_int_stop(struct rc_dev *rc)
{
	struct tm6000_IR *ir = rc->priv;

	if (!ir || !ir->int_urb)
		return;

	dprintk(2, "%s\n",__func__);

	usb_kill_urb(ir->int_urb);
	kfree(ir->int_urb->transfer_buffer);
	usb_free_urb(ir->int_urb);
	ir->int_urb = NULL;
}

int tm6000_ir_int_start(struct tm6000_core *dev)
{
	struct tm6000_IR *ir = dev->ir;

	if (!ir)
		return 0;

	return __tm6000_ir_int_start(ir->rc);
}

void tm6000_ir_int_stop(struct tm6000_core *dev)
{
	struct tm6000_IR *ir = dev->ir;

	if (!ir || !ir->rc)
		return;

	__tm6000_ir_int_stop(ir->rc);
}

int tm6000_ir_init(struct tm6000_core *dev)
{
	struct tm6000_IR *ir;
	struct rc_dev *rc;
	int err = -ENOMEM;

	if (!enable_ir)
		return -ENODEV;

	if (!dev->caps.has_remote)
		return 0;

	if (!dev->ir_codes)
		return 0;

	ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
	rc = rc_allocate_device();
	if (!ir || !rc)
		goto out;

	dprintk(2, "%s\n", __func__);

	/* record handles to ourself */
	ir->dev = dev;
	dev->ir = ir;
	ir->rc = rc;

	/* input setup */
	rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
	/* Neded, in order to support NEC remotes with 24 or 32 bits */
	rc->scanmask = 0xffff;
	rc->priv = ir;
	rc->change_protocol = tm6000_ir_change_protocol;
	if (dev->int_in.endp) {
		rc->open    = __tm6000_ir_int_start;
		rc->close   = __tm6000_ir_int_stop;
		INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work);
	} else {
		rc->open  = tm6000_ir_start;
		rc->close = tm6000_ir_stop;
		ir->polling = 50;
		INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
	}
	rc->driver_type = RC_DRIVER_SCANCODE;

	snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
						dev->name);

	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
	strlcat(ir->phys, "/input0", sizeof(ir->phys));

	tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	rc->input_id.bustype = BUS_USB;
	rc->input_id.version = 1;
	rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
	rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
	rc->map_name = dev->ir_codes;
	rc->driver_name = "tm6000";
	rc->dev.parent = &dev->udev->dev;

	/* ir register */
	err = rc_register_device(rc);
	if (err)
		goto out;

	return 0;

out:
	dev->ir = NULL;
	rc_free_device(rc);
	kfree(ir);
	return err;
}

int tm6000_ir_fini(struct tm6000_core *dev)
{
	struct tm6000_IR *ir = dev->ir;

	/* skip detach on non attached board */

	if (!ir)
		return 0;

	dprintk(2, "%s\n",__func__);

	rc_unregister_device(ir->rc);

	if (!ir->polling)
		__tm6000_ir_int_stop(ir->rc);

	tm6000_ir_stop(ir->rc);

	/* Turn off the led */
	tm6000_flash_led(dev, 0);
	ir->pwled = 0;


	kfree(ir);
	dev->ir = NULL;

	return 0;
}
