// 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.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_SEL		0x0020
#define MTK_KPD_SEL_DOUBLE_KP_MODE	BIT(0)
#define MTK_KPD_SEL_COL	GENMASK(15, 10)
#define MTK_KPD_SEL_ROW	GENMASK(9, 4)
#define MTK_KPD_SEL_COLMASK(c)	GENMASK((c) + 9, 10)
#define MTK_KPD_SEL_ROWMASK(r)	GENMASK((r) + 3, 4)
#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;
	u32 n_rows;
	u32 n_cols;
	void (*calc_row_col)(unsigned int key,
			     unsigned int *row, unsigned int *col);
	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, key;
	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;

		key = bit_nr / 32 * 16 + bit_nr % 32;
		keypad->calc_row_col(key, &row, &col);

		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_calc_row_col_single(unsigned int key,
					      unsigned int *row,
					      unsigned int *col)
{
	*row = key / 9;
	*col = key % 9;
}

static void mt6779_keypad_calc_row_col_double(unsigned int key,
					      unsigned int *row,
					      unsigned int *col)
{
	*row = key / 13;
	*col = (key % 13) / 2;
}

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

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

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

	keypad->regmap = devm_regmap_init_mmio(&pdev->dev, 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;
	}

	if (device_property_read_u32(&pdev->dev, "mediatek,keys-per-group",
				     &keys_per_group))
		keys_per_group = 1;

	switch (keys_per_group) {
	case 1:
		keypad->calc_row_col = mt6779_keypad_calc_row_col_single;
		break;
	case 2:
		keypad->calc_row_col = mt6779_keypad_calc_row_col_double;
		break;
	default:
		dev_err(&pdev->dev,
			"Invalid keys-per-group: %d\n", keys_per_group);
		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);

	if (keys_per_group == 2)
		regmap_update_bits(keypad->regmap, MTK_KPD_SEL,
				   MTK_KPD_SEL_DOUBLE_KP_MODE,
				   MTK_KPD_SEL_DOUBLE_KP_MODE);

	regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_ROW,
			   MTK_KPD_SEL_ROWMASK(keypad->n_rows));
	regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_COL,
			   MTK_KPD_SEL_COLMASK(keypad->n_cols));

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

	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 */ }
};
MODULE_DEVICE_TABLE(of, mt6779_keypad_of_match);

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");
