// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com>
 */

#include <common.h>
#include <button.h>
#include <dm.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
#include <log.h>
#include <asm/gpio.h>

struct button_gpio_priv {
	struct gpio_desc gpio;
};

static enum button_state_t button_gpio_get_state(struct udevice *dev)
{
	struct button_gpio_priv *priv = dev_get_priv(dev);
	int ret;

	if (!dm_gpio_is_valid(&priv->gpio))
		return -EREMOTEIO;
	ret = dm_gpio_get_value(&priv->gpio);
	if (ret < 0)
		return ret;

	return ret ? BUTTON_ON : BUTTON_OFF;
}

static int button_gpio_probe(struct udevice *dev)
{
	struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
	struct button_gpio_priv *priv = dev_get_priv(dev);
	int ret;

	/* Ignore the top-level button node */
	if (!uc_plat->label)
		return 0;

	ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
	if (ret)
		return ret;

	return 0;
}

static int button_gpio_remove(struct udevice *dev)
{
	/*
	 * The GPIO driver may have already been removed. We will need to
	 * address this more generally.
	 */
	if (!IS_ENABLED(CONFIG_SANDBOX)) {
		struct button_gpio_priv *priv = dev_get_priv(dev);

		if (dm_gpio_is_valid(&priv->gpio))
			dm_gpio_free(dev, &priv->gpio);
	}

	return 0;
}

static int button_gpio_bind(struct udevice *parent)
{
	struct udevice *dev;
	ofnode node;
	int ret;

	dev_for_each_subnode(node, parent) {
		struct button_uc_plat *uc_plat;
		const char *label;

		label = ofnode_read_string(node, "label");
		if (!label) {
			debug("%s: node %s has no label\n", __func__,
			      ofnode_get_name(node));
			return -EINVAL;
		}
		ret = device_bind_driver_to_node(parent, "button_gpio",
						 ofnode_get_name(node),
						 node, &dev);
		if (ret)
			return ret;
		uc_plat = dev_get_uclass_platdata(dev);
		uc_plat->label = label;
	}

	return 0;
}

static const struct button_ops button_gpio_ops = {
	.get_state	= button_gpio_get_state,
};

static const struct udevice_id button_gpio_ids[] = {
	{ .compatible = "gpio-keys" },
	{ .compatible = "gpio-keys-polled" },
	{ }
};

U_BOOT_DRIVER(button_gpio) = {
	.name		= "button_gpio",
	.id		= UCLASS_BUTTON,
	.of_match	= button_gpio_ids,
	.ops		= &button_gpio_ops,
	.priv_auto_alloc_size = sizeof(struct button_gpio_priv),
	.bind		= button_gpio_bind,
	.probe		= button_gpio_probe,
	.remove		= button_gpio_remove,
};
