/****************************************************************

 Siano Mobile Silicon, Inc.
 MDTV receiver kernel modules.
 Copyright (C) 2006-2009, Uri Shkolnik

 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, see <http://www.gnu.org/licenses/>.

 ****************************************************************/


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

#include "smscoreapi.h"
#include "smsir.h"
#include "sms-cards.h"

/* In order to add new IR remote control -
 * 1) Add it to the <enum ir_kb_type> @ smsir,h,
 * 2) Add its map to keyboard_layout_maps below
 * 3) Set your board (sms-cards sub-module) to use it
 */

static struct keyboard_layout_map_t keyboard_layout_maps[] = {
		[SMS_IR_KB_DEFAULT_TV] = {
			.ir_protocol = IR_RC5,
			.rc5_kbd_address = KEYBOARD_ADDRESS_TV1,
			.keyboard_layout_map = {
					KEY_0, KEY_1, KEY_2,
					KEY_3, KEY_4, KEY_5,
					KEY_6, KEY_7, KEY_8,
					KEY_9, 0, 0, KEY_POWER,
					KEY_MUTE, 0, 0,
					KEY_VOLUMEUP, KEY_VOLUMEDOWN,
					KEY_BRIGHTNESSUP,
					KEY_BRIGHTNESSDOWN, 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, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0, 0, 0
			}
		},
		[SMS_IR_KB_HCW_SILVER] = {
			.ir_protocol = IR_RC5,
			.rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1,
			.keyboard_layout_map = {
					KEY_0, KEY_1, KEY_2,
					KEY_3, KEY_4, KEY_5,
					KEY_6, KEY_7, KEY_8,
					KEY_9, KEY_TEXT, KEY_RED,
					KEY_RADIO, KEY_MENU,
					KEY_SUBTITLE,
					KEY_MUTE, KEY_VOLUMEUP,
					KEY_VOLUMEDOWN, KEY_PREVIOUS, 0,
					KEY_UP, KEY_DOWN, KEY_LEFT,
					KEY_RIGHT, KEY_VIDEO, KEY_AUDIO,
					KEY_MHP, KEY_EPG, KEY_TV,
					0, KEY_NEXTSONG, KEY_EXIT,
					KEY_CHANNELUP, 	KEY_CHANNELDOWN,
					KEY_CHANNEL, 0,
					KEY_PREVIOUSSONG, KEY_ENTER,
					KEY_SLEEP, 0, 0, KEY_BLUE,
					0, 0, 0, 0, KEY_GREEN, 0,
					KEY_PAUSE, 0, KEY_REWIND,
					0, KEY_FASTFORWARD, KEY_PLAY,
					KEY_STOP, KEY_RECORD,
					KEY_YELLOW, 0, 0, KEY_SELECT,
					KEY_ZOOM, KEY_POWER, 0, 0
			}
		},
		{ } /* Terminating entry */
};

static u32 ir_pos;
static u32 ir_word;
static u32 ir_toggle;

#define RC5_PUSH_BIT(dst, bit, pos)	\
	{ dst <<= 1; dst |= bit; pos++; }


static void sms_ir_rc5_event(struct smscore_device_t *coredev,
				u32 toggle, u32 addr, u32 cmd)
{
	bool toggle_changed;
	u16 keycode;

	sms_log("IR RC5 word: address %d, command %d, toggle %d",
				addr, cmd, toggle);

	toggle_changed = ir_toggle != toggle;
	/* keep toggle */
	ir_toggle = toggle;

	if (addr !=
		keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address)
		return; /* Check for valid address */

	keycode =
		keyboard_layout_maps
		[coredev->ir.ir_kb_type].keyboard_layout_map[cmd];

	if (!toggle_changed &&
			(keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN))
		return; /* accept only repeated volume, reject other keys */

	sms_log("kernel input keycode (from ir) %d", keycode);
	input_report_key(coredev->ir.input_dev, keycode, 1);
	input_sync(coredev->ir.input_dev);

}

