// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Mediatek IR Receiver Controller
 *
 * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
 */

#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/reset.h>
#include <media/rc-core.h>

#define MTK_IR_DEV KBUILD_MODNAME

/* Register to enable PWM and IR */
#define MTK_CONFIG_HIGH_REG       0x0c

/* Bit to enable IR pulse width detection */
#define MTK_PWM_EN		  BIT(13)

/*
 * Register to setting ok count whose unit based on hardware sampling period
 * indicating IR receiving completion and then making IRQ fires
 */
#define MTK_OK_COUNT(x)		  (((x) & GENMASK(23, 16)) << 16)

/* Bit to enable IR hardware function */
#define MTK_IR_EN		  BIT(0)

/* Bit to restart IR receiving */
#define MTK_IRCLR		  BIT(0)

/* Fields containing pulse width data */
#define MTK_WIDTH_MASK		  (GENMASK(7, 0))

/* IR threshold */
#define MTK_IRTHD		 0x14
#define MTK_DG_CNT_MASK		 (GENMASK(12, 8))
#define MTK_DG_CNT(x)		 ((x) << 8)

/* Bit to enable interrupt */
#define MTK_IRINT_EN		  BIT(0)

/* Bit to clear interrupt status */
#define MTK_IRINT_CLR		  BIT(0)

/* Maximum count of samples */
#define MTK_MAX_SAMPLES		  0xff
/* Indicate the end of IR message */
#define MTK_IR_END(v, p)	  ((v) == MTK_MAX_SAMPLES && (p) == 0)
/* Number of registers to record the pulse width */
#define MTK_CHKDATA_SZ		  17
/* Sample period in ns */
#define MTK_IR_SAMPLE		  46000

enum mtk_fields {
	/* Register to setting software sampling period */
	MTK_CHK_PERIOD,
	/* Register to setting hardware sampling period */
	MTK_HW_PERIOD,
};

enum mtk_regs {
	/* Register to clear state of state machine */
	MTK_IRCLR_REG,
	/* Register containing pulse width data */
	MTK_CHKDATA_REG,
	/* Register to enable IR interrupt */
	MTK_IRINT_EN_REG,
	/* Register to ack IR interrupt */
	MTK_IRINT_CLR_REG
};

static const u32 mt7623_regs[] = {
	[MTK_IRCLR_REG] =	0x20,
	[MTK_CHKDATA_REG] =	0x88,
	[MTK_IRINT_EN_REG] =	0xcc,
	[MTK_IRINT_CLR_REG] =	0xd0,
};

static const u32 mt7622_regs[] = {
	[MTK_IRCLR_REG] =	0x18,
	[MTK_CHKDATA_REG] =	0x30,
	[MTK_IRINT_EN_REG] =	0x1c,
	[MTK_IRINT_CLR_REG] =	0x20,
};

struct mtk_field_type {
	u32 reg;
	u8 offset;
	u32 mask;
};

/*
 * struct mtk_ir_data -	This is the structure holding all differences among
			various hardwares
 * @regs:		The pointer to the array holding registers offset
 * @fields:		The pointer to the array holding fields location
 * @div:		The internal divisor for the based reference clock
 * @ok_count:		The count indicating the completion of IR data
 *			receiving when count is reached
 * @hw_period:		The value indicating the hardware sampling period
 */
struct mtk_ir_data {
	const u32 *regs;
	const struct mtk_field_type *fields;
	u8 div;
	u8 ok_count;
	u32 hw_period;
};

static const struct mtk_field_type mt7623_fields[] = {
	[MTK_CHK_PERIOD] = {0x10, 8, GENMASK(20, 8)},
	[MTK_HW_PERIOD] = {0x10, 0, GENMASK(7, 0)},
};

static const struct mtk_field_type mt7622_fields[] = {
	[MTK_CHK_PERIOD] = {0x24, 0, GENMASK(24, 0)},
	[MTK_HW_PERIOD] = {0x10, 0, GENMASK(24, 0)},
};

/*
 * struct mtk_ir -	This is the main datasructure for holding the state
 *			of the driver
 * @dev:		The device pointer
 * @rc:			The rc instrance
 * @base:		The mapped register i/o base
 * @irq:		The IRQ that we are using
 * @clk:		The clock that IR internal is using
 * @bus:		The clock that software decoder is using
 * @data:		Holding specific data for vaious platform
 */
struct mtk_ir {
	struct device	*dev;
	struct rc_dev	*rc;
	void __iomem	*base;
	int		irq;
	struct clk	*clk;
	struct clk	*bus;
	const struct mtk_ir_data *data;
};

static inline u32 mtk_chkdata_reg(struct mtk_ir *ir, u32 i)
{
	return ir->data->regs[MTK_CHKDATA_REG] + 4 * i;
}

