// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the RTC found in the SpacemiT P1 PMIC
 *
 * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
 */

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/rtc.h>

#define MOD_NAME	"spacemit-p1-rtc"

/*
 * Six consecutive 1-byte registers hold the seconds, minutes, hours,
 * day-of-month, month, and year (respectively).
 *
 * The range of values in these registers is:
 *    seconds	0-59
 *    minutes	0-59
 *    hours	0-59
 *    day	0-30 (struct tm is 1-31)
 *    month	0-11
 *    year	years since 2000 (struct tm is since 1900)
 *
 * Note that the day and month must be converted after reading and
 * before writing.
 */
#define RTC_TIME		0x0d	/* Offset of the seconds register */

#define RTC_CTRL		0x1d
#define RTC_EN		BIT(2)

/* Number of attempts to read a consistent time stamp before giving up */
#define RTC_READ_TRIES		20	/* At least 1 */

struct p1_rtc {
	struct regmap *regmap;
	struct rtc_device *rtc;
};

/*
 * The P1 hardware documentation states that the register values are
 * latched to ensure a consistent time snapshot within the registers,
 * but these are in fact unstable due to a bug in the hardware design.
 * So we loop until we get two identical readings.
 */
static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
{
	struct p1_rtc *p1 = dev_get_drvdata(dev);
	struct regmap *regmap = p1->regmap;
	u32 count = RTC_READ_TRIES;
	u8 seconds;
	u8 time[6];
	int ret;

	ret = regmap_test_bits(regmap, RTC_CTRL, RTC_EN);
	if (ret <= 0)
		return ret ?: -EINVAL;	/* RTC is disabled or error */

	ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
	if (ret)
		return ret;

	do {
		seconds = time[0];
		ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
		if (ret)
			return ret;
	} while (time[0] != seconds && --count);

	if (!count)
		return -EIO;		/* Unable to get a consistent result */

	t->tm_sec = time[0] & GENMASK(5, 0);
	t->tm_min = time[1] & GENMASK(5, 0);
	t->tm_hour = time[2] & GENMASK(4, 0);
	t->tm_mday = (time[3] & GENMASK(4, 0)) + 1;
	t->tm_mon = time[4] & GENMASK(3, 0);
	t->tm_year = (time[5] & GENMASK(5, 0)) + 100;

	return 0;
}

/*
 * The P1 hardware documentation states that values in the registers are
 * latched so when written they represent a consistent time snapshot.
 * Nevertheless, this is not guaranteed by the implementation, so we must
 * disable the RTC while updating it.
 */
static int p1_rtc_set_time(struct device *dev, struct rtc_time *t)
{
	struct p1_rtc *p1 = dev_get_drvdata(dev);
	struct regmap *regmap = p1->regmap;
	u8 time[6];
	int ret;

	time[0] = t->tm_sec;
	time[1] = t->tm_min;
	time[2] = t->tm_hour;
	time[3] = t->tm_mday - 1;
	time[4] = t->tm_mon;
	time[5] = t->tm_year - 100;

	/* Disable the RTC to update; re-enable again when done */
	ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN);
	if (ret)
		return ret;

	/* If something goes wrong, leave the RTC disabled */
	ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time));
	if (ret)
		return ret;

	return regmap_set_bits(regmap, RTC_CTRL, RTC_EN);
}

static const struct rtc_class_ops p1_rtc_class_ops = {
	.read_time = p1_rtc_read_time,
	.set_time = p1_rtc_set_time,
};

static int p1_rtc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rtc_device *rtc;
	struct p1_rtc *p1;

	p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL);
	if (!p1)
		return -ENOMEM;
	dev_set_drvdata(dev, p1);

	p1->regmap = dev_get_regmap(dev->parent, NULL);
	if (!p1->regmap)
		return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");

	rtc = devm_rtc_allocate_device(dev);
	if (IS_ERR(rtc))
		return dev_err_probe(dev, PTR_ERR(rtc),
				     "error allocating device\n");
	p1->rtc = rtc;

	rtc->ops = &p1_rtc_class_ops;
	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
	rtc->range_max = RTC_TIMESTAMP_END_2063;

	clear_bit(RTC_FEATURE_ALARM, rtc->features);
	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);

	return devm_rtc_register_device(rtc);
}

static struct platform_driver p1_rtc_driver = {
	.probe = p1_rtc_probe,
	.driver = {
		.name = MOD_NAME,
	},
};

module_platform_driver(p1_rtc_driver);

MODULE_DESCRIPTION("SpacemiT P1 RTC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" MOD_NAME);
