// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Nuvoton Technology Corporation

#include <linux/bcd.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/rtc.h>
#include <linux/slab.h>

#define NCT3018Y_REG_SC		0x00 /* seconds */
#define NCT3018Y_REG_SCA	0x01 /* alarm */
#define NCT3018Y_REG_MN		0x02
#define NCT3018Y_REG_MNA	0x03 /* alarm */
#define NCT3018Y_REG_HR		0x04
#define NCT3018Y_REG_HRA	0x05 /* alarm */
#define NCT3018Y_REG_DW		0x06
#define NCT3018Y_REG_DM		0x07
#define NCT3018Y_REG_MO		0x08
#define NCT3018Y_REG_YR		0x09
#define NCT3018Y_REG_CTRL	0x0A /* timer control */
#define NCT3018Y_REG_ST		0x0B /* status */
#define NCT3018Y_REG_CLKO	0x0C /* clock out */
#define NCT3018Y_REG_PART	0x21 /* part info */

#define NCT3018Y_BIT_AF		BIT(7)
#define NCT3018Y_BIT_ST		BIT(7)
#define NCT3018Y_BIT_DM		BIT(6)
#define NCT3018Y_BIT_HF		BIT(5)
#define NCT3018Y_BIT_DSM	BIT(4)
#define NCT3018Y_BIT_AIE	BIT(3)
#define NCT3018Y_BIT_OFIE	BIT(2)
#define NCT3018Y_BIT_CIE	BIT(1)
#define NCT3018Y_BIT_TWO	BIT(0)

#define NCT3018Y_REG_BAT_MASK		0x07
#define NCT3018Y_REG_CLKO_F_MASK	0x03 /* frequenc mask */
#define NCT3018Y_REG_CLKO_CKE		0x80 /* clock out enabled */
#define NCT3018Y_REG_PART_NCT3018Y	0x02

struct nct3018y {
	struct rtc_device *rtc;
	struct i2c_client *client;
	int part_num;
#ifdef CONFIG_COMMON_CLK
	struct clk_hw clkout_hw;
#endif
};

static int nct3018y_set_alarm_mode(struct i2c_client *client, bool on)
{
	int err, flags;

	dev_dbg(&client->dev, "%s:on:%d\n", __func__, on);

	flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
	if (flags < 0) {
		dev_dbg(&client->dev,
			"Failed to read NCT3018Y_REG_CTRL\n");
		return flags;
	}

	if (on)
		flags |= NCT3018Y_BIT_AIE;
	else
		flags &= ~NCT3018Y_BIT_AIE;

	flags |= NCT3018Y_BIT_CIE;
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
		return err;
	}

	flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST);
	if (flags < 0) {
		dev_dbg(&client->dev,
			"Failed to read NCT3018Y_REG_ST\n");
		return flags;
	}

	flags &= ~(NCT3018Y_BIT_AF);
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_ST\n");
		return err;
	}

	return 0;
}

static int nct3018y_get_alarm_mode(struct i2c_client *client, unsigned char *alarm_enable,
				   unsigned char *alarm_flag)
{
	int flags;

	if (alarm_enable) {
		dev_dbg(&client->dev, "%s:NCT3018Y_REG_CTRL\n", __func__);
		flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
		if (flags < 0)
			return flags;
		*alarm_enable = flags & NCT3018Y_BIT_AIE;
		dev_dbg(&client->dev, "%s:alarm_enable:%x\n", __func__, *alarm_enable);

	}

	if (alarm_flag) {
		dev_dbg(&client->dev, "%s:NCT3018Y_REG_ST\n", __func__);
		flags =  i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST);
		if (flags < 0)
			return flags;
		*alarm_flag = flags & NCT3018Y_BIT_AF;
		dev_dbg(&client->dev, "%s:alarm_flag:%x\n", __func__, *alarm_flag);
	}

	return 0;
}

