// SPDX-License-Identifier: GPL-2.0+
// ir-rcmm-decoder.c - A decoder for the RCMM IR protocol
//
// Copyright (C) 2018 by Patrick Lerda <patrick9876@free.fr>

#include "rc-core-priv.h"
#include <linux/module.h>

#define RCMM_UNIT		166667	/* nanosecs */
#define RCMM_PREFIX_PULSE	416666  /* 166666.666666666*2.5 */
#define RCMM_PULSE_0            277777  /* 166666.666666666*(1+2/3) */
#define RCMM_PULSE_1            444444  /* 166666.666666666*(2+2/3) */
#define RCMM_PULSE_2            611111  /* 166666.666666666*(3+2/3) */
#define RCMM_PULSE_3            777778  /* 166666.666666666*(4+2/3) */

enum rcmm_state {
	STATE_INACTIVE,
	STATE_LOW,
	STATE_BUMP,
	STATE_VALUE,
	STATE_FINISHED,
};

static bool rcmm_mode(const struct rcmm_dec *data)
{
	return !((0x000c0000 & data->bits) == 0x000c0000);
}

static int rcmm_miscmode(struct rc_dev *dev, struct rcmm_dec *data)
{
	switch (data->count) {
	case 24:
		if (dev->enabled_protocols & RC_PROTO_BIT_RCMM24) {
			rc_keydown(dev, RC_PROTO_RCMM24, data->bits, 0);
			data->state = STATE_INACTIVE;
			return 0;
		}
		return -1;

	case 12:
		if (dev->enabled_protocols & RC_PROTO_BIT_RCMM12) {
			rc_keydown(dev, RC_PROTO_RCMM12, data->bits, 0);
			data->state = STATE_INACTIVE;
			return 0;
		}
		return -1;
	}

	return -1;
}

/**
 * ir_rcmm_decode() - Decode one RCMM pulse or space
 * @dev:	the struct rc_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct rcmm_dec *data = &dev->raw->rcmm;
	u32 scancode;
	u8 toggle;
	int value;

	if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 |
							RC_PROTO_BIT_RCMM24 |
							RC_PROTO_BIT_RCMM12)))
		return 0;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	switch (data->state) {
	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT))
			break;

		data->state = STATE_LOW;
		data->count = 0;
		data->bits  = 0;
		return 0;

	case STATE_LOW:
		if (ev.pulse)
			break;

		if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT))
			break;

		data->state = STATE_BUMP;
		return 0;

	case STATE_BUMP:
		if (!ev.pulse)
			break;

		if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
			break;

		data->state = STATE_VALUE;
		return 0;

	case STATE_VALUE:
		if (ev.pulse)
			break;

		if (eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2))
			value = 0;
		else if (eq_margin(ev.duration, RCMM_PULSE_1, RCMM_UNIT / 2))
			value = 1;
		else if (eq_margin(ev.duration, RCMM_PULSE_2, RCMM_UNIT / 2))
			value = 2;
		else if (eq_margin(ev.duration, RCMM_PULSE_3, RCMM_UNIT / 2))
			value = 3;
		else
			value = -1;

		if (value == -1) {
			if (!rcmm_miscmode(dev, data))
				return 0;
			break;
		}

		data->bits <<= 2;
		data->bits |= value;

		data->count += 2;

		if (data->count < 32)
			data->state = STATE_BUMP;
		else
			data->state = STATE_FINISHED;

		return 0;

	case STATE_FINISHED:
		if (!ev.pulse)
			break;

		if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
			break;

		if (rcmm_mode(data)) {
			toggle = !!(0x8000 & data->bits);
			scancode = data->bits & ~0x8000;
		} else {
			toggle = 0;
			scancode = data->bits;
		}

		if (dev->enabled_protocols & RC_PROTO_BIT_RCMM32) {
			rc_keydown(dev, RC_PROTO_RCMM32, scancode, toggle);
			data->state = STATE_INACTIVE;
			return 0;
		}

		break;
	}

	dev_dbg(&dev->dev, "RC-MM decode failed at count %d state %d (%uus %s)\n",
		data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}

static const int rcmmspace[] = {
	RCMM_PULSE_0,
	RCMM_PULSE_1,
	RCMM_PULSE_2,
	RCMM_PULSE_3,
};

static int ir_rcmm_rawencoder(struct ir_raw_event **ev, unsigned int max,
			      unsigned int n, u32 data)
{
	int i;
	int ret;

	ret = ir_raw_gen_pulse_space(ev, &max, RCMM_PREFIX_PULSE, RCMM_PULSE_0);
	if (ret)
		return ret;

	for (i = n - 2; i >= 0; i -= 2) {
		const unsigned int space = rcmmspace[(data >> i) & 3];

		ret = ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, space);
		if (ret)
			return ret;
	}

	return ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, RCMM_PULSE_3 * 2);
}

static int ir_rcmm_encode(enum rc_proto protocol, u32 scancode,
			  struct ir_raw_event *events, unsigned int max)
{
	struct ir_raw_event *e = events;
	int ret;

	switch (protocol) {
	case RC_PROTO_RCMM32:
		ret = ir_rcmm_rawencoder(&e, max, 32, scancode);
		break;
	case RC_PROTO_RCMM24:
		ret = ir_rcmm_rawencoder(&e, max, 24, scancode);
		break;
	case RC_PROTO_RCMM12:
		ret = ir_rcmm_rawencoder(&e, max, 12, scancode);
		break;
	default:
		ret = -EINVAL;
	}

	if (ret < 0)
		return ret;

	return e - events;
}

static struct ir_raw_handler rcmm_handler = {
	.protocols	= RC_PROTO_BIT_RCMM32 |
			  RC_PROTO_BIT_RCMM24 |
			  RC_PROTO_BIT_RCMM12,
	.decode		= ir_rcmm_decode,
	.encode         = ir_rcmm_encode,
	.carrier        = 36000,
	.min_timeout	= RCMM_PULSE_3 + RCMM_UNIT,
};

static int __init ir_rcmm_decode_init(void)
{
	ir_raw_handler_register(&rcmm_handler);

	pr_info("IR RCMM protocol handler initialized\n");
	return 0;
}

static void __exit ir_rcmm_decode_exit(void)
{
	ir_raw_handler_unregister(&rcmm_handler);
}

module_init(ir_rcmm_decode_init);
module_exit(ir_rcmm_decode_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick Lerda");
MODULE_DESCRIPTION("RCMM IR protocol decoder");
