// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022 MediaTek Inc.
 * Author Fengping Yu <fengping.yu@mediatek.com>
 */
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/input/matrix_keypad.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#define MTK_KPD_NAME		"mt6779-keypad"
#define MTK_KPD_MEM		0x0004
#define MTK_KPD_DEBOUNCE	0x0018
#define MTK_KPD_DEBOUNCE_MASK	GENMASK(13, 0)
#define MTK_KPD_DEBOUNCE_MAX_MS	256
#define MTK_KPD_NUM_MEMS	5
#define MTK_KPD_NUM_BITS	136	/* 4*32+8 MEM5 only use 8 BITS */

struct mt6779_keypad {
	struct regmap *regmap;
	struct input_dev *input_dev;
	struct clk *clk;
	void __iomem *base;
	u32 n_rows;
	u32 n_cols;
	DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS);
};

static const struct regmap_config mt6779_keypad_regmap_cfg = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = sizeof(u32),
	.max_register = 36,
};

static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
{
	struct mt6779_keypad *keypad = dev_id;
	const unsigned short *keycode = keypad->input_dev->keycode;
	DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
	DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
	unsigned int bit_nr;
	unsigned int row, col;
	unsigned int scancode;
	unsigned int row_shift = get_count_order(keypad->n_cols);
	bool pressed;

	regmap_bulk_read(keypad->regmap, MTK_KPD_MEM,
			 new_state, MTK_KPD_NUM_MEMS);

	bitmap_xor(change, new_state, keypad->keymap_state, MTK_KPD_NUM_BITS);

	for_each_set_bit(bit_nr, change, MTK_KPD_NUM_BITS) {
		/*
		 * Registers are 32bits, but only bits [15:0] are used to
		 * indicate key status.
		 */
		if (bit_nr % 32 >= 16)
			continue;

		row = bit_nr / 32;
		col = bit_nr % 32;
		scancode = MATRIX_SCAN_CODE(row, col, row_shift);
		/* 1: not pressed, 0: pressed */
		pressed = !test_bit(bit_nr, new_state);
		dev_dbg(&keypad->input_dev->dev, "%s",
			pressed ? "pressed" : "released");

		input_event(keypad->input_dev, EV_MSC, MSC_SCAN, scancode);
		input_report_key(keypad->input_dev, keycode[scancode], pressed);
		input_sync(keypad->input_dev);

		dev_dbg(&keypad->input_dev->dev,
			"report Linux keycode = %d\n", keycode[scancode]);
	}

	bitmap_copy(keypad->keymap_state, new_state, MTK_KPD_NUM_BITS);

	return IRQ_HANDLED;
}

static void mt6779_keypad_clk_disable(void *data)
{
	clk_disable_unprepare(data);
}

static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
{
	struct mt6779_keypad *keypad;
	int irq;
	u32 debounce;
	bool wakeup;
	int error;

	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
	if (!keypad)
		return -ENOMEM;

	keypad->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(keypad->base))
		return PTR_ERR(keypad->base);

	keypad->regmap = devm_regmap_init_mmio(&pdev->dev, keypad->base,
					       &mt6779_keypad_regmap_cfg);
	if (IS_ERR(keypad->regmap)) {
		dev_err(&pdev->dev,
			"regmap init failed:%pe\n", keypad->regmap);
		return PTR_ERR(keypad->regmap);
	}

	bitmap_fill(keypad->keymap_state, MTK_KPD_NUM_BITS);

	keypad->input_dev = devm_input_allocate_device(&pdev->dev);
	if (!keypad->input_dev) {
		dev_err(&pdev->dev, "Failed to allocate input dev\n");
		return -ENOMEM;
	}

	keypad->input_dev->name = MTK_KPD_NAME;
	keypad->input_dev->id.bustype = BUS_HOST;

	error = matrix_keypad_parse_properties(&pdev->dev, &keypad->n_rows,
					       &keypad->n_cols);
	if (error) {
		dev_err(&pdev->dev, "Failed to parse keypad params\n");
		return error;
	}

	if (device_property_read_u32(&pdev->dev, "debounce-delay-ms",
				     &debounce))
		debounce = 16;

	if (debounce > MTK_KPD_DEBOUNCE_MAX_MS) {
		dev_err(&pdev->dev,
			"Debounce time exceeds the maximum allowed time %dms\n",
			MTK_KPD_DEBOUNCE_MAX_MS);
		return -EINVAL;
	}

	wakeup = device_property_read_bool(&pdev->dev, "wakeup-source");

	dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n",
		keypad->n_rows, keypad->n_cols, debounce);

	error = matrix_keypad_build_keymap(NULL, NULL,
					   keypad->n_rows, keypad->n_cols,
					   NULL, keypad->input_dev);
	if (error) {
		dev_err(&pdev->dev, "Failed to build keymap\n");
		return error;
	}

	input_set_capability(keypad->input_dev, EV_MSC, MSC_SCAN);

	regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
		     (debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK);

	keypad->clk = devm_clk_get(&pdev->dev, "kpd");
	if (IS_ERR(keypad->clk))
		return PTR_ERR(keypad->clk);

	error = clk_prepare_enable(keypad->clk);
	if (error) {
		dev_err(&pdev->dev, "cannot prepare/enable keypad clock\n");
		return error;
	}

	error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable,
					 keypad->clk);
	if (error)
		return error;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	error = devm_request_threaded_irq(&pdev->dev, irq,
					  NULL, mt6779_keypad_irq_handler,
					  IRQF_ONESHOT, MTK_KPD_NAME, keypad);
	if (error) {
		dev_err(&pdev->dev, "Failed to request IRQ#%d: %d\n",
			irq, error);
		return error;
	}

	error = input_register_device(keypad->input_dev);
	if (error) {
		dev_err(&pdev->dev, "Failed to register device\n");
		return error;
	}

	error = device_init_wakeup(&pdev->dev, wakeup);
	if (error)
		dev_warn(&pdev->dev, "device_init_wakeup() failed: %d\n",
			 error);

	return 0;
}

static const struct of_device_id mt6779_keypad_of_match[] = {
	{ .compatible = "mediatek,mt6779-keypad" },
	{ .compatible = "mediatek,mt6873-keypad" },
	{ /* sentinel */ }
};

static struct platform_driver mt6779_keypad_pdrv = {
	.probe = mt6779_keypad_pdrv_probe,
	.driver = {
		   .name = MTK_KPD_NAME,
		   .of_match_table = mt6779_keypad_of_match,
	},
};
module_platform_driver(mt6779_keypad_pdrv);

MODULE_AUTHOR("Mediatek Corporation");
MODULE_DESCRIPTION("MTK Keypad (KPD) Driver");
MODULE_LICENSE("GPL");
