// SPDX-License-Identifier: GPL-2.0-only
/*
 * Analog Devices ADP5585 Keys driver
 *
 * Copyright (C) 2025 Analog Devices, Inc.
 */

#include <linux/bitmap.h>
#include <linux/container_of.h>
#include <linux/device.h>
#include <linux/find.h>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/mfd/adp5585.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/types.h>

/* As needed for the matrix parsing code */
#define ADP5589_MAX_KEYMAPSIZE		123

struct adp5585_kpad_chip {
	u8 key_ev_min;
	u8 key_ev_max;
	u8 max_rows;
	u8 max_cols;
};

struct adp5585_kpad {
	const struct adp5585_kpad_chip *info;
	struct notifier_block nb;
	struct input_dev *input;
	unsigned short keycode[ADP5589_MAX_KEYMAPSIZE];
	struct device *dev;
	unsigned long keypad;
	int row_shift;
};

static int adp5585_keys_validate_events(const struct adp5585_kpad *kpad,
					const u32 *events, u32 n_events)
{
	unsigned int ev;
	u32 row, col;

	for (ev = 0; ev < n_events; ev++) {
		if (events[ev] < kpad->info->key_ev_min ||
		    events[ev] > kpad->info->key_ev_max)
			continue;

		/*
		 * if the event is to be generated by the keymap, we need to make
		 * sure that the pins are part of it!
		 */
		row = (events[ev] - 1) / kpad->info->max_cols;
		col = (events[ev] - 1) % kpad->info->max_cols;

		if (test_bit(row, &kpad->keypad) &&
		    test_bit(col + kpad->info->max_rows, &kpad->keypad))
			continue;

		return dev_err_probe(kpad->dev, -EINVAL,
				     "Invalid unlock/reset event(%u) not used in the keypad\n",
				     events[ev]);
	}

	return 0;
}

static int adp5585_keys_check_special_events(const struct adp5585_dev *adp5585,
					     const struct adp5585_kpad *kpad)
{
	int error;

	error = adp5585_keys_validate_events(kpad, adp5585->unlock_keys,
					     adp5585->nkeys_unlock);
	if (error)
		return error;

	error = adp5585_keys_validate_events(kpad, adp5585->reset1_keys,
					     adp5585->nkeys_reset1);
	if (error)
		return error;

	return adp5585_keys_validate_events(kpad, adp5585->reset2_keys,
					    adp5585->nkeys_reset2);
}

static void adp5585_keys_pins_free(void *data)
{
	struct adp5585_kpad *kpad = data;
	struct adp5585_dev *adp5585 = dev_get_drvdata(kpad->dev->parent);
	unsigned int pin;

	for_each_set_bit(pin, &kpad->keypad, adp5585->n_pins)
		clear_bit(pin, adp5585->pin_usage);
}

static int adp5585_keys_parse_fw(const struct adp5585_dev *adp5585,
				 struct adp5585_kpad *kpad)
{
	struct device *dev = kpad->dev;
	u32 cols = 0, rows = 0, pin;
	int error, n_pins;

	/*
	 * We do not check for errors (or no value) since the input device is
	 * only added if this property is present in the first place.
	 */
	n_pins = device_property_count_u32(dev, "adi,keypad-pins");
	if (n_pins > adp5585->n_pins)
		return dev_err_probe(dev, -EINVAL,
				     "Too many keypad pins (%d) defined (max=%d)\n",
				     n_pins, adp5585->n_pins);

	unsigned int *keypad_pins __free(kfree) = kcalloc(n_pins, sizeof(*keypad_pins),
							  GFP_KERNEL);
	if (!keypad_pins)
		return -ENOMEM;

	error = device_property_read_u32_array(dev, "adi,keypad-pins",
					       keypad_pins, n_pins);
	if (error)
		return error;

	/*
	 * We can add the action here since it makes the code easier and nothing
	 * "bad" will happen out of it. Worst case, it will be a no-op and no
	 * bit will set.
	 */
	error = devm_add_action_or_reset(dev, adp5585_keys_pins_free, kpad);
	if (error)
		return error;

