// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018-2022 Denx Software Engineering GmbH
 * Heiko Schocher <hs@denx.de>
 * Philip Oberfichtner <pro@denx.de>
 *
 * A bootcount driver using the registers MEMA - MEMD on the PFUZE100.
 * This works only, if the PMIC is not connected.
 */

#include <common.h>
#include <bootcount.h>
#include <dm.h>
#include <power/pmic.h>
#include <power/pfuze100_pmic.h>

DECLARE_GLOBAL_DATA_PTR;

#define PFUZE_BC_MAGIC 0xdead

struct bootcount_pmic_priv {
	struct udevice *pmic;
};

static int pfuze100_get_magic(struct udevice *dev, u32 *magic)
{
	int ret;

	ret = pmic_reg_read(dev, PFUZE100_MEMA);
	if (ret < 0)
		return ret;
	*magic = ret;

	ret = pmic_reg_read(dev, PFUZE100_MEMB);
	if (ret < 0)
		return ret;
	*magic += ret << 8;

	return 0;
}

static int pfuze100_set_magic(struct udevice *dev)
{
	int ret;

	ret = pmic_reg_write(dev, PFUZE100_MEMA, PFUZE_BC_MAGIC & 0xff);
	if (ret)
		return ret;

	ret = pmic_reg_write(dev, PFUZE100_MEMB, (PFUZE_BC_MAGIC >> 8) & 0xff);
	return ret;
}

static int pfuze100_get_value(struct udevice *dev, u32 *a)
{
	int ret;

	ret = pmic_reg_read(dev, PFUZE100_MEMC);
	if (ret < 0)
		return ret;
	*a = ret;

	ret = pmic_reg_read(dev, PFUZE100_MEMD);
	if (ret < 0)
		return ret;
	*a += ret << 8;

	return 0;
}

static int pfuze100_set_value(struct udevice *dev, u32 val)
{
	int ret;

	ret = pmic_reg_write(dev, PFUZE100_MEMC, val & 0xff);
	if (ret)
		return ret;

	ret = pmic_reg_write(dev, PFUZE100_MEMD, (val >> 8) & 0xff);
	return ret;
}

static int bootcount_pmic_set(struct udevice *dev, const u32 a)
{
	struct bootcount_pmic_priv *priv = dev_get_priv(dev);

	if (pfuze100_set_magic(priv->pmic)) {
		debug("%s: writing magic failed\n", __func__);
		return -EIO;
	}

	if (pfuze100_set_value(priv->pmic, a)) {
		debug("%s: writing value failed\n", __func__);
		return -EIO;
	}

	return 0;
}

static int bootcount_pmic_get(struct udevice *dev, u32 *a)
{
	struct bootcount_pmic_priv *priv = dev_get_priv(dev);
	u32 magic;

	if (pfuze100_get_magic(priv->pmic, &magic)) {
		debug("%s: reading magic failed\n", __func__);
		return -EIO;
	}

	if (magic != PFUZE_BC_MAGIC) {
		*a = 0;
		return 0;
	}

	if (pfuze100_get_value(priv->pmic, a)) {
		debug("%s: reading value failed\n", __func__);
		return -EIO;
	}

	return 0;
}

static int bootcount_pmic_probe(struct udevice *dev)
{
	struct ofnode_phandle_args phandle_args;
	struct bootcount_pmic_priv *priv = dev_get_priv(dev);
	struct udevice *pmic;

	if (dev_read_phandle_with_args(dev, "pmic", NULL, 0, 0, &phandle_args)) {
		debug("%s: pmic backing device not specified\n", dev->name);
		return -ENOENT;
	}

	if (uclass_get_device_by_ofnode(UCLASS_PMIC, phandle_args.node, &pmic)) {
		debug("%s: could not get backing device\n", dev->name);
		return -ENODEV;
	}

	priv->pmic = pmic;

	return 0;
}

static const struct bootcount_ops bootcount_pmic_ops = {
	.get = bootcount_pmic_get,
	.set = bootcount_pmic_set,
};

static const struct udevice_id bootcount_pmic_ids[] = {
	{ .compatible = "u-boot,bootcount-pmic" },
	{ }
};

U_BOOT_DRIVER(bootcount_pmic) = {
	.name	= "bootcount-pmic",
	.id	= UCLASS_BOOTCOUNT,
	.priv_auto	= sizeof(struct bootcount_pmic_priv),
	.probe	= bootcount_pmic_probe,
	.of_match = bootcount_pmic_ids,
	.ops	= &bootcount_pmic_ops,
};
