/*
 * drivers/amlogic/irblaster/irblaster-nec-encoder.c
 *
 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
 *
 * 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.
 *
 */

#include <linux/module.h>
#include <linux/amlogic/irblaster_encoder.h>

#define NEC_NBITS		32
#define NEC_UNIT		562  /* ns */
#define NEC_HEADER_PULSE	9000
#define NEC_HEADER_SPACE	4500
#define NEC_BIT_PULSE		560
#define NEC_BIT_0_SPACE		560
#define NEC_BIT_1_SPACE		1690
#define	NEC_TRAILER_PULSE	560
#define	NEC_TRAILER_SPACE	5600 /* even longer in reality */

static struct irblaster_raw_timings irblaster_nec_timings = {
	.header_pulse	= NEC_HEADER_PULSE,
	.header_space	= NEC_HEADER_SPACE,
	.bit_pulse	= NEC_BIT_PULSE,
	.bit_space[0]	= NEC_BIT_0_SPACE,
	.bit_space[1]	= NEC_BIT_1_SPACE,
	.trailer_pulse	= NEC_TRAILER_PULSE,
	.trailer_space	= NEC_TRAILER_SPACE,
	.msb_first	= 0,
	.raw_nbits	= NEC_NBITS,
	.data_size	= (NEC_NBITS + 2) * 2,
};

static u32 irblaster_nec32_scancode_to_raw(enum irblaster_protocol protocol,
					   unsigned int addrs,
					   unsigned int commmand)
{
	unsigned int addr = 0, addr_inv, data, data_inv;

	data = commmand & 0xff;
	addr_inv = addr & 0xff;
	addr = addrs & 0xff;
	data_inv = data & 0xff;

	return data_inv << 24 |
	       data     << 16 |
	       addr_inv <<  8 |
	       addr;
}

static u32 irblaster_necx_scancode_to_raw(enum irblaster_protocol protocol,
					  unsigned int addrs,
					  unsigned int commmand)
{
	unsigned int addr, addr_inv, data, data_inv;

	data = commmand & 0xff;
	addr = addrs & 0xff;
	addr_inv = addr & 0xff;
	data_inv = data ^ 0xff;

	return data_inv << 24 |
	       data     << 16 |
	       addr_inv <<  8 |
	       addr;
}

static u32 irblaster_nec_scancode_to_raw(enum irblaster_protocol protocol,
					 unsigned int addrs,
					 unsigned int commmand)
{
	unsigned int addr, addr_inv, data, data_inv;

	data = commmand & 0xff;
	addr       = addrs & 0xff;
	addr_inv   = addr ^ 0xff;
	data_inv   = data ^ 0xff;

	return data_inv << 24 |
	       data     << 16 |
	       addr_inv <<  8 |
	       addr;
}

int irblaster_nec_encode(enum irblaster_protocol protocol,
			 unsigned int addr,
			 unsigned int commmand,
			 unsigned int *data)
{
	u32 raw, ret;

	if (protocol >= IRBLASTER_PROTOCOL_MAX)
		return -ENODEV;

	/* Convert a NEC scancode to raw NEC data */
	switch (protocol) {
	case IRBLASTER_PROTOCOL_NEC:
		raw = irblaster_nec_scancode_to_raw(protocol, addr, commmand);
		break;
	case IRBLASTER_PROTOCOL_NECX:
		raw = irblaster_necx_scancode_to_raw(protocol, addr, commmand);
		break;
	case IRBLASTER_PROTOCOL_NEC32:
		raw = irblaster_nec32_scancode_to_raw(protocol, addr, commmand);
		break;
	default:
		raw = irblaster_nec_scancode_to_raw(protocol, addr, commmand);
		break;
	}

	/* Modulate the raw data using a pulse distance modulation */
	ret = irblaster_raw_gen(data, &irblaster_nec_timings, raw);
	if (ret < 0)
		return ret;

	return ret;
}

static struct irblaster_raw_handler irblaster_nec_handler[] = {
	{
		.name		= "NEC",
		.protocol	= IRBLASTER_PROTOCOL_NEC,
		.encode		= irblaster_nec_encode,
		.freq		= 38000,
		.duty		= 50,
		.timing		= &irblaster_nec_timings,
	},
	{
		.name		= "NECX",
		.protocol	= IRBLASTER_PROTOCOL_NECX,
		.encode		= irblaster_nec_encode,
		.freq		= 38000,
		.duty		= 50,
		.timing		= &irblaster_nec_timings,
	},
	{
		.name		= "NEC32",
		.protocol	= IRBLASTER_PROTOCOL_NEC32,
		.encode		= irblaster_nec_encode,
		.freq		= 38000,
		.duty		= 50,
		.timing		= &irblaster_nec_timings,
	}
};

static int __init irblaster_nec_decode_init(void)
{
	int i;

	for (i = 0; i < sizeof(irblaster_nec_handler) /
	     sizeof(struct irblaster_raw_handler); i++)
		irblaster_raw_handler_register(irblaster_nec_handler + i);

	return 0;
}

static void __exit irblaster_nec_decode_exit(void)
{
	int i;

	for (i = 0; i < sizeof(irblaster_nec_handler) /
	     sizeof(struct irblaster_raw_handler); i++)
		irblaster_raw_handler_unregister(irblaster_nec_handler + i);
}

fs_initcall(irblaster_nec_decode_init);
module_exit(irblaster_nec_decode_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("NEC IR protocol decoder");
