// SPDX-License-Identifier: GPL-2.0
/*
 * RTC driver for the Micro Crystal RV3028
 *
 * Copyright (C) 2019 Micro Crystal SA
 *
 * Alexandre Belloni <alexandre.belloni@bootlin.com>
 *
 */

#include <linux/clk-provider.h>
#include <linux/bcd.h>
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/rtc.h>

#define RV3028_SEC			0x00
#define RV3028_MIN			0x01
#define RV3028_HOUR			0x02
#define RV3028_WDAY			0x03
#define RV3028_DAY			0x04
#define RV3028_MONTH			0x05
#define RV3028_YEAR			0x06
#define RV3028_ALARM_MIN		0x07
#define RV3028_ALARM_HOUR		0x08
#define RV3028_ALARM_DAY		0x09
#define RV3028_STATUS			0x0E
#define RV3028_CTRL1			0x0F
#define RV3028_CTRL2			0x10
#define RV3028_EVT_CTRL			0x13
#define RV3028_TS_COUNT			0x14
#define RV3028_TS_SEC			0x15
#define RV3028_RAM1			0x1F
#define RV3028_EEPROM_ADDR		0x25
#define RV3028_EEPROM_DATA		0x26
#define RV3028_EEPROM_CMD		0x27
#define RV3028_CLKOUT			0x35
#define RV3028_OFFSET			0x36
#define RV3028_BACKUP			0x37

#define RV3028_STATUS_PORF		BIT(0)
#define RV3028_STATUS_EVF		BIT(1)
#define RV3028_STATUS_AF		BIT(2)
#define RV3028_STATUS_TF		BIT(3)
#define RV3028_STATUS_UF		BIT(4)
#define RV3028_STATUS_BSF		BIT(5)
#define RV3028_STATUS_CLKF		BIT(6)
#define RV3028_STATUS_EEBUSY		BIT(7)

#define RV3028_CLKOUT_FD_MASK		GENMASK(2, 0)
#define RV3028_CLKOUT_PORIE		BIT(3)
#define RV3028_CLKOUT_CLKSY		BIT(6)
#define RV3028_CLKOUT_CLKOE		BIT(7)

#define RV3028_CTRL1_EERD		BIT(3)
#define RV3028_CTRL1_WADA		BIT(5)

#define RV3028_CTRL2_RESET		BIT(0)
#define RV3028_CTRL2_12_24		BIT(1)
#define RV3028_CTRL2_EIE		BIT(2)
#define RV3028_CTRL2_AIE		BIT(3)
#define RV3028_CTRL2_TIE		BIT(4)
#define RV3028_CTRL2_UIE		BIT(5)
#define RV3028_CTRL2_TSE		BIT(7)

#define RV3028_EVT_CTRL_TSR		BIT(2)

#define RV3028_EEPROM_CMD_UPDATE	0x11
#define RV3028_EEPROM_CMD_WRITE		0x21
#define RV3028_EEPROM_CMD_READ		0x22

#define RV3028_EEBUSY_POLL		10000
#define RV3028_EEBUSY_TIMEOUT		100000

#define RV3028_BACKUP_TCE		BIT(5)
#define RV3028_BACKUP_TCR_MASK		GENMASK(1,0)

#define OFFSET_STEP_PPT			953674

enum rv3028_type {
	rv_3028,
};

struct rv3028_data {
	struct regmap *regmap;
	struct rtc_device *rtc;
	enum rv3028_type type;
#ifdef CONFIG_COMMON_CLK
	struct clk_hw clkout_hw;
#endif
};

static u16 rv3028_trickle_resistors[] = {3000, 5000, 9000, 15000};

static ssize_t timestamp0_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);

	regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR,
			   RV3028_EVT_CTRL_TSR);

	return count;
};

static ssize_t timestamp0_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
	struct rtc_time tm;
	int ret, count;
	u8 date[6];

	ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
	if (ret)
		return ret;

	if (!count)
		return 0;

	ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date,
			       sizeof(date));
	if (ret)
		return ret;

	tm.tm_sec = bcd2bin(date[0]);
	tm.tm_min = bcd2bin(date[1]);
	tm.tm_hour = bcd2bin(date[2]);
	tm.tm_mday = bcd2bin(date[3]);
	tm.tm_mon = bcd2bin(date[4]) - 1;
	tm.tm_year = bcd2bin(date[5]) + 100;

	ret = rtc_valid_tm(&tm);
	if (ret)
		return ret;

	return sprintf(buf, "%llu\n",
		       (unsigned long long)rtc_tm_to_time64(&tm));
};