static inline u32 mtk_chk_period(struct mtk_ir *ir)
{
	u32 val;

	/* Period of raw software sampling in ns */
	val = DIV_ROUND_CLOSEST(1000000000ul,
				clk_get_rate(ir->bus) / ir->data->div);

	/*
	 * Period for software decoder used in the
	 * unit of raw software sampling
	 */
	val = DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, val);

	dev_dbg(ir->dev, "@pwm clk  = \t%lu\n",
		clk_get_rate(ir->bus) / ir->data->div);
	dev_dbg(ir->dev, "@chkperiod = %08x\n", val);

	return val;
}

static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
{
	u32 tmp;

	tmp = __raw_readl(ir->base + reg);
	tmp = (tmp & ~mask) | val;
	__raw_writel(tmp, ir->base + reg);
}

static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
{
	__raw_writel(val, ir->base + reg);
}

static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
{
	return __raw_readl(ir->base + reg);
}

static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
{
	u32 val;

	val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]);
	mtk_w32(ir, val & ~mask, ir->data->regs[MTK_IRINT_EN_REG]);
}

static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
{
	u32 val;

	val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]);
	mtk_w32(ir, val | mask, ir->data->regs[MTK_IRINT_EN_REG]);
}

static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
{
	struct mtk_ir *ir = dev_id;
	u8  wid = 0;
	u32 i, j, val;
	struct ir_raw_event rawir = {};

	/*
	 * Reset decoder state machine explicitly is required
	 * because 1) the longest duration for space MTK IR hardware
	 * could record is not safely long. e.g  12ms if rx resolution
	 * is 46us by default. There is still the risk to satisfying
	 * every decoder to reset themselves through long enough
	 * trailing spaces and 2) the IRQ handler guarantees that
	 * start of IR message is always contained in and starting
	 * from register mtk_chkdata_reg(ir, i).
	 */
	ir_raw_event_reset(ir->rc);

	/* First message must be pulse */
	rawir.pulse = false;

	/* Handle all pulse and space IR controller captures */
	for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
		val = mtk_r32(ir, mtk_chkdata_reg(ir, i));
		dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);

		for (j = 0 ; j < 4 ; j++) {
			wid = (val & (MTK_WIDTH_MASK << j * 8)) >> j * 8;
			rawir.pulse = !rawir.pulse;
			rawir.duration = wid * (MTK_IR_SAMPLE + 1);
			ir_raw_event_store_with_filter(ir->rc, &rawir);
		}
	}

	/*
	 * The maximum number of edges the IR controller can
	 * hold is MTK_CHKDATA_SZ * 4. So if received IR messages
	 * is over the limit, the last incomplete IR message would
	 * be appended trailing space and still would be sent into
	 * ir-rc-raw to decode. That helps it is possible that it
	 * has enough information to decode a scancode even if the
	 * trailing end of the message is missing.
	 */
	if (!MTK_IR_END(wid, rawir.pulse)) {
		rawir.pulse = false;
		rawir.duration = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
		ir_raw_event_store_with_filter(ir->rc, &rawir);
	}

	ir_raw_event_handle(ir->rc);

	/*
	 * Restart controller for the next receive that would
	 * clear up all CHKDATA registers
	 */
	mtk_w32_mask(ir, 0x1, MTK_IRCLR, ir->data->regs[MTK_IRCLR_REG]);

	/* Clear interrupt status */
	mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR,
		     ir->data->regs[MTK_IRINT_CLR_REG]);

	return IRQ_HANDLED;
}

static const struct mtk_ir_data mt7623_data = {
	.regs = mt7623_regs,
	.fields = mt7623_fields,
	.ok_count = 0xf,
	.hw_period = 0xff,
	.div	= 4,
};

static const struct mtk_ir_data mt7622_data = {
	.regs = mt7622_regs,
	.fields = mt7622_fields,
	.ok_count = 0xf,
	.hw_period = 0xffff,
	.div	= 32,
};

static const struct of_device_id mtk_ir_match[] = {
	{ .compatible = "mediatek,mt7623-cir", .data = &mt7623_data},
	{ .compatible = "mediatek,mt7622-cir", .data = &mt7622_data},
	{},
};
MODULE_DEVICE_TABLE(of, mtk_ir_match);

