// SPDX-License-Identifier: GPL-2.0+
/*
 * Simulate an I2C real time clock
 *
 * Copyright (c) 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

/*
 * This is a test driver. It starts off with the current time of the machine,
 * but also supports setting the time, using an offset from the current
 * clock. This driver is only intended for testing, not accurate
 * time-keeping. It does not change the system time.
 */

#include <common.h>
#include <dm.h>
#include <i2c.h>
#include <log.h>
#include <os.h>
#include <rtc.h>
#include <asm/rtc.h>
#include <asm/test.h>

#ifdef DEBUG
#define debug_buffer print_buffer
#else
#define debug_buffer(x, ...)
#endif

/**
 * struct sandbox_i2c_rtc_plat_data - platform data for the RTC
 *
 * @base_time:		Base system time when RTC device was bound
 * @offset:		RTC offset from current system time
 * @use_system_time:	true to use system time, false to use @base_time
 * @reg:		Register values
 */
struct sandbox_i2c_rtc_plat_data {
	long base_time;
	long offset;
	bool use_system_time;
	u8 reg[REG_COUNT];
};

struct sandbox_i2c_rtc {
	unsigned int offset_secs;
};

long sandbox_i2c_rtc_set_offset(struct udevice *dev, bool use_system_time,
				int offset)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
	long old_offset;

	old_offset = plat->offset;
	plat->use_system_time = use_system_time;
	if (offset != -1)
		plat->offset = offset;
	os_set_time_offset(plat->offset);

	return old_offset;
}

long sandbox_i2c_rtc_get_set_base_time(struct udevice *dev, long base_time)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
	long old_base_time;

	old_base_time = plat->base_time;
	if (base_time != -1)
		plat->base_time = base_time;

	return old_base_time;
}

static void reset_time(struct udevice *dev)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
	struct rtc_time now;

	os_localtime(&now);
	plat->base_time = rtc_mktime(&now);
	plat->offset = os_get_time_offset();
	plat->use_system_time = true;
}

static int sandbox_i2c_rtc_get(struct udevice *dev, struct rtc_time *time)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
	struct rtc_time tm_now;
	long now;

	if (plat->use_system_time) {
		os_localtime(&tm_now);
		now = rtc_mktime(&tm_now);
	} else {
		now = plat->base_time;
	}

	rtc_to_tm(now + plat->offset, time);

	return 0;
}

static int sandbox_i2c_rtc_set(struct udevice *dev, const struct rtc_time *time)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
	struct rtc_time tm_now;
	long now;

	if (plat->use_system_time) {
		os_localtime(&tm_now);
		now = rtc_mktime(&tm_now);
	} else {
		now = plat->base_time;
	}
	plat->offset = rtc_mktime(time) - now;
	os_set_time_offset(plat->offset);

	return 0;
}

/* Update the current time in the registers */
static int sandbox_i2c_rtc_prepare_read(struct udevice *emul)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(emul);
	struct rtc_time time;
	int ret;

	ret = sandbox_i2c_rtc_get(emul, &time);
	if (ret)
		return ret;

	plat->reg[REG_SEC] = time.tm_sec;
	plat->reg[REG_MIN] = time.tm_min;
	plat->reg[REG_HOUR] = time.tm_hour;
	plat->reg[REG_MDAY] = time.tm_mday;
	plat->reg[REG_MON] = time.tm_mon;
	plat->reg[REG_YEAR] = time.tm_year - 1900;
	plat->reg[REG_WDAY] = time.tm_wday;

	return 0;
}

static int sandbox_i2c_rtc_complete_write(struct udevice *emul)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(emul);
	struct rtc_time time;
	int ret;

	time.tm_sec = plat->reg[REG_SEC];
	time.tm_min = plat->reg[REG_MIN];
	time.tm_hour = plat->reg[REG_HOUR];
	time.tm_mday = plat->reg[REG_MDAY];
	time.tm_mon = plat->reg[REG_MON];
	time.tm_year = plat->reg[REG_YEAR] + 1900;
	time.tm_wday = plat->reg[REG_WDAY];

	ret = sandbox_i2c_rtc_set(emul, &time);
	if (ret)
		return ret;

	return 0;
}

static int sandbox_i2c_rtc_xfer(struct udevice *emul, struct i2c_msg *msg,
				int nmsgs)
{
	struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(emul);
	uint offset = 0;
	int ret;

	debug("\n%s\n", __func__);
	ret = sandbox_i2c_rtc_prepare_read(emul);
	if (ret)
		return ret;
	for (; nmsgs > 0; nmsgs--, msg++) {
		int len;
		u8 *ptr;

		len = msg->len;
		debug("   %s: msg->len=%d",
		      msg->flags & I2C_M_RD ? "read" : "write",
		      msg->len);
		if (msg->flags & I2C_M_RD) {
			debug(", offset %x, len %x: ", offset, len);

			/* Read the register */
			memcpy(msg->buf, plat->reg + offset, len);
			memset(msg->buf + len, '\xff', msg->len - len);
			debug_buffer(0, msg->buf, 1, msg->len, 0);
		} else if (len >= 1) {
			ptr = msg->buf;
			offset = *ptr++ & (REG_COUNT - 1);
			len--;
			debug(", set offset %x: ", offset);
			debug_buffer(0, msg->buf, 1, msg->len, 0);

			/* Write the register */
			memcpy(plat->reg + offset, ptr, len);
			/* If the reset register was written to, do reset. */
			if (offset <= REG_RESET && REG_RESET < offset + len)
				reset_time(emul);
		}
	}
	ret = sandbox_i2c_rtc_complete_write(emul);
	if (ret)
		return ret;

	return 0;
}

struct dm_i2c_ops sandbox_i2c_rtc_emul_ops = {
	.xfer = sandbox_i2c_rtc_xfer,
};

static int sandbox_i2c_rtc_bind(struct udevice *dev)
{
	reset_time(dev);

	return 0;
}

static const struct udevice_id sandbox_i2c_rtc_ids[] = {
	{ .compatible = "sandbox,i2c-rtc" },
	{ }
};

U_BOOT_DRIVER(sandbox_i2c_rtc_emul) = {
	.name		= "sandbox_i2c_rtc_emul",
	.id		= UCLASS_I2C_EMUL,
	.of_match	= sandbox_i2c_rtc_ids,
	.bind		= sandbox_i2c_rtc_bind,
	.priv_auto	= sizeof(struct sandbox_i2c_rtc),
	.plat_auto	= sizeof(struct sandbox_i2c_rtc_plat_data),
	.ops		= &sandbox_i2c_rtc_emul_ops,
};