static DEVICE_ATTR_RW(timestamp0);

static ssize_t timestamp0_count_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
	int ret, count;

	ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
	if (ret)
		return ret;

	return sprintf(buf, "%u\n", count);
};

static DEVICE_ATTR_RO(timestamp0_count);

static struct attribute *rv3028_attrs[] = {
	&dev_attr_timestamp0.attr,
	&dev_attr_timestamp0_count.attr,
	NULL
};

static const struct attribute_group rv3028_attr_group = {
	.attrs	= rv3028_attrs,
};

static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd)
{
	if (eerd)
		return 0;

	return regmap_update_bits(rv3028->regmap, RV3028_CTRL1, RV3028_CTRL1_EERD, 0);
}

static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd)
{
	u32 ctrl1, status;
	int ret;

	ret = regmap_read(rv3028->regmap, RV3028_CTRL1, &ctrl1);
	if (ret)
		return ret;

	*eerd = ctrl1 & RV3028_CTRL1_EERD;
	if (*eerd)
		return 0;

	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
				 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
	if (ret)
		return ret;

	ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
				       !(status & RV3028_STATUS_EEBUSY),
				       RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
	if (ret) {
		rv3028_exit_eerd(rv3028, *eerd);

		return ret;
	}

	return 0;
}

static int rv3028_update_eeprom(struct rv3028_data *rv3028, u32 eerd)
{
	u32 status;
	int ret;

	ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
	if (ret)
		goto exit_eerd;

	ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, RV3028_EEPROM_CMD_UPDATE);
	if (ret)
		goto exit_eerd;

	usleep_range(63000, RV3028_EEBUSY_TIMEOUT);

	ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
				       !(status & RV3028_STATUS_EEBUSY),
				       RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);

exit_eerd:
	rv3028_exit_eerd(rv3028, eerd);

	return ret;
}

static int rv3028_update_cfg(struct rv3028_data *rv3028, unsigned int reg,
			     unsigned int mask, unsigned int val)
{
	u32 eerd;
	int ret;

	ret = rv3028_enter_eerd(rv3028, &eerd);
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3028->regmap, reg, mask, val);
	if (ret) {
		rv3028_exit_eerd(rv3028, eerd);
		return ret;
	}

	return rv3028_update_eeprom(rv3028, eerd);
}

static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
{
	struct rv3028_data *rv3028 = dev_id;
	unsigned long events = 0;
	u32 status = 0, ctrl = 0;

	if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 ||
	   status == 0) {
		return IRQ_NONE;
	}

	if (status & RV3028_STATUS_PORF)
		dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");

	if (status & RV3028_STATUS_TF) {
		status |= RV3028_STATUS_TF;
		ctrl |= RV3028_CTRL2_TIE;
		events |= RTC_PF;
	}

	if (status & RV3028_STATUS_AF) {
		status |= RV3028_STATUS_AF;
		ctrl |= RV3028_CTRL2_AIE;
		events |= RTC_AF;
	}

	if (status & RV3028_STATUS_UF) {
		status |= RV3028_STATUS_UF;
		ctrl |= RV3028_CTRL2_UIE;
		events |= RTC_UF;
	}

	if (events) {
		rtc_update_irq(rv3028->rtc, 1, events);
		regmap_update_bits(rv3028->regmap, RV3028_STATUS, status, 0);
		regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ctrl, 0);
	}

	if (status & RV3028_STATUS_EVF) {
		sysfs_notify(&rv3028->rtc->dev.kobj, NULL,
			     dev_attr_timestamp0.attr.name);
		dev_warn(&rv3028->rtc->dev, "event detected");
	}

	return IRQ_HANDLED;
}

static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	u8 date[7];
	int ret, status;

	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
	if (ret < 0)
		return ret;

	if (status & RV3028_STATUS_PORF) {
		dev_warn(dev, "Voltage low, data is invalid.\n");
		return -EINVAL;
	}

	ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date));
	if (ret)
		return ret;

	tm->tm_sec  = bcd2bin(date[RV3028_SEC] & 0x7f);
	tm->tm_min  = bcd2bin(date[RV3028_MIN] & 0x7f);
	tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f);
	tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f);
	tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f);
	tm->tm_mon  = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1;
	tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100;

	return 0;
}

