// SPDX-License-Identifier: GPL-2.0+
/*
 * Qualcomm generic pmic gpio driver
 *
 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 * (C) Copyright 2023 Linaro Ltd.
 */

#include <button.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <log.h>
#include <power/pmic.h>
#include <spmi/spmi.h>
#include <linux/bitops.h>
#include <time.h>

#define REG_TYPE		0x4
#define REG_SUBTYPE		0x5

struct qcom_pmic_btn_data {
	char *compatible;
	unsigned int status_bit;
	int code;
	char *label;
};

struct qcom_pmic_btn_priv {
	u32 base;
	u32 status_bit;
	int code;
	struct udevice *pmic;
	ulong last_release_time;
};

#define PON_INT_RT_STS                        0x10
#define  PON_KPDPWR_N_SET		0
#define  PON_RESIN_N_SET		1
#define  PON_GEN3_RESIN_N_SET		6
#define  PON_GEN3_KPDPWR_N_SET		7

static enum button_state_t qcom_pwrkey_get_state(struct udevice *dev)
{
	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
	bool pressed;
	int reg;

	if (get_timer_us(0) - priv->last_release_time < 25000)
		return BUTTON_OFF;

	reg = pmic_reg_read(priv->pmic, priv->base + PON_INT_RT_STS);
	if (reg < 0)
		return 0;

	pressed = !!(reg & BIT(priv->status_bit));
	if (!pressed)
		priv->last_release_time = get_timer_us(0);

	return pressed;
}

static int qcom_pwrkey_get_code(struct udevice *dev)
{
	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);

	return priv->code;
}

static const struct qcom_pmic_btn_data qcom_pmic_btn_data_table[] = {
	{
		.compatible = "qcom,pm8941-pwrkey",
		.status_bit = PON_KPDPWR_N_SET,
		.code = KEY_ENTER,
		.label = "Power Button",
	},
	{
		.compatible = "qcom,pm8941-resin",
		.status_bit = PON_RESIN_N_SET,
		.code = KEY_DOWN,
		.label = "Volume Down",
	},
	{
		.compatible = "qcom,pmk8350-pwrkey",
		.status_bit = PON_GEN3_KPDPWR_N_SET,
		.code = KEY_ENTER,
		.label = "Power Button",
	},
	{
		.compatible = "qcom,pmk8350-resin",
		.status_bit = PON_GEN3_RESIN_N_SET,
		.code = KEY_DOWN,
		.label = "Volume Down",
	},
};

static const struct qcom_pmic_btn_data *button_qcom_pmic_match(ofnode node)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(qcom_pmic_btn_data_table); ++i) {
		if (ofnode_device_is_compatible(node,
						qcom_pmic_btn_data_table[i].compatible))
			return &qcom_pmic_btn_data_table[i];
	}

	return NULL;
}

static int qcom_pwrkey_probe(struct udevice *dev)
{
	struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
	const struct qcom_pmic_btn_data *btn_data;
	ofnode node = dev_ofnode(dev);
	int ret;
	u64 base;

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

	/* Get the data for the node compatible */
	btn_data = button_qcom_pmic_match(node);
	if (!btn_data)
		return -EINVAL;

	priv->status_bit = btn_data->status_bit;
	priv->code = btn_data->code;

	/* the pwrkey and resin nodes are children of the "pon" node, get the
	 * PMIC device to use in pmic_reg_* calls.
	 */
	priv->pmic = dev->parent->parent;

	/* Get the address of the parent pon node */
	base = dev_read_addr(dev->parent);
	if (base == FDT_ADDR_T_NONE) {
		printf("%s: Can't find address\n", dev->name);
		return -EINVAL;
	}

	priv->base = base;

	ret = dev_read_u32(dev, "linux,code", &priv->code);
	if (ret == 0) {
		/* convert key, if read OK */
		switch (priv->code) {
		case KEY_VOLUMEDOWN:
			priv->code = KEY_DOWN;
			uc_plat->label = "Volume Down";
			break;
		case KEY_VOLUMEUP:
			priv->code = KEY_UP;
			uc_plat->label = "Volume Up";
			break;
		}
	}

	/* Do a sanity check */
	ret = pmic_reg_read(priv->pmic, priv->base + REG_TYPE);
	if (ret != 0x1 && ret != 0xb) {
		printf("%s: unexpected PMIC function type %d\n", dev->name, ret);
		return -ENXIO;
	}

	ret = pmic_reg_read(priv->pmic, priv->base + REG_SUBTYPE);
	if (ret < 0 || (ret & 0x7) == 0) {
		printf("%s: unexpected PMIC function subtype %d\n", dev->name, ret);
		return -ENXIO;
	}

	return 0;
}

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

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

		if (!ofnode_is_enabled(node))
			continue;

		/* Get the data for the node compatible */
		btn_data = button_qcom_pmic_match(node);
		if (!btn_data) {
			debug("Unknown button node '%s'\n", ofnode_get_name(node));
			continue;
		}

		ret = device_bind_driver_to_node(parent, "qcom_pwrkey",
						 ofnode_get_name(node),
						 node, &dev);
		if (ret) {
			printf("Failed to bind %s! %d\n", label, ret);
			return ret;
		}
		uc_plat = dev_get_uclass_plat(dev);
		uc_plat->label = btn_data->label;
	}

	return 0;
}

static const struct button_ops button_qcom_pmic_ops = {
	.get_state	= qcom_pwrkey_get_state,
	.get_code	= qcom_pwrkey_get_code,
};

static const struct udevice_id qcom_pwrkey_ids[] = {
	{ .compatible = "qcom,pm8916-pon" },
	{ .compatible = "qcom,pm8941-pon" },
	{ .compatible = "qcom,pm8998-pon" },
	{ .compatible = "qcom,pmk8350-pon" },
	{ }
};

U_BOOT_DRIVER(qcom_pwrkey) = {
	.name = "qcom_pwrkey",
	.id = UCLASS_BUTTON,
	.of_match = qcom_pwrkey_ids,
	.bind = button_qcom_pmic_bind,
	.probe = qcom_pwrkey_probe,
	.ops = &button_qcom_pmic_ops,
	.priv_auto = sizeof(struct qcom_pmic_btn_priv),
};
