// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for the remote control of SAA7146 based AV7110 cards
 *
 * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
 * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de>
 * Copyright (C) 2019 Sean Young <sean@mess.org>
 */

#include <linux/kernel.h>
#include <media/rc-core.h>

#include "av7110.h"
#include "av7110_hw.h"

#define IR_RC5		0
#define IR_RCMM		1
#define IR_RC5_EXT	2 /* internal only */

/* interrupt handler */
void av7110_ir_handler(struct av7110 *av7110, u32 ircom)
{
	struct rc_dev *rcdev = av7110->ir.rcdev;
	enum rc_proto proto;
	u32 command, addr, scancode;
	u32 toggle;

	dprintk(4, "ir command = %08x\n", ircom);

	if (rcdev) {
		switch (av7110->ir.ir_config) {
		case IR_RC5: /* RC5: 5 bits device address, 6 bits command */
			command = ircom & 0x3f;
			addr = (ircom >> 6) & 0x1f;
			scancode = RC_SCANCODE_RC5(addr, command);
			toggle = ircom & 0x0800;
			proto = RC_PROTO_RC5;
			break;

		case IR_RCMM: /* RCMM: ? bits device address, ? bits command */
			command = ircom & 0xff;
			addr = (ircom >> 8) & 0x1f;
			scancode = ircom;
			toggle = ircom & 0x8000;
			proto = RC_PROTO_UNKNOWN;
			break;

		case IR_RC5_EXT:
			/*
			 * extended RC5: 5 bits device address, 7 bits command
			 *
			 * Extended RC5 uses only one start bit. The second
			 * start bit is re-assigned bit 6 of the command bit.
			 */
			command = ircom & 0x3f;
			addr = (ircom >> 6) & 0x1f;
			if (!(ircom & 0x1000))
				command |= 0x40;
			scancode = RC_SCANCODE_RC5(addr, command);
			toggle = ircom & 0x0800;
			proto = RC_PROTO_RC5;
			break;
		default:
			dprintk(2, "unknown ir config %d\n",
				av7110->ir.ir_config);
			return;
		}

		rc_keydown(rcdev, proto, scancode, toggle != 0);
	}
}

int av7110_set_ir_config(struct av7110 *av7110)
{
	dprintk(4, "ir config = %08x\n", av7110->ir.ir_config);

	return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
			     av7110->ir.ir_config);
}

static int change_protocol(struct rc_dev *rcdev, u64 *rc_type)
{
	struct av7110 *av7110 = rcdev->priv;
	u32 ir_config;

	if (*rc_type & RC_PROTO_BIT_UNKNOWN) {
		ir_config = IR_RCMM;
		*rc_type = RC_PROTO_UNKNOWN;
	} else if (*rc_type & RC_PROTO_BIT_RC5) {
		if (FW_VERSION(av7110->arm_app) >= 0x2620)
			ir_config = IR_RC5_EXT;
		else
			ir_config = IR_RC5;
		*rc_type = RC_PROTO_BIT_RC5;
	} else {
		return -EINVAL;
	}

	if (ir_config == av7110->ir.ir_config)
		return 0;

	av7110->ir.ir_config = ir_config;

	return av7110_set_ir_config(av7110);
}

int av7110_ir_init(struct av7110 *av7110)
{
	struct rc_dev *rcdev;
	struct pci_dev *pci;
	int ret;

	rcdev = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!rcdev)
		return -ENOMEM;

	pci = av7110->dev->pci;

	snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
		 "pci-%s/ir0", pci_name(pci));

	rcdev->device_name = av7110->card_name;
	rcdev->driver_name = KBUILD_MODNAME;
	rcdev->input_phys = av7110->ir.input_phys;
	rcdev->input_id.bustype = BUS_PCI;
	rcdev->input_id.version = 2;
	if (pci->subsystem_vendor) {
		rcdev->input_id.vendor	= pci->subsystem_vendor;
		rcdev->input_id.product = pci->subsystem_device;
	} else {
		rcdev->input_id.vendor	= pci->vendor;
		rcdev->input_id.product = pci->device;
	}

	rcdev->dev.parent = &pci->dev;
	rcdev->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_UNKNOWN;
	rcdev->change_protocol = change_protocol;
	rcdev->map_name = RC_MAP_HAUPPAUGE;
	rcdev->priv = av7110;

	av7110->ir.rcdev = rcdev;
	av7110->ir.ir_config = IR_RC5;
	av7110_set_ir_config(av7110);

	ret = rc_register_device(rcdev);
	if (ret) {
		av7110->ir.rcdev = NULL;
		rc_free_device(rcdev);
	}

	return ret;
}

void av7110_ir_exit(struct av7110 *av7110)
{
	rc_unregister_device(av7110->ir.rcdev);
}

//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
//MODULE_LICENSE("GPL");