static int rv3028_set_time(struct device *dev, struct rtc_time *tm)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	u8 date[7];
	int ret;

	date[RV3028_SEC]   = bin2bcd(tm->tm_sec);
	date[RV3028_MIN]   = bin2bcd(tm->tm_min);
	date[RV3028_HOUR]  = bin2bcd(tm->tm_hour);
	date[RV3028_WDAY]  = 1 << (tm->tm_wday);
	date[RV3028_DAY]   = bin2bcd(tm->tm_mday);
	date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1);
	date[RV3028_YEAR]  = bin2bcd(tm->tm_year - 100);

	/*
	 * Writing to the Seconds register has the same effect as setting RESET
	 * bit to 1
	 */
	ret = regmap_bulk_write(rv3028->regmap, RV3028_SEC, date,
				sizeof(date));
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
				 RV3028_STATUS_PORF, 0);

	return ret;
}

static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	u8 alarmvals[3];
	int status, ctrl, ret;

	ret = regmap_bulk_read(rv3028->regmap, RV3028_ALARM_MIN, alarmvals,
			       sizeof(alarmvals));
	if (ret)
		return ret;

	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
	if (ret < 0)
		return ret;

	ret = regmap_read(rv3028->regmap, RV3028_CTRL2, &ctrl);
	if (ret < 0)
		return ret;

	alrm->time.tm_sec  = 0;
	alrm->time.tm_min  = bcd2bin(alarmvals[0] & 0x7f);
	alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
	alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);

	alrm->enabled = !!(ctrl & RV3028_CTRL2_AIE);
	alrm->pending = (status & RV3028_STATUS_AF) && alrm->enabled;

	return 0;
}

static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	u8 alarmvals[3];
	u8 ctrl = 0;
	int ret;

	/* The alarm has no seconds, round up to nearest minute */
	if (alrm->time.tm_sec) {
		time64_t alarm_time = rtc_tm_to_time64(&alrm->time);

		alarm_time += 60 - alrm->time.tm_sec;
		rtc_time64_to_tm(alarm_time, &alrm->time);
	}

	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
				 RV3028_CTRL2_AIE | RV3028_CTRL2_UIE, 0);
	if (ret)
		return ret;

	alarmvals[0] = bin2bcd(alrm->time.tm_min);
	alarmvals[1] = bin2bcd(alrm->time.tm_hour);
	alarmvals[2] = bin2bcd(alrm->time.tm_mday);

	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
				 RV3028_STATUS_AF, 0);
	if (ret)
		return ret;

	ret = regmap_bulk_write(rv3028->regmap, RV3028_ALARM_MIN, alarmvals,
				sizeof(alarmvals));
	if (ret)
		return ret;

	if (alrm->enabled) {
		if (rv3028->rtc->uie_rtctimer.enabled)
			ctrl |= RV3028_CTRL2_UIE;
		if (rv3028->rtc->aie_timer.enabled)
			ctrl |= RV3028_CTRL2_AIE;
	}

	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
				 RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl);

	return ret;
}

static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	int ctrl = 0, ret;

	if (enabled) {
		if (rv3028->rtc->uie_rtctimer.enabled)
			ctrl |= RV3028_CTRL2_UIE;
		if (rv3028->rtc->aie_timer.enabled)
			ctrl |= RV3028_CTRL2_AIE;
	}

	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
				 RV3028_STATUS_AF | RV3028_STATUS_UF, 0);
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
				 RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl);
	if (ret)
		return ret;

	return 0;
}

static int rv3028_read_offset(struct device *dev, long *offset)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	int ret, value, steps;

	ret = regmap_read(rv3028->regmap, RV3028_OFFSET, &value);
	if (ret < 0)
		return ret;

	steps = sign_extend32(value << 1, 8);

	ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value);
	if (ret < 0)
		return ret;

	steps += value >> 7;

	*offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000);

	return 0;
}

static int rv3028_set_offset(struct device *dev, long offset)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	u32 eerd;
	int ret;

	offset = clamp(offset, -244141L, 243187L) * 1000;
	offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);

	ret = rv3028_enter_eerd(rv3028, &eerd);
	if (ret)
		return ret;

	ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1);
	if (ret < 0)
		goto exit_eerd;

	ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
				 offset << 7);
	if (ret < 0)
		goto exit_eerd;

	return rv3028_update_eeprom(rv3028, eerd);

exit_eerd:
	rv3028_exit_eerd(rv3028, eerd);

	return ret;

}

static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
	int status, ret = 0;

	switch (cmd) {
	case RTC_VL_READ:
		ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
		if (ret < 0)
			return ret;

		status = status & RV3028_STATUS_PORF ? RTC_VL_DATA_INVALID : 0;
		return put_user(status, (unsigned int __user *)arg);

	default:
		return -ENOIOCTLCMD;
	}
}