	for (pin = 0; pin < n_pins; pin++) {
		if (keypad_pins[pin] >= adp5585->n_pins)
			return dev_err_probe(dev, -EINVAL,
					     "Invalid keypad pin(%u) defined\n",
					     keypad_pins[pin]);

		if (test_and_set_bit(keypad_pins[pin], adp5585->pin_usage))
			return dev_err_probe(dev, -EBUSY,
					     "Keypad pin(%u) already used\n",
					     keypad_pins[pin]);

		__set_bit(keypad_pins[pin], &kpad->keypad);
	}

	/*
	 * Note that given that we get a mask (and the HW allows it), we
	 * can have holes in our keypad (eg: row0, row1 and row7 enabled).
	 * However, for the matrix parsing functions we need to pass the
	 * number of rows/cols as the maximum row/col used plus 1. This
	 * pretty much means we will also have holes in our SW keypad.
	 */

	rows = find_last_bit(&kpad->keypad, kpad->info->max_rows) + 1;
	if (rows == kpad->info->max_rows + 1)
		return dev_err_probe(dev, -EINVAL,
				     "Now rows defined in the keypad!\n");

	cols = find_last_bit(&kpad->keypad, kpad->info->max_cols + kpad->info->max_rows);
	if (cols < kpad->info->max_rows)
		return dev_err_probe(dev, -EINVAL,
				     "No columns defined in the keypad!\n");

	cols = cols + 1 - kpad->info->max_rows;

	error = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
					   kpad->keycode, kpad->input);
	if (error)
		return error;

	kpad->row_shift = get_count_order(cols);

	if (device_property_read_bool(kpad->dev, "autorepeat"))
		__set_bit(EV_REP, kpad->input->evbit);

	error = adp5585_keys_check_special_events(adp5585, kpad);
	if (error)
		return error;

	return 0;
}

static int adp5585_keys_setup(const struct adp5585_dev *adp5585,
			      struct adp5585_kpad *kpad)
{
	unsigned long keys_bits, start = 0, nbits = kpad->info->max_rows;
	const struct adp5585_regs *regs = adp5585->regs;
	unsigned int i = 0, max_cols = kpad->info->max_cols;
	int error;

	/*
	 * Take care as the below assumes max_rows is always less or equal than
	 * 8 which is true for the supported devices. If we happen to add
	 * another device we need to make sure this still holds true. Although
	 * adding a new device is very unlikely.
	 */
	do {
		keys_bits = bitmap_read(&kpad->keypad, start, nbits);
		if (keys_bits) {
			error = regmap_write(adp5585->regmap, regs->pin_cfg_a + i,
					     keys_bits);
			if (error)
				return error;
		}

		start += nbits;
		if (max_cols > 8) {
			nbits = 8;
			max_cols -= nbits;
		} else {
			nbits = max_cols;
		}

		i++;
	} while (start < kpad->info->max_rows + kpad->info->max_cols);

	return 0;
}

static int adp5585_keys_ev_handle(struct notifier_block *nb, unsigned long key,
				  void *data)
{
	struct adp5585_kpad *kpad = container_of(nb, struct adp5585_kpad, nb);
	unsigned long key_press = (unsigned long)data;
	unsigned int row, col, code;

	/* make sure the event is for us */
	if (key < kpad->info->key_ev_min || key > kpad->info->key_ev_max)
		return NOTIFY_DONE;

	/*
	 * Unlikely but lets be on the safe side! We do not return any error
	 * because the event was indeed for us but with some weird value. So,
	 * we still want the caller know that the right handler was called.
	 */
	if (!key)
		return NOTIFY_BAD;

	row = (key - 1) / (kpad->info->max_cols);
	col = (key - 1) % (kpad->info->max_cols);
	code = MATRIX_SCAN_CODE(row, col, kpad->row_shift);

	dev_dbg_ratelimited(kpad->dev, "report key(%lu) r(%d) c(%d) code(%d)\n",
			    key, row, col, kpad->keycode[code]);

	input_report_key(kpad->input, kpad->keycode[code], key_press);
	input_sync(kpad->input);

	return NOTIFY_STOP;
}

