// 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		166  /* microseconds */
#define RCMM_PREFIX_PULSE	417  /* 166.666666666666*2.5 */
#define RCMM_PULSE_0            278  /* 166.666666666666*(1+2/3) */
#define RCMM_PULSE_1            444  /* 166.666666666666*(2+2/3) */
#define RCMM_PULSE_2            611  /* 166.666666666666*(3+2/3) */
#define RCMM_PULSE_3            778  /* 166.666666666666*(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, 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");