static int rv3028_nvram_write(void *priv, unsigned int offset, void *val,
			      size_t bytes)
{
	return regmap_bulk_write(priv, RV3028_RAM1 + offset, val, bytes);
}

static int rv3028_nvram_read(void *priv, unsigned int offset, void *val,
			     size_t bytes)
{
	return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes);
}

static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
			       size_t bytes)
{
	struct rv3028_data *rv3028 = priv;
	u32 status, eerd;
	int i, ret;
	u8 *buf = val;

	ret = rv3028_enter_eerd(rv3028, &eerd);
	if (ret)
		return ret;

	for (i = 0; i < bytes; i++) {
		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
		if (ret)
			goto restore_eerd;

		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_DATA, buf[i]);
		if (ret)
			goto restore_eerd;

		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
		if (ret)
			goto restore_eerd;

		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
				   RV3028_EEPROM_CMD_WRITE);
		if (ret)
			goto restore_eerd;

		usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);

		ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
					       !(status & RV3028_STATUS_EEBUSY),
					       RV3028_EEBUSY_POLL,
					       RV3028_EEBUSY_TIMEOUT);
		if (ret)
			goto restore_eerd;
	}

restore_eerd:
	rv3028_exit_eerd(rv3028, eerd);

	return ret;
}

static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
			      size_t bytes)
{
	struct rv3028_data *rv3028 = priv;
	u32 status, eerd, data;
	int i, ret;
	u8 *buf = val;

	ret = rv3028_enter_eerd(rv3028, &eerd);
	if (ret)
		return ret;

	for (i = 0; i < bytes; i++) {
		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
		if (ret)
			goto restore_eerd;

		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
		if (ret)
			goto restore_eerd;

		ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
				   RV3028_EEPROM_CMD_READ);
		if (ret)
			goto restore_eerd;

		ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
					       !(status & RV3028_STATUS_EEBUSY),
					       RV3028_EEBUSY_POLL,
					       RV3028_EEBUSY_TIMEOUT);
		if (ret)
			goto restore_eerd;

		ret = regmap_read(rv3028->regmap, RV3028_EEPROM_DATA, &data);
		if (ret)
			goto restore_eerd;
		buf[i] = data;
	}

restore_eerd:
	rv3028_exit_eerd(rv3028, eerd);

	return ret;
}

#ifdef CONFIG_COMMON_CLK
#define clkout_hw_to_rv3028(hw) container_of(hw, struct rv3028_data, clkout_hw)

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

static unsigned long rv3028_clkout_recalc_rate(struct clk_hw *hw,
					       unsigned long parent_rate)
{
	int clkout, ret;
	struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);

	ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &clkout);
	if (ret < 0)
		return 0;

	clkout &= RV3028_CLKOUT_FD_MASK;
	return clkout_rates[clkout];
}

static long rv3028_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long *prate)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
		if (clkout_rates[i] <= rate)
			return clkout_rates[i];

	return 0;
}

static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{
	int i, ret;
	u32 enabled;
	struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);

	ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &enabled);
	if (ret < 0)
		return ret;

	ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0);
	if (ret < 0)
		return ret;

	enabled &= RV3028_CLKOUT_CLKOE;

	for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
		if (clkout_rates[i] == rate)
			return rv3028_update_cfg(rv3028, RV3028_CLKOUT, 0xff,
						 RV3028_CLKOUT_CLKSY | enabled | i);

	return -EINVAL;
}

static int rv3028_clkout_prepare(struct clk_hw *hw)
{
	struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);

	return regmap_write(rv3028->regmap, RV3028_CLKOUT,
			    RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE);
}

static void rv3028_clkout_unprepare(struct clk_hw *hw)
{
	struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);

	regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0);
	regmap_update_bits(rv3028->regmap, RV3028_STATUS,
			   RV3028_STATUS_CLKF, 0);
}

static int rv3028_clkout_is_prepared(struct clk_hw *hw)
{
	int clkout, ret;
	struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);

	ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &clkout);
	if (ret < 0)
		return ret;

	return !!(clkout & RV3028_CLKOUT_CLKOE);
}

static const struct clk_ops rv3028_clkout_ops = {
	.prepare = rv3028_clkout_prepare,
	.unprepare = rv3028_clkout_unprepare,
	.is_prepared = rv3028_clkout_is_prepared,
	.recalc_rate = rv3028_clkout_recalc_rate,
	.round_rate = rv3028_clkout_round_rate,
	.set_rate = rv3028_clkout_set_rate,
};

