// SPDX-License-Identifier: GPL-2.0-only
/*
 * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
 * Based on "Real Time Clock driver for msb252x." that was contained
 * in various MStar kernels.
 *
 * (C) 2019 Daniel Palmer
 * (C) 2021 Romain Perier
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>

/* Registers */
#define REG_RTC_CTRL		0x00
#define REG_RTC_FREQ_CW_L	0x04
#define REG_RTC_FREQ_CW_H	0x08
#define REG_RTC_LOAD_VAL_L	0x0C
#define REG_RTC_LOAD_VAL_H	0x10
#define REG_RTC_MATCH_VAL_L	0x14
#define REG_RTC_MATCH_VAL_H	0x18
#define REG_RTC_STATUS_INT	0x1C
#define REG_RTC_CNT_VAL_L	0x20
#define REG_RTC_CNT_VAL_H	0x24

/* Control bits for REG_RTC_CTRL */
#define SOFT_RSTZ_BIT		BIT(0)
#define CNT_EN_BIT		BIT(1)
#define WRAP_EN_BIT		BIT(2)
#define LOAD_EN_BIT		BIT(3)
#define READ_EN_BIT		BIT(4)
#define INT_MASK_BIT		BIT(5)
#define INT_FORCE_BIT		BIT(6)
#define INT_CLEAR_BIT		BIT(7)

/* Control bits for REG_RTC_STATUS_INT */
#define RAW_INT_BIT		BIT(0)
#define ALM_INT_BIT		BIT(1)

struct msc313_rtc {
	struct rtc_device *rtc_dev;
	void __iomem *rtc_base;
};

static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
	struct msc313_rtc *priv = dev_get_drvdata(dev);
	unsigned long seconds;

	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
			| ((unsigned long)readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);

	rtc_time64_to_tm(seconds, &alarm->time);

	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
		alarm->enabled = 1;

	return 0;
}

static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct msc313_rtc *priv = dev_get_drvdata(dev);
	u16 reg;

	reg = readw(priv->rtc_base + REG_RTC_CTRL);
	if (enabled)
		reg &= ~INT_MASK_BIT;
	else
		reg |= INT_MASK_BIT;
	writew(reg, priv->rtc_base + REG_RTC_CTRL);
	return 0;
}

static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
	struct msc313_rtc *priv = dev_get_drvdata(dev);
	unsigned long seconds;

	seconds = rtc_tm_to_time64(&alarm->time);
	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);

	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);

	return 0;
}

static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
{
	return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
}

static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
{
	u16 reg;

	reg = readw(priv->rtc_base + REG_RTC_CTRL);
	reg |= CNT_EN_BIT;
	writew(reg, priv->rtc_base + REG_RTC_CTRL);
}

static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct msc313_rtc *priv = dev_get_drvdata(dev);
	u32 seconds;
	u16 reg;

	if (!msc313_rtc_get_enabled(priv))
		return -EINVAL;

	reg = readw(priv->rtc_base + REG_RTC_CTRL);
	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);

	/* Wait for HW latch done */
	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
		udelay(1);

	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
			| ((unsigned long)readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);

	rtc_time64_to_tm(seconds, tm);

	return 0;
}

static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct msc313_rtc *priv = dev_get_drvdata(dev);
	unsigned long seconds;
	u16 reg;

	seconds = rtc_tm_to_time64(tm);
	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);

	/* Enable load for loading value into internal RTC counter */
	reg = readw(priv->rtc_base + REG_RTC_CTRL);
	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);

	/* Wait for HW latch done */
	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
		udelay(1);
	msc313_rtc_set_enabled(priv);
	return 0;
}

static const struct rtc_class_ops msc313_rtc_ops = {
	.read_time = msc313_rtc_read_time,
	.set_time = msc313_rtc_set_time,
	.read_alarm = msc313_rtc_read_alarm,
	.set_alarm = msc313_rtc_set_alarm,
	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
};

static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
{
	struct msc313_rtc *priv = dev_id;
	u16 reg;

	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
	if (!(reg & ALM_INT_BIT))
		return IRQ_NONE;

	reg = readw(priv->rtc_base + REG_RTC_CTRL);
	reg |= INT_CLEAR_BIT;
	reg &= ~INT_FORCE_BIT;
	writew(reg, priv->rtc_base + REG_RTC_CTRL);

	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);

	return IRQ_HANDLED;
}

static int msc313_rtc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct msc313_rtc *priv;
	unsigned long rate;
	struct clk *clk;
	int ret;
	int irq;

	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv->rtc_base))
		return PTR_ERR(priv->rtc_base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return -EINVAL;

	priv->rtc_dev = devm_rtc_allocate_device(dev);
	if (IS_ERR(priv->rtc_dev))
		return PTR_ERR(priv->rtc_dev);

	priv->rtc_dev->ops = &msc313_rtc_ops;
	priv->rtc_dev->range_max = U32_MAX;

	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
			       dev_name(&pdev->dev), priv);
	if (ret) {
		dev_err(dev, "Could not request IRQ\n");
		return ret;
	}

	clk = devm_clk_get_enabled(dev, NULL);
	if (IS_ERR(clk)) {
		dev_err(dev, "No input reference clock\n");
		return PTR_ERR(clk);
	}

	rate = clk_get_rate(clk);
	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);

	platform_set_drvdata(pdev, priv);

	return devm_rtc_register_device(priv->rtc_dev);
}

static const struct of_device_id msc313_rtc_of_match_table[] = {
	{ .compatible = "mstar,msc313-rtc" },
	{ }
};
MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);

static struct platform_driver msc313_rtc_driver = {
	.probe = msc313_rtc_probe,
	.driver = {
		.name = "msc313-rtc",
		.of_match_table = msc313_rtc_of_match_table,
	},
};

module_platform_driver(msc313_rtc_driver);

MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");
MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
MODULE_DESCRIPTION("MStar RTC Driver");
MODULE_LICENSE("GPL v2");