static irqreturn_t nct3018y_irq(int irq, void *dev_id)
{
	struct nct3018y *nct3018y = i2c_get_clientdata(dev_id);
	struct i2c_client *client = nct3018y->client;
	int err;
	unsigned char alarm_flag;
	unsigned char alarm_enable;

	dev_dbg(&client->dev, "%s:irq:%d\n", __func__, irq);
	err = nct3018y_get_alarm_mode(nct3018y->client, &alarm_enable, &alarm_flag);
	if (err)
		return IRQ_NONE;

	if (alarm_flag) {
		dev_dbg(&client->dev, "%s:alarm flag:%x\n",
			__func__, alarm_flag);
		rtc_update_irq(nct3018y->rtc, 1, RTC_IRQF | RTC_AF);
		nct3018y_set_alarm_mode(nct3018y->client, 0);
		dev_dbg(&client->dev, "%s:IRQ_HANDLED\n", __func__);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

/*
 * In the routines that deal directly with the nct3018y hardware, we use
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
 */
static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	unsigned char buf[10];
	int err;

	err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_ST, 1, buf);
	if (err < 0)
		return err;

	if (!buf[0]) {
		dev_dbg(&client->dev, " voltage <=1.7, date/time is not reliable.\n");
		return -EINVAL;
	}

	err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SC, sizeof(buf), buf);
	if (err < 0)
		return err;

	tm->tm_sec = bcd2bin(buf[0] & 0x7F);
	tm->tm_min = bcd2bin(buf[2] & 0x7F);
	tm->tm_hour = bcd2bin(buf[4] & 0x3F);
	tm->tm_wday = buf[6] & 0x07;
	tm->tm_mday = bcd2bin(buf[7] & 0x3F);
	tm->tm_mon = bcd2bin(buf[8] & 0x1F) - 1;
	tm->tm_year = bcd2bin(buf[9]) + 100;

	return 0;
}

static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct nct3018y *nct3018y = dev_get_drvdata(dev);
	unsigned char buf[4] = {0};
	int err, flags;
	int restore_flags = 0;

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
	if (flags < 0) {
		dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_CTRL.\n");
		return flags;
	}

	/* Check and set TWO bit */
	if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y && !(flags & NCT3018Y_BIT_TWO)) {
		restore_flags = 1;
		flags |= NCT3018Y_BIT_TWO;
		err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
		if (err < 0) {
			dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
			return err;
		}
	}

	buf[0] = bin2bcd(tm->tm_sec);
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SC, buf[0]);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SC\n");
		return err;
	}

	buf[0] = bin2bcd(tm->tm_min);
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MN, buf[0]);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MN\n");
		return err;
	}

	buf[0] = bin2bcd(tm->tm_hour);
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HR, buf[0]);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HR\n");
		return err;
	}

	buf[0] = tm->tm_wday & 0x07;
	buf[1] = bin2bcd(tm->tm_mday);
	buf[2] = bin2bcd(tm->tm_mon + 1);
	buf[3] = bin2bcd(tm->tm_year - 100);
	err = i2c_smbus_write_i2c_block_data(client, NCT3018Y_REG_DW,
					     sizeof(buf), buf);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write for day and mon and year\n");
		return -EIO;
	}

	/* Restore TWO bit */
	if (restore_flags) {
		if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y)
			flags &= ~NCT3018Y_BIT_TWO;

		err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
		if (err < 0) {
			dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
			return err;
		}
	}

	return err;
}

static int nct3018y_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	unsigned char buf[5];
	int err;

	err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SCA,
					    sizeof(buf), buf);
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to read date\n");
		return -EIO;
	}

	dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n",
		__func__, buf[0], buf[2], buf[4]);

	tm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
	tm->time.tm_min = bcd2bin(buf[2] & 0x7F);
	tm->time.tm_hour = bcd2bin(buf[4] & 0x3F);

	err = nct3018y_get_alarm_mode(client, &tm->enabled, &tm->pending);
	if (err < 0)
		return err;

	dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n",
		__func__, tm->time.tm_sec, tm->time.tm_min,
		tm->time.tm_hour, tm->enabled, tm->pending);

	return 0;
}

static int nct3018y_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	int err;

	dev_dbg(dev, "%s, sec=%d, min=%d hour=%d tm->enabled:%d\n",
		__func__, tm->time.tm_sec, tm->time.tm_min, tm->time.tm_hour,
		tm->enabled);

	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SCA, bin2bcd(tm->time.tm_sec));
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SCA\n");
		return err;
	}

	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MNA, bin2bcd(tm->time.tm_min));
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MNA\n");
		return err;
	}

	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HRA, bin2bcd(tm->time.tm_hour));
	if (err < 0) {
		dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HRA\n");
		return err;
	}

	return nct3018y_set_alarm_mode(client, tm->enabled);
}