static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
				      struct i2c_client *client)
{
	int ret;
	struct clk *clk;
	struct clk_init_data init;
	struct device_node *node = client->dev.of_node;

	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
				 RV3028_STATUS_CLKF, 0);
	if (ret < 0)
		return ret;

	init.name = "rv3028-clkout";
	init.ops = &rv3028_clkout_ops;
	init.flags = 0;
	init.parent_names = NULL;
	init.num_parents = 0;
	rv3028->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, &rv3028->clkout_hw);
	if (!IS_ERR(clk))
		of_clk_add_provider(node, of_clk_src_simple_get, clk);

	return 0;
}
#endif

static struct rtc_class_ops rv3028_rtc_ops = {
	.read_time = rv3028_get_time,
	.set_time = rv3028_set_time,
	.read_offset = rv3028_read_offset,
	.set_offset = rv3028_set_offset,
	.ioctl = rv3028_ioctl,
};

static const struct regmap_config regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
        .max_register = 0x37,
};

static int rv3028_probe(struct i2c_client *client)
{
	struct rv3028_data *rv3028;
	int ret, status;
	u32 ohms;
	struct nvmem_config nvmem_cfg = {
		.name = "rv3028_nvram",
		.word_size = 1,
		.stride = 1,
		.size = 2,
		.type = NVMEM_TYPE_BATTERY_BACKED,
		.reg_read = rv3028_nvram_read,
		.reg_write = rv3028_nvram_write,
	};
	struct nvmem_config eeprom_cfg = {
		.name = "rv3028_eeprom",
		.word_size = 1,
		.stride = 1,
		.size = 43,
		.type = NVMEM_TYPE_EEPROM,
		.reg_read = rv3028_eeprom_read,
		.reg_write = rv3028_eeprom_write,
	};

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

	rv3028->regmap = devm_regmap_init_i2c(client, &regmap_config);
	if (IS_ERR(rv3028->regmap))
		return PTR_ERR(rv3028->regmap);

	i2c_set_clientdata(client, rv3028);

	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
	if (ret < 0)
		return ret;

	if (status & RV3028_STATUS_PORF)
		dev_warn(&client->dev, "Voltage low, data loss detected.\n");

	if (status & RV3028_STATUS_AF)
		dev_warn(&client->dev, "An alarm may have been missed.\n");

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

	if (client->irq > 0) {
		ret = devm_request_threaded_irq(&client->dev, client->irq,
						NULL, rv3028_handle_irq,
						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
						"rv3028", rv3028);
		if (ret) {
			dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
			client->irq = 0;
		} else {
			rv3028_rtc_ops.read_alarm = rv3028_get_alarm;
			rv3028_rtc_ops.set_alarm = rv3028_set_alarm;
			rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable;
		}
	}

	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
				 RV3028_CTRL1_WADA, RV3028_CTRL1_WADA);
	if (ret)
		return ret;

	/* setup timestamping */
	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
				 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE,
				 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE);
	if (ret)
		return ret;

	/* setup trickle charger */
	if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms",
				      &ohms)) {
		int i;

		for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++)
			if (ohms == rv3028_trickle_resistors[i])
				break;

		if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
			ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
						 RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i);
			if (ret)
				return ret;
		} else {
			dev_warn(&client->dev, "invalid trickle resistor value\n");
		}
	}

	ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
	if (ret)
		return ret;

	rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
	rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099;
	rv3028->rtc->ops = &rv3028_rtc_ops;
	ret = rtc_register_device(rv3028->rtc);
	if (ret)
		return ret;

	nvmem_cfg.priv = rv3028->regmap;
	rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
	eeprom_cfg.priv = rv3028;
	rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);

	rv3028->rtc->max_user_freq = 1;

#ifdef CONFIG_COMMON_CLK
	rv3028_clkout_register_clk(rv3028, client);
#endif
	return 0;
}

static const struct of_device_id rv3028_of_match[] = {
	{ .compatible = "microcrystal,rv3028", },
	{ }
};
MODULE_DEVICE_TABLE(of, rv3028_of_match);

static struct i2c_driver rv3028_driver = {
	.driver = {
		.name = "rtc-rv3028",
		.of_match_table = of_match_ptr(rv3028_of_match),
	},
	.probe_new	= rv3028_probe,
};
module_i2c_driver(rv3028_driver);

MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
MODULE_DESCRIPTION("Micro Crystal RV3028 RTC driver");
MODULE_LICENSE("GPL v2");
