/*
 * FireDTV driver (formerly known as FireSAT)
 *
 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
 *
 *	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.
 */

#include <linux/bitops.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>

#include "firedtv.h"

/* fixed table with older keycodes, geared towards MythTV */
static const u16 oldtable[] = {

	/* code from device: 0x4501...0x451f */

	KEY_ESC,
	KEY_F9,
	KEY_1,
	KEY_2,
	KEY_3,
	KEY_4,
	KEY_5,
	KEY_6,
	KEY_7,
	KEY_8,
	KEY_9,
	KEY_I,
	KEY_0,
	KEY_ENTER,
	KEY_RED,
	KEY_UP,
	KEY_GREEN,
	KEY_F10,
	KEY_SPACE,
	KEY_F11,
	KEY_YELLOW,
	KEY_DOWN,
	KEY_BLUE,
	KEY_Z,
	KEY_P,
	KEY_PAGEDOWN,
	KEY_LEFT,
	KEY_W,
	KEY_RIGHT,
	KEY_P,
	KEY_M,

	/* code from device: 0x4540...0x4542 */

	KEY_R,
	KEY_V,
	KEY_C,
};

/* user-modifiable table for a remote as sold in 2008 */
static const u16 keytable[] = {

	/* code from device: 0x0300...0x031f */

	[0x00] = KEY_POWER,
	[0x01] = KEY_SLEEP,
	[0x02] = KEY_STOP,
	[0x03] = KEY_OK,
	[0x04] = KEY_RIGHT,
	[0x05] = KEY_1,
	[0x06] = KEY_2,
	[0x07] = KEY_3,
	[0x08] = KEY_LEFT,
	[0x09] = KEY_4,
	[0x0a] = KEY_5,
	[0x0b] = KEY_6,
	[0x0c] = KEY_UP,
	[0x0d] = KEY_7,
	[0x0e] = KEY_8,
	[0x0f] = KEY_9,
	[0x10] = KEY_DOWN,
	[0x11] = KEY_TITLE,	/* "OSD" - fixme */
	[0x12] = KEY_0,
	[0x13] = KEY_F20,	/* "16:9" - fixme */
	[0x14] = KEY_SCREEN,	/* "FULL" - fixme */
	[0x15] = KEY_MUTE,
	[0x16] = KEY_SUBTITLE,
	[0x17] = KEY_RECORD,
	[0x18] = KEY_TEXT,
	[0x19] = KEY_AUDIO,
	[0x1a] = KEY_RED,
	[0x1b] = KEY_PREVIOUS,
	[0x1c] = KEY_REWIND,
	[0x1d] = KEY_PLAYPAUSE,
	[0x1e] = KEY_NEXT,
	[0x1f] = KEY_VOLUMEUP,

	/* code from device: 0x0340...0x0354 */

	[0x20] = KEY_CHANNELUP,
	[0x21] = KEY_F21,	/* "4:3" - fixme */
	[0x22] = KEY_TV,
	[0x23] = KEY_DVD,
	[0x24] = KEY_VCR,
	[0x25] = KEY_AUX,
	[0x26] = KEY_GREEN,
	[0x27] = KEY_YELLOW,
	[0x28] = KEY_BLUE,
	[0x29] = KEY_CHANNEL,	/* "CH.LIST" */
	[0x2a] = KEY_VENDOR,	/* "CI" - fixme */
	[0x2b] = KEY_VOLUMEDOWN,
	[0x2c] = KEY_CHANNELDOWN,
	[0x2d] = KEY_LAST,
	[0x2e] = KEY_INFO,
	[0x2f] = KEY_FORWARD,
	[0x30] = KEY_LIST,
	[0x31] = KEY_FAVORITES,
	[0x32] = KEY_MENU,
	[0x33] = KEY_EPG,
	[0x34] = KEY_EXIT,
};

int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
{
	struct input_dev *idev;
	int i, err;

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

	fdtv->remote_ctrl_dev = idev;
	idev->name = "FireDTV remote control";
	idev->dev.parent = dev;
	idev->evbit[0] = BIT_MASK(EV_KEY);
	idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
	if (!idev->keycode) {
		err = -ENOMEM;
		goto fail;
	}
	idev->keycodesize = sizeof(keytable[0]);
	idev->keycodemax = ARRAY_SIZE(keytable);

	for (i = 0; i < ARRAY_SIZE(keytable); i++)
		set_bit(keytable[i], idev->keybit);

	err = input_register_device(idev);
	if (err)
		goto fail_free_keymap;

	return 0;

fail_free_keymap:
	kfree(idev->keycode);
fail:
	input_free_device(idev);
	return err;
}

void fdtv_unregister_rc(struct firedtv *fdtv)
{
	kfree(fdtv->remote_ctrl_dev->keycode);
	input_unregister_device(fdtv->remote_ctrl_dev);
}

void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
{
	u16 *keycode = fdtv->remote_ctrl_dev->keycode;

	if (code >= 0x0300 && code <= 0x031f)
		code = keycode[code - 0x0300];
	else if (code >= 0x0340 && code <= 0x0354)
		code = keycode[code - 0x0320];
	else if (code >= 0x4501 && code <= 0x451f)
		code = oldtable[code - 0x4501];
	else if (code >= 0x4540 && code <= 0x4542)
		code = oldtable[code - 0x4521];
	else {
		printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
		       "from remote control\n", code);
		return;
	}

	input_report_key(fdtv->remote_ctrl_dev, code, 1);
	input_report_key(fdtv->remote_ctrl_dev, code, 0);
}