static void adp5585_keys_unreg_notifier(void *data)
{
	struct adp5585_kpad *kpad = data;
	struct adp5585_dev *adp5585 = dev_get_drvdata(kpad->dev->parent);

	blocking_notifier_chain_unregister(&adp5585->event_notifier,
					   &kpad->nb);
}

static int adp5585_keys_probe(struct platform_device *pdev)
{
	const struct platform_device_id *id = platform_get_device_id(pdev);
	struct adp5585_dev *adp5585 = dev_get_drvdata(pdev->dev.parent);
	struct device *dev = &pdev->dev;
	struct adp5585_kpad *kpad;
	unsigned int revid;
	const char *phys;
	int error;

	kpad = devm_kzalloc(dev, sizeof(*kpad), GFP_KERNEL);
	if (!kpad)
		return -ENOMEM;

	if (!adp5585->irq)
		return dev_err_probe(dev, -EINVAL,
				     "IRQ is mandatory for the keypad\n");

	kpad->dev = dev;

	kpad->input = devm_input_allocate_device(dev);
	if (!kpad->input)
		return -ENOMEM;

	kpad->info = (const struct adp5585_kpad_chip *)id->driver_data;
	if (!kpad->info)
		return -ENODEV;

	error = regmap_read(adp5585->regmap, ADP5585_ID, &revid);
	if (error)
		return dev_err_probe(dev, error, "Failed to read device ID\n");

	phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", pdev->name);
	if (!phys)
		return -ENOMEM;

	kpad->input->name = pdev->name;
	kpad->input->phys = phys;

	kpad->input->id.bustype = BUS_I2C;
	kpad->input->id.vendor = 0x0001;
	kpad->input->id.product = 0x0001;
	kpad->input->id.version = revid & ADP5585_REV_ID_MASK;

	device_set_of_node_from_dev(dev, dev->parent);

	error = adp5585_keys_parse_fw(adp5585, kpad);
	if (error)
		return error;

	error = adp5585_keys_setup(adp5585, kpad);
	if (error)
		return error;

	kpad->nb.notifier_call = adp5585_keys_ev_handle;
	error = blocking_notifier_chain_register(&adp5585->event_notifier,
						 &kpad->nb);
	if (error)
		return error;

	error = devm_add_action_or_reset(dev, adp5585_keys_unreg_notifier, kpad);
	if (error)
		return error;

	error = input_register_device(kpad->input);
	if (error)
		return dev_err_probe(dev, error,
				     "Failed to register input device\n");

	return 0;
}

static const struct adp5585_kpad_chip adp5585_kpad_chip_info = {
	.max_rows = 6,
	.max_cols = 5,
	.key_ev_min = ADP5585_ROW5_KEY_EVENT_START,
	.key_ev_max = ADP5585_ROW5_KEY_EVENT_END,
};

static const struct adp5585_kpad_chip adp5589_kpad_chip_info = {
	.max_rows = 8,
	.max_cols = 11,
	.key_ev_min = ADP5589_KEY_EVENT_START,
	.key_ev_max = ADP5589_KEY_EVENT_END,
};

static const struct platform_device_id adp5585_keys_id_table[] = {
	{ "adp5585-keys", (kernel_ulong_t)&adp5585_kpad_chip_info },
	{ "adp5589-keys", (kernel_ulong_t)&adp5589_kpad_chip_info },
	{ }
};
MODULE_DEVICE_TABLE(platform, adp5585_keys_id_table);

static struct platform_driver adp5585_keys_driver = {
	.driver	= {
		.name = "adp5585-keys",
	},
	.probe = adp5585_keys_probe,
	.id_table = adp5585_keys_id_table,
};
module_platform_driver(adp5585_keys_driver);

MODULE_AUTHOR("Nuno Sá <nuno.sa@analog.com>");
MODULE_DESCRIPTION("ADP5585 Keys Driver");
MODULE_LICENSE("GPL");
