// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
 */

#include <stdlib.h>
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <input.h>
#include <keyboard.h>
#include <button.h>
#include <dm/device-internal.h>
#include <log.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/delay.h>
#include <linux/input.h>

/**
 * struct button_kbd_priv - driver private data
 *
 * @input: input configuration
 * @button_size: number of buttons found
 * @old_state: a pointer to old button states array. Used to determine button state change.
 */
struct button_kbd_priv {
	struct input_config *input;
	u32 button_size;
	u32 *old_state;
};

static int button_kbd_start(struct udevice *dev)
{
	struct button_kbd_priv *priv = dev_get_priv(dev);
	int i = 0;
	struct udevice *button_gpio_devp, *next_devp;
	struct uclass *uc;

	uclass_foreach_dev_probe(UCLASS_BUTTON, button_gpio_devp) {
		struct button_uc_plat *uc_plat = dev_get_uclass_plat(button_gpio_devp);
		/* Ignore the top-level button node */
		if (!uc_plat->label)
			continue;
		debug("Found button %s #%d - %s, probing...\n",
		      uc_plat->label, i, button_gpio_devp->name);
		i++;
	}

	if (uclass_get(UCLASS_BUTTON, &uc))
		return -ENOENT;

	/*
	 * Unbind any buttons that failed to probe so we don't iterate over
	 * them when polling.
	 */
	uclass_foreach_dev_safe(button_gpio_devp, next_devp, uc) {
		if (!(dev_get_flags(button_gpio_devp) & DM_FLAG_ACTIVATED)) {
			log_warning("Button %s failed to probe\n",
				    button_gpio_devp->name);
			device_unbind(button_gpio_devp);
		}
	}

	priv->button_size = i;
	priv->old_state = calloc(i, sizeof(int));

	return 0;
}

int button_read_keys(struct input_config *input)
{
	struct button_kbd_priv *priv = dev_get_priv(input->dev);
	struct udevice *button_gpio_devp;
	struct uclass *uc;
	int i = 0;
	u32 code, state, state_changed = 0;

	uclass_id_foreach_dev(UCLASS_BUTTON, button_gpio_devp, uc) {
		struct button_uc_plat *uc_plat = dev_get_uclass_plat(button_gpio_devp);
		/* Ignore the top-level button node */
		if (!uc_plat->label)
			continue;
		code = button_get_code(button_gpio_devp);
		if (!code)
			continue;

		state = button_get_state(button_gpio_devp);
		state_changed = state != priv->old_state[i];

		if (state_changed) {
			debug("%s: %d\n", uc_plat->label, code);
			priv->old_state[i] = state;
			input_add_keycode(input, code, state);
		}
		i++;
	}
	return 0;
}

static const struct keyboard_ops button_kbd_ops = {
	.start	= button_kbd_start,
};

static int button_kbd_probe(struct udevice *dev)
{
	struct button_kbd_priv *priv = dev_get_priv(dev);
	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
	struct stdio_dev *sdev = &uc_priv->sdev;
	struct input_config *input = &uc_priv->input;
	int ret = 0;

	input_init(input, false);
	input_add_tables(input, false);

	/* Register the device. */
	priv->input = input;
	input->dev = dev;
	input->read_keys = button_read_keys;
	strcpy(sdev->name, "button-kbd");
	ret = input_stdio_register(sdev);
	if (ret) {
		debug("%s: input_stdio_register() failed\n", __func__);
		return ret;
	}

	return 0;
}

U_BOOT_DRIVER(button_kbd) = {
	.name		= "button_kbd",
	.id		= UCLASS_KEYBOARD,
	.ops		= &button_kbd_ops,
	.priv_auto	= sizeof(struct button_kbd_priv),
	.probe		= button_kbd_probe,
};

U_BOOT_DRVINFO(button_kbd) = {
	.name = "button_kbd"
};