static int nct3018y_irq_enable(struct device *dev, unsigned int enabled)
{
	dev_dbg(dev, "%s: alarm enable=%d\n", __func__, enabled);

	return nct3018y_set_alarm_mode(to_i2c_client(dev), enabled);
}

static int nct3018y_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	struct i2c_client *client = to_i2c_client(dev);
	int status, flags = 0;

	switch (cmd) {
	case RTC_VL_READ:
		status = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST);
		if (status < 0)
			return status;

		if (!(status & NCT3018Y_REG_BAT_MASK))
			flags |= RTC_VL_DATA_INVALID;

		return put_user(flags, (unsigned int __user *)arg);

	default:
		return -ENOIOCTLCMD;
	}
}

#ifdef CONFIG_COMMON_CLK
/*
 * Handling of the clkout
 */

#define clkout_hw_to_nct3018y(_hw) container_of(_hw, struct nct3018y, clkout_hw)

static const int clkout_rates[] = {
	32768,
	1024,
	32,
	1,
};

static unsigned long nct3018y_clkout_recalc_rate(struct clk_hw *hw,
						 unsigned long parent_rate)
{
	struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw);
	struct i2c_client *client = nct3018y->client;
	int flags;

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO);
	if (flags < 0)
		return 0;

	flags &= NCT3018Y_REG_CLKO_F_MASK;
	return clkout_rates[flags];
}

static int nct3018y_clkout_determine_rate(struct clk_hw *hw,
					  struct clk_rate_request *req)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
		if (clkout_rates[i] <= req->rate) {
			req->rate = clkout_rates[i];

			return 0;
		}

	req->rate = clkout_rates[0];

	return 0;
}

static int nct3018y_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
				    unsigned long parent_rate)
{
	struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw);
	struct i2c_client *client = nct3018y->client;
	int i, flags;

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO);
	if (flags < 0)
		return flags;

	for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
		if (clkout_rates[i] == rate) {
			flags &= ~NCT3018Y_REG_CLKO_F_MASK;
			flags |= i;
			return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags);
		}

	return -EINVAL;
}

static int nct3018y_clkout_control(struct clk_hw *hw, bool enable)
{
	struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw);
	struct i2c_client *client = nct3018y->client;
	int flags;

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO);
	if (flags < 0)
		return flags;

	if (enable)
		flags |= NCT3018Y_REG_CLKO_CKE;
	else
		flags &= ~NCT3018Y_REG_CLKO_CKE;

	return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags);
}

static int nct3018y_clkout_prepare(struct clk_hw *hw)
{
	return nct3018y_clkout_control(hw, 1);
}

static void nct3018y_clkout_unprepare(struct clk_hw *hw)
{
	nct3018y_clkout_control(hw, 0);
}

static int nct3018y_clkout_is_prepared(struct clk_hw *hw)
{
	struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw);
	struct i2c_client *client = nct3018y->client;
	int flags;

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO);
	if (flags < 0)
		return flags;

	return flags & NCT3018Y_REG_CLKO_CKE;
}

static const struct clk_ops nct3018y_clkout_ops = {
	.prepare = nct3018y_clkout_prepare,
	.unprepare = nct3018y_clkout_unprepare,
	.is_prepared = nct3018y_clkout_is_prepared,
	.recalc_rate = nct3018y_clkout_recalc_rate,
	.determine_rate = nct3018y_clkout_determine_rate,
	.set_rate = nct3018y_clkout_set_rate,
};

static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y)
{
	struct i2c_client *client = nct3018y->client;
	struct device_node *node = client->dev.of_node;
	struct clk_init_data init = {};
	struct clk *clk;

	init.name = "nct3018y-clkout";
	init.ops = &nct3018y_clkout_ops;
	init.flags = 0;
	init.parent_names = NULL;
	init.num_parents = 0;
	nct3018y->clkout_hw.init = &init;

	/* optional override of the clockname */
	of_property_read_string(node, "clock-output-names", &init.name);

	/* register the clock */
	clk = devm_clk_register(&client->dev, &nct3018y->clkout_hw);

	if (!IS_ERR(clk))
		of_clk_add_provider(node, of_clk_src_simple_get, clk);

	return clk;
}
#endif