/* decode raw bit pattern to RC5 code */
/* taken from ir-functions.c */
static u32 ir_rc5_decode(unsigned int code)
{
/*	unsigned int org_code = code;*/
	unsigned int pair;
	unsigned int rc5 = 0;
	int i;

	for (i = 0; i < 14; ++i) {
		pair = code & 0x3;
		code >>= 2;

		rc5 <<= 1;
		switch (pair) {
		case 0:
		case 2:
			break;
		case 1:
			rc5 |= 1;
			break;
		case 3:
/*	dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/
			sms_log("bad code");
			return 0;
		}
	}
/*
	dprintk(1, "ir-common: code=%x, rc5=%x, start=%x,
		toggle=%x, address=%x, "
		"instr=%x\n", rc5, org_code, RC5_START(rc5),
		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
*/
	return rc5;
}

static void sms_rc5_parse_word(struct smscore_device_t *coredev)
{
	#define RC5_START(x)    (((x)>>12)&3)
	#define RC5_TOGGLE(x)   (((x)>>11)&1)
	#define RC5_ADDR(x)     (((x)>>6)&0x1F)
	#define RC5_INSTR(x)    ((x)&0x3F)

	int i, j;
	u32 rc5_word = 0;

	/* Reverse the IR word direction */
	for (i = 0 ; i < 28 ; i++)
		RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j)

	rc5_word = ir_rc5_decode(rc5_word);
	/* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */

	sms_ir_rc5_event(coredev,
				RC5_TOGGLE(rc5_word),
				RC5_ADDR(rc5_word),
				RC5_INSTR(rc5_word));
}


static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev,
		s32 ir_sample)
{
	#define RC5_TIME_GRANULARITY	200
	#define RC5_DEF_BIT_TIME		889
	#define RC5_MAX_SAME_BIT_CONT	4
	#define RC5_WORD_LEN			27 /* 28 bit */

	u32 i, j;
	s32 delta_time;
	u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample);
	u32 level = (ir_sample < 0) ? 0 : 1;

	for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) {
		delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY;
		if (delta_time < 0)
			continue; /* not so many consecutive bits */
		if (delta_time > (2 * RC5_TIME_GRANULARITY)) {
			/* timeout */
			if (ir_pos == (RC5_WORD_LEN-1))
				/* complete last bit */
				RC5_PUSH_BIT(ir_word, level, ir_pos)

			if (ir_pos == RC5_WORD_LEN)
				sms_rc5_parse_word(coredev);
			else if (ir_pos) /* timeout within a word */
				sms_log("IR error parsing a word");

			ir_pos = 0;
			ir_word = 0;
			/* sms_log("timeout %d", time); */
			break;
		}
		/* The time is within the range of this number of bits */
		for (j = 0 ; j < i ; j++)
			RC5_PUSH_BIT(ir_word, level, ir_pos)

		break;
	}
}

void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
{
	#define IR_DATA_RECEIVE_MAX_LEN	520 /* 128*4 + 4 + 4 */
	u32 i;
	enum ir_protocol ir_protocol =
			keyboard_layout_maps[coredev->ir.ir_kb_type]
					     .ir_protocol;
	s32 *samples;
	int count = len>>2;

	samples = (s32 *)buf;
/*	sms_log("IR buffer received, length = %d", count);*/

	for (i = 0; i < count; i++)
		if (ir_protocol == IR_RC5)
			sms_rc5_accumulate_bits(coredev, samples[i]);
	/*  IR_RCMM not implemented */
}

int sms_ir_init(struct smscore_device_t *coredev)
{
	struct input_dev *input_dev;

	sms_log("Allocating input device");
	input_dev = input_allocate_device();
	if (!input_dev)	{
		sms_err("Not enough memory");
		return -ENOMEM;
	}

	coredev->ir.input_dev = input_dev;
	coredev->ir.ir_kb_type =
		sms_get_board(smscore_get_board_id(coredev))->ir_kb_type;
	coredev->ir.keyboard_layout_map =
		keyboard_layout_maps[coredev->ir.ir_kb_type].
				keyboard_layout_map;
	sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type);

	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	sms_log("IR port %d, timeout %d ms",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name,
				IR_DEV_NAME_MAX_LEN,
				"SMS IR w/kbd type %d",
				coredev->ir.ir_kb_type);
	input_dev->name = coredev->ir.name;
	input_dev->phys = coredev->ir.name;
	input_dev->dev.parent = coredev->device;

	/* Key press events only */
	input_dev->evbit[0] = BIT_MASK(EV_KEY);
	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);

	sms_log("Input device (IR) %s is set for key events", input_dev->name);

	if (input_register_device(input_dev)) {
		sms_err("Failed to register device");
		input_free_device(input_dev);
		return -EACCES;
	}

	return 0;
}

void sms_ir_exit(struct smscore_device_t *coredev)
{
	if (coredev->ir.input_dev)
		input_unregister_device(coredev->ir.input_dev);

	sms_log("");
}

