// SPDX-License-Identifier: GPL-2.0-only
/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
 *
 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
 */

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

#define SONY_UNIT		600 /* us */
#define SONY_HEADER_PULSE	(4 * SONY_UNIT)
#define	SONY_HEADER_SPACE	(1 * SONY_UNIT)
#define SONY_BIT_0_PULSE	(1 * SONY_UNIT)
#define SONY_BIT_1_PULSE	(2 * SONY_UNIT)
#define SONY_BIT_SPACE		(1 * SONY_UNIT)
#define SONY_TRAILER_SPACE	(10 * SONY_UNIT) /* minimum */

enum sony_state {
	STATE_INACTIVE,
	STATE_HEADER_SPACE,
	STATE_BIT_PULSE,
	STATE_BIT_SPACE,
	STATE_FINISHED,
};

/**
 * ir_sony_decode() - Decode one Sony 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_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
	struct sony_dec *data = &dev->raw->sony;
	enum rc_proto protocol;
	u32 scancode;
	u8 device, subdevice, function;

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

	if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
		goto out;

	dev_dbg(&dev->dev, "Sony decode started at state %d (%uus %s)\n",
		data->state, ev.duration, TO_STR(ev.pulse));

	switch (data->state) {

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

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

		data->count = 0;
		data->state = STATE_HEADER_SPACE;
		return 0;

	case STATE_HEADER_SPACE:
		if (ev.pulse)
			break;

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

		data->state = STATE_BIT_PULSE;
		return 0;

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

		data->bits <<= 1;
		if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
			data->bits |= 1;
		else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
			break;

		data->count++;
		data->state = STATE_BIT_SPACE;
		return 0;

	case STATE_BIT_SPACE:
		if (ev.pulse)
			break;

		if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
			break;

		decrease_duration(&ev, SONY_BIT_SPACE);

		if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
			data->state = STATE_BIT_PULSE;
			return 0;
		}

		data->state = STATE_FINISHED;
		fallthrough;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
			break;

		switch (data->count) {
		case 12:
			if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY12))
				goto finish_state_machine;

			device    = bitrev8((data->bits <<  3) & 0xF8);
			subdevice = 0;
			function  = bitrev8((data->bits >>  4) & 0xFE);
			protocol = RC_PROTO_SONY12;
			break;
		case 15:
			if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY15))
				goto finish_state_machine;

			device    = bitrev8((data->bits >>  0) & 0xFF);
			subdevice = 0;
			function  = bitrev8((data->bits >>  7) & 0xFE);
			protocol = RC_PROTO_SONY15;
			break;
		case 20:
			if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY20))
				goto finish_state_machine;

			device    = bitrev8((data->bits >>  5) & 0xF8);
			subdevice = bitrev8((data->bits >>  0) & 0xFF);
			function  = bitrev8((data->bits >> 12) & 0xFE);
			protocol = RC_PROTO_SONY20;
			break;
		default:
			dev_dbg(&dev->dev, "Sony invalid bitcount %u\n",
				data->count);
			goto out;
		}

		scancode = device << 16 | subdevice << 8 | function;
		dev_dbg(&dev->dev, "Sony(%u) scancode 0x%05x\n", data->count,
			scancode);
		rc_keydown(dev, protocol, scancode, 0);
		goto finish_state_machine;
	}

out:
	dev_dbg(&dev->dev, "Sony decode failed at state %d (%uus %s)\n",
		data->state, ev.duration, TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;

finish_state_machine:
	data->state = STATE_INACTIVE;
	return 0;
}

static const struct ir_raw_timings_pl ir_sony_timings = {
	.header_pulse  = SONY_HEADER_PULSE,
	.bit_space     = SONY_BIT_SPACE,
	.bit_pulse[0]  = SONY_BIT_0_PULSE,
	.bit_pulse[1]  = SONY_BIT_1_PULSE,
	.trailer_space = SONY_TRAILER_SPACE + SONY_BIT_SPACE,
	.msb_first     = 0,
};

/**
 * ir_sony_encode() - Encode a scancode as a stream of raw events
 *
 * @protocol:	protocol to encode
 * @scancode:	scancode to encode
 * @events:	array of raw ir events to write into
 * @max:	maximum size of @events
 *
 * Returns:	The number of events written.
 *		-ENOBUFS if there isn't enough space in the array to fit the
 *		encoding. In this case all @max events will have been written.
 */
static int ir_sony_encode(enum rc_proto protocol, u32 scancode,
			  struct ir_raw_event *events, unsigned int max)
{
	struct ir_raw_event *e = events;
	u32 raw, len;
	int ret;

	if (protocol == RC_PROTO_SONY12) {
		raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9);
		len = 12;
	} else if (protocol == RC_PROTO_SONY15) {
		raw = (scancode & 0x7f) | ((scancode & 0xff0000) >> 9);
		len = 15;
	} else {
		raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9) |
		       ((scancode & 0xff00) << 4);
		len = 20;
	}

	ret = ir_raw_gen_pl(&e, max, &ir_sony_timings, len, raw);
	if (ret < 0)
		return ret;

	return e - events;
}

static struct ir_raw_handler sony_handler = {
	.protocols	= RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 |
							RC_PROTO_BIT_SONY20,
	.decode		= ir_sony_decode,
	.encode		= ir_sony_encode,
	.carrier	= 40000,
	.min_timeout	= SONY_TRAILER_SPACE,
};

static int __init ir_sony_decode_init(void)
{
	ir_raw_handler_register(&sony_handler);

	printk(KERN_INFO "IR Sony protocol handler initialized\n");
	return 0;
}

static void __exit ir_sony_decode_exit(void)
{
	ir_raw_handler_unregister(&sony_handler);
}

module_init(ir_sony_decode_init);
module_exit(ir_sony_decode_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
MODULE_DESCRIPTION("Sony IR protocol decoder");