static const struct rtc_class_ops nct3018y_rtc_ops = {
	.read_time	= nct3018y_rtc_read_time,
	.set_time	= nct3018y_rtc_set_time,
	.read_alarm	= nct3018y_rtc_read_alarm,
	.set_alarm	= nct3018y_rtc_set_alarm,
	.alarm_irq_enable = nct3018y_irq_enable,
	.ioctl		= nct3018y_ioctl,
};

static int nct3018y_probe(struct i2c_client *client)
{
	struct nct3018y *nct3018y;
	int err, flags;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
				     I2C_FUNC_SMBUS_BYTE |
				     I2C_FUNC_SMBUS_BLOCK_DATA))
		return -ENODEV;

	nct3018y = devm_kzalloc(&client->dev, sizeof(struct nct3018y),
				GFP_KERNEL);
	if (!nct3018y)
		return -ENOMEM;

	i2c_set_clientdata(client, nct3018y);
	nct3018y->client = client;
	device_set_wakeup_capable(&client->dev, 1);

	flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
	if (flags < 0) {
		dev_dbg(&client->dev, "%s: read error\n", __func__);
		return flags;
	} else if (flags & NCT3018Y_BIT_TWO) {
		dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
	}

	nct3018y->part_num = i2c_smbus_read_byte_data(client, NCT3018Y_REG_PART);
	if (nct3018y->part_num < 0) {
		dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_PART.\n");
		return nct3018y->part_num;
	} else {
		nct3018y->part_num &= 0x03; /* Part number is corresponding to bit 0 and 1 */
		if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y) {
			flags = NCT3018Y_BIT_HF;
			err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
			if (err < 0) {
				dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
				return err;
			}
		}
	}

	flags = 0;
	err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags);
	if (err < 0) {
		dev_dbg(&client->dev, "%s: write error\n", __func__);
		return err;
	}

	nct3018y->rtc = devm_rtc_allocate_device(&client->dev);
	if (IS_ERR(nct3018y->rtc))
		return PTR_ERR(nct3018y->rtc);

	nct3018y->rtc->ops = &nct3018y_rtc_ops;
	nct3018y->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
	nct3018y->rtc->range_max = RTC_TIMESTAMP_END_2099;

	if (client->irq > 0) {
		err = devm_request_threaded_irq(&client->dev, client->irq,
						NULL, nct3018y_irq,
						IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
						"nct3018y", client);
		if (err) {
			dev_dbg(&client->dev, "unable to request IRQ %d\n", client->irq);
			return err;
		}
	} else {
		clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, nct3018y->rtc->features);
		clear_bit(RTC_FEATURE_ALARM, nct3018y->rtc->features);
	}

#ifdef CONFIG_COMMON_CLK
	/* register clk in common clk framework */
	nct3018y_clkout_register_clk(nct3018y);
#endif

	return devm_rtc_register_device(nct3018y->rtc);
}

static const struct i2c_device_id nct3018y_id[] = {
	{ .name = "nct3018y" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, nct3018y_id);

static const struct of_device_id nct3018y_of_match[] = {
	{ .compatible = "nuvoton,nct3018y" },
	{}
};
MODULE_DEVICE_TABLE(of, nct3018y_of_match);

static struct i2c_driver nct3018y_driver = {
	.driver		= {
		.name	= "rtc-nct3018y",
		.of_match_table = nct3018y_of_match,
	},
	.probe		= nct3018y_probe,
	.id_table	= nct3018y_id,
};

module_i2c_driver(nct3018y_driver);

MODULE_AUTHOR("Medad CChien <ctcchien@nuvoton.com>");
MODULE_AUTHOR("Mia Lin <mimi05633@gmail.com>");
MODULE_DESCRIPTION("Nuvoton NCT3018Y RTC driver");
MODULE_LICENSE("GPL");
