/*
 * Driver for the remote control of SAA7146 based AV7110 cards
 *
 * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
 * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.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; 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.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 *
 */


#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <linux/bitops.h>

#include "av7110.h"
#include "av7110_hw.h"


#define AV_CNT		4

#define IR_RC5		0
#define IR_RCMM		1
#define IR_RC5_EXT	2 /* internal only */

#define IR_ALL		0xffffffff

#define UP_TIMEOUT	(HZ*7/25)


/* Note: enable ir debugging by or'ing debug with 16 */

static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM};
module_param_array(ir_protocol, int, NULL, 0644);
MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)");

static int ir_inversion[AV_CNT];
module_param_array(ir_inversion, int, NULL, 0644);
MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted");

static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL };
module_param_array(ir_device_mask, uint, NULL, 0644);
MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)");


static int av_cnt;
static struct av7110 *av_list[AV_CNT];

static u16 default_key_map [256] = {
	KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
	KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
	KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
	0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
	KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
	KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
	KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
	0, 0, 0, 0, KEY_EPG, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
};


/* key-up timer */
static void av7110_emit_keyup(unsigned long parm)
{
	struct infrared *ir = (struct infrared *) parm;

	if (!ir || !test_bit(ir->last_key, ir->input_dev->key))
		return;

	input_report_key(ir->input_dev, ir->last_key, 0);
	input_sync(ir->input_dev);
}


/* tasklet */
static void av7110_emit_key(unsigned long parm)
{
	struct infrared *ir = (struct infrared *) parm;
	u32 ircom = ir->ir_command;
	u8 data;
	u8 addr;
	u16 toggle;
	u16 keycode;

	/* extract device address and data */
	switch (ir->protocol) {
	case IR_RC5: /* RC5: 5 bits device address, 6 bits data */
		data = ircom & 0x3f;
		addr = (ircom >> 6) & 0x1f;
		toggle = ircom & 0x0800;
		break;

	case IR_RCMM: /* RCMM: ? bits device address, ? bits data */
		data = ircom & 0xff;
		addr = (ircom >> 8) & 0x1f;
		toggle = ircom & 0x8000;
		break;

	case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */
		data = ircom & 0x3f;
		addr = (ircom >> 6) & 0x1f;
		/* invert 7th data bit for backward compatibility with RC5 keymaps */
		if (!(ircom & 0x1000))
			data |= 0x40;
		toggle = ircom & 0x0800;
		break;

	default:
		printk("%s invalid protocol %x\n", __func__, ir->protocol);
		return;
	}

	input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data);
	input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);

	keycode = ir->key_map[data];

	dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n",
		__func__, ircom, addr, data, keycode);

	/* check device address */
	if (!(ir->device_mask & (1 << addr)))
		return;

	if (!keycode) {
		printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n",
			__func__, ircom, addr, data);
		return;
	}

	if (timer_pending(&ir->keyup_timer)) {
		del_timer(&ir->keyup_timer);
		if (ir->last_key != keycode || toggle != ir->last_toggle) {
			ir->delay_timer_finished = 0;
			input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
			input_event(ir->input_dev, EV_KEY, keycode, 1);
			input_sync(ir->input_dev);
		} else if (ir->delay_timer_finished) {
			input_event(ir->input_dev, EV_KEY, keycode, 2);
			input_sync(ir->input_dev);
		}
	} else {
		ir->delay_timer_finished = 0;
		input_event(ir->input_dev, EV_KEY, keycode, 1);
		input_sync(ir->input_dev);
	}

	ir->last_key = keycode;
	ir->last_toggle = toggle;

	ir->keyup_timer.expires = jiffies + UP_TIMEOUT;
	add_timer(&ir->keyup_timer);

}


/* register with input layer */
static void input_register_keys(struct infrared *ir)
{
	int i;

	set_bit(EV_KEY, ir->input_dev->evbit);
	set_bit(EV_REP, ir->input_dev->evbit);
	set_bit(EV_MSC, ir->input_dev->evbit);

	set_bit(MSC_RAW, ir->input_dev->mscbit);
	set_bit(MSC_SCAN, ir->input_dev->mscbit);

	memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));

	for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) {
		if (ir->key_map[i] > KEY_MAX)
			ir->key_map[i] = 0;
		else if (ir->key_map[i] > KEY_RESERVED)
			set_bit(ir->key_map[i], ir->input_dev->keybit);
	}

	ir->input_dev->keycode = ir->key_map;
	ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
	ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
}


/* called by the input driver after rep[REP_DELAY] ms */
static void input_repeat_key(unsigned long parm)
{
	struct infrared *ir = (struct infrared *) parm;

	ir->delay_timer_finished = 1;
}