static int mtk_ir_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *dn = dev->of_node;
	struct resource *res;
	struct mtk_ir *ir;
	u32 val;
	int ret = 0;
	const char *map_name;

	ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	ir->dev = dev;
	ir->data = of_device_get_match_data(dev);

	ir->clk = devm_clk_get(dev, "clk");
	if (IS_ERR(ir->clk)) {
		dev_err(dev, "failed to get a ir clock.\n");
		return PTR_ERR(ir->clk);
	}

	ir->bus = devm_clk_get(dev, "bus");
	if (IS_ERR(ir->bus)) {
		/*
		 * For compatibility with older device trees try unnamed
		 * ir->bus uses the same clock as ir->clock.
		 */
		ir->bus = ir->clk;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ir->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(ir->base))
		return PTR_ERR(ir->base);

	ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
	if (!ir->rc) {
		dev_err(dev, "failed to allocate device\n");
		return -ENOMEM;
	}

	ir->rc->priv = ir;
	ir->rc->device_name = MTK_IR_DEV;
	ir->rc->input_phys = MTK_IR_DEV "/input0";
	ir->rc->input_id.bustype = BUS_HOST;
	ir->rc->input_id.vendor = 0x0001;
	ir->rc->input_id.product = 0x0001;
	ir->rc->input_id.version = 0x0001;
	map_name = of_get_property(dn, "linux,rc-map-name", NULL);
	ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
	ir->rc->dev.parent = dev;
	ir->rc->driver_name = MTK_IR_DEV;
	ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	ir->rc->rx_resolution = MTK_IR_SAMPLE;
	ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);

	ret = devm_rc_register_device(dev, ir->rc);
	if (ret) {
		dev_err(dev, "failed to register rc device\n");
		return ret;
	}

	platform_set_drvdata(pdev, ir);

	ir->irq = platform_get_irq(pdev, 0);
	if (ir->irq < 0)
		return -ENODEV;

	if (clk_prepare_enable(ir->clk)) {
		dev_err(dev, "try to enable ir_clk failed\n");
		return -EINVAL;
	}

	if (clk_prepare_enable(ir->bus)) {
		dev_err(dev, "try to enable ir_clk failed\n");
		ret = -EINVAL;
		goto exit_clkdisable_clk;
	}

	/*
	 * Enable interrupt after proper hardware
	 * setup and IRQ handler registration
	 */
	mtk_irq_disable(ir, MTK_IRINT_EN);

	ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
	if (ret) {
		dev_err(dev, "failed request irq\n");
		goto exit_clkdisable_bus;
	}

	/*
	 * Setup software sample period as the reference of software decoder
	 */
	val = (mtk_chk_period(ir) << ir->data->fields[MTK_CHK_PERIOD].offset) &
	       ir->data->fields[MTK_CHK_PERIOD].mask;
	mtk_w32_mask(ir, val, ir->data->fields[MTK_CHK_PERIOD].mask,
		     ir->data->fields[MTK_CHK_PERIOD].reg);

	/*
	 * Setup hardware sampling period used to setup the proper timeout for
	 * indicating end of IR receiving completion
	 */
	val = (ir->data->hw_period << ir->data->fields[MTK_HW_PERIOD].offset) &
	       ir->data->fields[MTK_HW_PERIOD].mask;
	mtk_w32_mask(ir, val, ir->data->fields[MTK_HW_PERIOD].mask,
		     ir->data->fields[MTK_HW_PERIOD].reg);

	/* Set de-glitch counter */
	mtk_w32_mask(ir, MTK_DG_CNT(1), MTK_DG_CNT_MASK, MTK_IRTHD);

	/* Enable IR and PWM */
	val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
	val |= MTK_OK_COUNT(ir->data->ok_count) |  MTK_PWM_EN | MTK_IR_EN;
	mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);

	mtk_irq_enable(ir, MTK_IRINT_EN);

	dev_info(dev, "Initialized MT7623 IR driver, sample period = %dus\n",
		 DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));

	return 0;

exit_clkdisable_bus:
	clk_disable_unprepare(ir->bus);
exit_clkdisable_clk:
	clk_disable_unprepare(ir->clk);

	return ret;
}

static int mtk_ir_remove(struct platform_device *pdev)
{
	struct mtk_ir *ir = platform_get_drvdata(pdev);

	/*
	 * Avoid contention between remove handler and
	 * IRQ handler so that disabling IR interrupt and
	 * waiting for pending IRQ handler to complete
	 */
	mtk_irq_disable(ir, MTK_IRINT_EN);
	synchronize_irq(ir->irq);

	clk_disable_unprepare(ir->bus);
	clk_disable_unprepare(ir->clk);

	return 0;
}

static struct platform_driver mtk_ir_driver = {
	.probe          = mtk_ir_probe,
	.remove         = mtk_ir_remove,
	.driver = {
		.name = MTK_IR_DEV,
		.of_match_table = mtk_ir_match,
	},
};

module_platform_driver(mtk_ir_driver);

MODULE_DESCRIPTION("Mediatek IR Receiver Controller Driver");
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_LICENSE("GPL");