/* check for configuration changes */
int av7110_check_ir_config(struct av7110 *av7110, int force)
{
	int i;
	int modified = force;
	int ret = -ENODEV;

	for (i = 0; i < av_cnt; i++)
		if (av7110 == av_list[i])
			break;

	if (i < av_cnt && av7110) {
		if ((av7110->ir.protocol & 1) != ir_protocol[i] ||
		    av7110->ir.inversion != ir_inversion[i])
			modified = true;

		if (modified) {
			/* protocol */
			if (ir_protocol[i]) {
				ir_protocol[i] = 1;
				av7110->ir.protocol = IR_RCMM;
				av7110->ir.ir_config = 0x0001;
			} else if (FW_VERSION(av7110->arm_app) >= 0x2620) {
				av7110->ir.protocol = IR_RC5_EXT;
				av7110->ir.ir_config = 0x0002;
			} else {
				av7110->ir.protocol = IR_RC5;
				av7110->ir.ir_config = 0x0000;
			}
			/* inversion */
			if (ir_inversion[i]) {
				ir_inversion[i] = 1;
				av7110->ir.ir_config |= 0x8000;
			}
			av7110->ir.inversion = ir_inversion[i];
			/* update ARM */
			ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
						av7110->ir.ir_config);
		} else
			ret = 0;

		/* address */
		if (av7110->ir.device_mask != ir_device_mask[i])
			av7110->ir.device_mask = ir_device_mask[i];
	}

	return ret;
}


/* /proc/av7110_ir interface */
static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
				    size_t count, loff_t *pos)
{
	char *page;
	u32 ir_config;
	int size = sizeof ir_config + sizeof av_list[0]->ir.key_map;
	int i;

	if (count < size)
		return -EINVAL;

	page = vmalloc(size);
	if (!page)
		return -ENOMEM;

	if (copy_from_user(page, buffer, size)) {
		vfree(page);
		return -EFAULT;
	}

	memcpy(&ir_config, page, sizeof ir_config);

	for (i = 0; i < av_cnt; i++) {
		/* keymap */
		memcpy(av_list[i]->ir.key_map, page + sizeof ir_config,
			sizeof(av_list[i]->ir.key_map));
		/* protocol, inversion, address */
		ir_protocol[i] = ir_config & 0x0001;
		ir_inversion[i] = ir_config & 0x8000 ? 1 : 0;
		if (ir_config & 0x4000)
			ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f);
		else
			ir_device_mask[i] = IR_ALL;
		/* update configuration */
		av7110_check_ir_config(av_list[i], false);
		input_register_keys(&av_list[i]->ir);
	}
	vfree(page);
	return count;
}

static const struct file_operations av7110_ir_proc_fops = {
	.owner		= THIS_MODULE,
	.write		= av7110_ir_proc_write,
	.llseek		= noop_llseek,
};

/* interrupt handler */
static void ir_handler(struct av7110 *av7110, u32 ircom)
{
	dprintk(4, "ir command = %08x\n", ircom);
	av7110->ir.ir_command = ircom;
	tasklet_schedule(&av7110->ir.ir_tasklet);
}


int av7110_ir_init(struct av7110 *av7110)
{
	struct input_dev *input_dev;
	static struct proc_dir_entry *e;
	int err;

	if (av_cnt >= ARRAY_SIZE(av_list))
		return -ENOSPC;

	av_list[av_cnt++] = av7110;
	av7110_check_ir_config(av7110, true);

	init_timer(&av7110->ir.keyup_timer);
	av7110->ir.keyup_timer.function = av7110_emit_keyup;
	av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir;

	input_dev = input_allocate_device();
	if (!input_dev)
		return -ENOMEM;

	av7110->ir.input_dev = input_dev;
	snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
		"pci-%s/ir0", pci_name(av7110->dev->pci));

	input_dev->name = "DVB on-card IR receiver";

	input_dev->phys = av7110->ir.input_phys;
	input_dev->id.bustype = BUS_PCI;
	input_dev->id.version = 2;
	if (av7110->dev->pci->subsystem_vendor) {
		input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
		input_dev->id.product = av7110->dev->pci->subsystem_device;
	} else {
		input_dev->id.vendor = av7110->dev->pci->vendor;
		input_dev->id.product = av7110->dev->pci->device;
	}
	input_dev->dev.parent = &av7110->dev->pci->dev;
	/* initial keymap */
	memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map);
	input_register_keys(&av7110->ir);
	err = input_register_device(input_dev);
	if (err) {
		input_free_device(input_dev);
		return err;
	}
	input_dev->timer.function = input_repeat_key;
	input_dev->timer.data = (unsigned long) &av7110->ir;

	if (av_cnt == 1) {
		e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
		if (e)
			proc_set_size(e, 4 + 256 * sizeof(u16));
	}

	tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
	av7110->ir.ir_handler = ir_handler;

	return 0;
}


void av7110_ir_exit(struct av7110 *av7110)
{
	int i;

	if (av_cnt == 0)
		return;

	del_timer_sync(&av7110->ir.keyup_timer);
	av7110->ir.ir_handler = NULL;
	tasklet_kill(&av7110->ir.ir_tasklet);

	for (i = 0; i < av_cnt; i++)
		if (av_list[i] == av7110) {
			av_list[i] = av_list[av_cnt-1];
			av_list[av_cnt-1] = NULL;
			break;
		}

	if (av_cnt == 1)
		remove_proc_entry("av7110_ir", NULL);

	input_unregister_device(av7110->ir.input_dev);

	av_cnt--;
}

//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
//MODULE_LICENSE("GPL");
