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

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/bcd.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/hwmon.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 RV3032_SEC			0x01
#define RV3032_MIN			0x02
#define RV3032_HOUR			0x03
#define RV3032_WDAY			0x04
#define RV3032_DAY			0x05
#define RV3032_MONTH			0x06
#define RV3032_YEAR			0x07
#define RV3032_ALARM_MIN		0x08
#define RV3032_ALARM_HOUR		0x09
#define RV3032_ALARM_DAY		0x0A
#define RV3032_STATUS			0x0D
#define RV3032_TLSB			0x0E
#define RV3032_TMSB			0x0F
#define RV3032_CTRL1			0x10
#define RV3032_CTRL2			0x11
#define RV3032_CTRL3			0x12
#define RV3032_TS_CTRL			0x13
#define RV3032_CLK_IRQ			0x14
#define RV3032_EEPROM_ADDR		0x3D
#define RV3032_EEPROM_DATA		0x3E
#define RV3032_EEPROM_CMD		0x3F
#define RV3032_RAM1			0x40
#define RV3032_PMU			0xC0
#define RV3032_OFFSET			0xC1
#define RV3032_CLKOUT1			0xC2
#define RV3032_CLKOUT2			0xC3
#define RV3032_TREF0			0xC4
#define RV3032_TREF1			0xC5

#define RV3032_STATUS_VLF		BIT(0)
#define RV3032_STATUS_PORF		BIT(1)
#define RV3032_STATUS_EVF		BIT(2)
#define RV3032_STATUS_AF		BIT(3)
#define RV3032_STATUS_TF		BIT(4)
#define RV3032_STATUS_UF		BIT(5)
#define RV3032_STATUS_TLF		BIT(6)
#define RV3032_STATUS_THF		BIT(7)

#define RV3032_TLSB_CLKF		BIT(1)
#define RV3032_TLSB_EEBUSY		BIT(2)
#define RV3032_TLSB_TEMP		GENMASK(7, 4)

#define RV3032_CLKOUT2_HFD_MSK		GENMASK(4, 0)
#define RV3032_CLKOUT2_FD_MSK		GENMASK(6, 5)
#define RV3032_CLKOUT2_OS		BIT(7)

#define RV3032_CTRL1_EERD		BIT(3)
#define RV3032_CTRL1_WADA		BIT(5)

#define RV3032_CTRL2_STOP		BIT(0)
#define RV3032_CTRL2_EIE		BIT(2)
#define RV3032_CTRL2_AIE		BIT(3)
#define RV3032_CTRL2_TIE		BIT(4)
#define RV3032_CTRL2_UIE		BIT(5)
#define RV3032_CTRL2_CLKIE		BIT(6)
#define RV3032_CTRL2_TSE		BIT(7)

#define RV3032_PMU_TCM			GENMASK(1, 0)
#define RV3032_PMU_TCR			GENMASK(3, 2)
#define RV3032_PMU_BSM			GENMASK(5, 4)
#define RV3032_PMU_NCLKE		BIT(6)

#define RV3032_PMU_BSM_DSM		1
#define RV3032_PMU_BSM_LSM		2

#define RV3032_OFFSET_MSK		GENMASK(5, 0)

#define RV3032_EVT_CTRL_TSR		BIT(2)

#define RV3032_EEPROM_CMD_UPDATE	0x11
#define RV3032_EEPROM_CMD_WRITE		0x21
#define RV3032_EEPROM_CMD_READ		0x22

#define RV3032_EEPROM_USER		0xCB

#define RV3032_EEBUSY_POLL		10000
#define RV3032_EEBUSY_TIMEOUT		100000

#define OFFSET_STEP_PPT			238419

struct rv3032_data {
	struct regmap *regmap;
	struct rtc_device *rtc;
#ifdef CONFIG_COMMON_CLK
	struct clk_hw clkout_hw;
#endif
};

static u16 rv3032_trickle_resistors[] = {1000, 2000, 7000, 11000};
static u16 rv3032_trickle_voltages[] = {0, 1750, 3000, 4400};

static int rv3032_exit_eerd(struct rv3032_data *rv3032, u32 eerd)
{
	if (eerd)
		return 0;

	return regmap_update_bits(rv3032->regmap, RV3032_CTRL1, RV3032_CTRL1_EERD, 0);
}

static int rv3032_enter_eerd(struct rv3032_data *rv3032, u32 *eerd)
{
	u32 ctrl1, status;
	int ret;

	ret = regmap_read(rv3032->regmap, RV3032_CTRL1, &ctrl1);
	if (ret)
		return ret;

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

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
				 RV3032_CTRL1_EERD, RV3032_CTRL1_EERD);
	if (ret)
		return ret;

	ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
				       !(status & RV3032_TLSB_EEBUSY),
				       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
	if (ret) {
		rv3032_exit_eerd(rv3032, *eerd);

		return ret;
	}

	return 0;
}

static int rv3032_update_cfg(struct rv3032_data *rv3032, unsigned int reg,
			     unsigned int mask, unsigned int val)
{
	u32 status, eerd;
	int ret;

	ret = rv3032_enter_eerd(rv3032, &eerd);
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3032->regmap, reg, mask, val);
	if (ret)
		goto exit_eerd;

	ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE);
	if (ret)
		goto exit_eerd;

	usleep_range(46000, RV3032_EEBUSY_TIMEOUT);

	ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
				       !(status & RV3032_TLSB_EEBUSY),
				       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);

exit_eerd:
	rv3032_exit_eerd(rv3032, eerd);

	return ret;
}

static irqreturn_t rv3032_handle_irq(int irq, void *dev_id)
{
	struct rv3032_data *rv3032 = dev_id;
	unsigned long events = 0;
	u32 status = 0, ctrl = 0;

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

	if (status & RV3032_STATUS_TF) {
		status |= RV3032_STATUS_TF;
		ctrl |= RV3032_CTRL2_TIE;
		events |= RTC_PF;
	}

	if (status & RV3032_STATUS_AF) {
		status |= RV3032_STATUS_AF;
		ctrl |= RV3032_CTRL2_AIE;
		events |= RTC_AF;
	}

	if (status & RV3032_STATUS_UF) {
		status |= RV3032_STATUS_UF;
		ctrl |= RV3032_CTRL2_UIE;
		events |= RTC_UF;
	}

	if (events) {
		rtc_update_irq(rv3032->rtc, 1, events);
		regmap_update_bits(rv3032->regmap, RV3032_STATUS, status, 0);
		regmap_update_bits(rv3032->regmap, RV3032_CTRL2, ctrl, 0);
	}

	return IRQ_HANDLED;
}

static int rv3032_get_time(struct device *dev, struct rtc_time *tm)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	u8 date[7];
	int ret, status;

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

	if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF))
		return -EINVAL;

	ret = regmap_bulk_read(rv3032->regmap, RV3032_SEC, date, sizeof(date));
	if (ret)
		return ret;

	tm->tm_sec  = bcd2bin(date[0] & 0x7f);
	tm->tm_min  = bcd2bin(date[1] & 0x7f);
	tm->tm_hour = bcd2bin(date[2] & 0x3f);
	tm->tm_wday = date[3] & 0x7;
	tm->tm_mday = bcd2bin(date[4] & 0x3f);
	tm->tm_mon  = bcd2bin(date[5] & 0x1f) - 1;
	tm->tm_year = bcd2bin(date[6]) + 100;

	return 0;
}

static int rv3032_set_time(struct device *dev, struct rtc_time *tm)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	u8 date[7];
	int ret;

	date[0] = bin2bcd(tm->tm_sec);
	date[1] = bin2bcd(tm->tm_min);
	date[2] = bin2bcd(tm->tm_hour);
	date[3] = tm->tm_wday;
	date[4] = bin2bcd(tm->tm_mday);
	date[5] = bin2bcd(tm->tm_mon + 1);
	date[6] = bin2bcd(tm->tm_year - 100);

	ret = regmap_bulk_write(rv3032->regmap, RV3032_SEC, date,
				sizeof(date));
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS,
				 RV3032_STATUS_PORF | RV3032_STATUS_VLF, 0);

	return ret;
}

static int rv3032_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	u8 alarmvals[3];
	int status, ctrl, ret;

	ret = regmap_bulk_read(rv3032->regmap, RV3032_ALARM_MIN, alarmvals,
			       sizeof(alarmvals));
	if (ret)
		return ret;

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

	ret = regmap_read(rv3032->regmap, RV3032_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 & RV3032_CTRL2_AIE);
	alrm->pending = (status & RV3032_STATUS_AF) && alrm->enabled;

	return 0;
}

static int rv3032_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rv3032_data *rv3032 = 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(rv3032->regmap, RV3032_CTRL2,
				 RV3032_CTRL2_AIE | RV3032_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(rv3032->regmap, RV3032_STATUS,
				 RV3032_STATUS_AF, 0);
	if (ret)
		return ret;

	ret = regmap_bulk_write(rv3032->regmap, RV3032_ALARM_MIN, alarmvals,
				sizeof(alarmvals));
	if (ret)
		return ret;

	if (alrm->enabled) {
		if (rv3032->rtc->uie_rtctimer.enabled)
			ctrl |= RV3032_CTRL2_UIE;
		if (rv3032->rtc->aie_timer.enabled)
			ctrl |= RV3032_CTRL2_AIE;
	}

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
				 RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl);

	return ret;
}

static int rv3032_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	int ctrl = 0, ret;

	if (enabled) {
		if (rv3032->rtc->uie_rtctimer.enabled)
			ctrl |= RV3032_CTRL2_UIE;
		if (rv3032->rtc->aie_timer.enabled)
			ctrl |= RV3032_CTRL2_AIE;
	}

	ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS,
				 RV3032_STATUS_AF | RV3032_STATUS_UF, 0);
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
				 RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl);
	if (ret)
		return ret;

	return 0;
}

static int rv3032_read_offset(struct device *dev, long *offset)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	int ret, value, steps;

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

	steps = sign_extend32(FIELD_GET(RV3032_OFFSET_MSK, value), 5);

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

	return 0;
}

static int rv3032_set_offset(struct device *dev, long offset)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);

	offset = clamp(offset, -7629L, 7391L) * 1000;
	offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);

	return rv3032_update_cfg(rv3032, RV3032_OFFSET, RV3032_OFFSET_MSK,
				 FIELD_PREP(RV3032_OFFSET_MSK, offset));
}

static int rv3032_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	int status, val = 0, ret = 0;

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

		if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF))
			val = RTC_VL_DATA_INVALID;
		return put_user(val, (unsigned int __user *)arg);

	default:
		return -ENOIOCTLCMD;
	}
}

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

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

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

	ret = rv3032_enter_eerd(rv3032, &eerd);
	if (ret)
		return ret;

	for (i = 0; i < bytes; i++) {
		ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR,
				   RV3032_EEPROM_USER + offset + i);
		if (ret)
			goto exit_eerd;

		ret = regmap_write(rv3032->regmap, RV3032_EEPROM_DATA, buf[i]);
		if (ret)
			goto exit_eerd;

		ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD,
				   RV3032_EEPROM_CMD_WRITE);
		if (ret)
			goto exit_eerd;

		usleep_range(RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);

		ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
					       !(status & RV3032_TLSB_EEBUSY),
					       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
		if (ret)
			goto exit_eerd;
	}

exit_eerd:
	rv3032_exit_eerd(rv3032, eerd);

	return ret;
}

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

	ret = rv3032_enter_eerd(rv3032, &eerd);
	if (ret)
		return ret;

	for (i = 0; i < bytes; i++) {
		ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR,
				   RV3032_EEPROM_USER + offset + i);
		if (ret)
			goto exit_eerd;

		ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD,
				   RV3032_EEPROM_CMD_READ);
		if (ret)
			goto exit_eerd;

		ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
					       !(status & RV3032_TLSB_EEBUSY),
					       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
		if (ret)
			goto exit_eerd;

		ret = regmap_read(rv3032->regmap, RV3032_EEPROM_DATA, &data);
		if (ret)
			goto exit_eerd;
		buf[i] = data;
	}

exit_eerd:
	rv3032_exit_eerd(rv3032, eerd);

	return ret;
}

static int rv3032_trickle_charger_setup(struct device *dev, struct rv3032_data *rv3032)
{
	u32 val, ohms, voltage;
	int i;

	val = FIELD_PREP(RV3032_PMU_TCM, 1) | FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_DSM);
	if (!device_property_read_u32(dev, "trickle-voltage-millivolt", &voltage)) {
		for (i = 0; i < ARRAY_SIZE(rv3032_trickle_voltages); i++)
			if (voltage == rv3032_trickle_voltages[i])
				break;
		if (i < ARRAY_SIZE(rv3032_trickle_voltages))
			val = FIELD_PREP(RV3032_PMU_TCM, i) |
			      FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_LSM);
	}

	if (device_property_read_u32(dev, "trickle-resistor-ohms", &ohms))
		return 0;

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

	if (i >= ARRAY_SIZE(rv3032_trickle_resistors)) {
		dev_warn(dev, "invalid trickle resistor value\n");

		return 0;
	}

	return rv3032_update_cfg(rv3032, RV3032_PMU,
				 RV3032_PMU_TCR | RV3032_PMU_TCM | RV3032_PMU_BSM,
				 val | FIELD_PREP(RV3032_PMU_TCR, i));
}

#ifdef CONFIG_COMMON_CLK
#define clkout_hw_to_rv3032(hw) container_of(hw, struct rv3032_data, clkout_hw)

static int clkout_xtal_rates[] = {
	32768,
	1024,
	64,
	1,
};

#define RV3032_HFD_STEP 8192

static unsigned long rv3032_clkout_recalc_rate(struct clk_hw *hw,
					       unsigned long parent_rate)
{
	int clkout, ret;
	struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);

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

	if (clkout & RV3032_CLKOUT2_OS) {
		unsigned long rate = FIELD_GET(RV3032_CLKOUT2_HFD_MSK, clkout) << 8;

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

		rate += clkout + 1;

		return rate * RV3032_HFD_STEP;
	}

	return clkout_xtal_rates[FIELD_GET(RV3032_CLKOUT2_FD_MSK, clkout)];
}

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

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

	hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP);

	return RV3032_HFD_STEP * clamp(hfd, 0, 8192);
}

static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{
	struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
	u32 status, eerd;
	int i, hfd, ret;

	for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) {
		if (clkout_xtal_rates[i] == rate) {
			return rv3032_update_cfg(rv3032, RV3032_CLKOUT2, 0xff,
						 FIELD_PREP(RV3032_CLKOUT2_FD_MSK, i));
		}
	}

	hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP);
	hfd = clamp(hfd, 1, 8192) - 1;

	ret = rv3032_enter_eerd(rv3032, &eerd);
	if (ret)
		goto exit_eerd;

	ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff);
	if (ret)
		return ret;

	ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS |
			    FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8));
	if (ret)
		goto exit_eerd;

	ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE);
	if (ret)
		goto exit_eerd;

	usleep_range(46000, RV3032_EEBUSY_TIMEOUT);

	ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
				       !(status & RV3032_TLSB_EEBUSY),
				       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);

exit_eerd:
	rv3032_exit_eerd(rv3032, eerd);

	return ret;
}

static int rv3032_clkout_prepare(struct clk_hw *hw)
{
	struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);

	return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, 0);
}

static void rv3032_clkout_unprepare(struct clk_hw *hw)
{
	struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);

	rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, RV3032_PMU_NCLKE);
}

static int rv3032_clkout_is_prepared(struct clk_hw *hw)
{
	int val, ret;
	struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);

	ret = regmap_read(rv3032->regmap, RV3032_PMU, &val);
	if (ret < 0)
		return ret;

	return !(val & RV3032_PMU_NCLKE);
}

static const struct clk_ops rv3032_clkout_ops = {
	.prepare = rv3032_clkout_prepare,
	.unprepare = rv3032_clkout_unprepare,
	.is_prepared = rv3032_clkout_is_prepared,
	.recalc_rate = rv3032_clkout_recalc_rate,
	.round_rate = rv3032_clkout_round_rate,
	.set_rate = rv3032_clkout_set_rate,
};

static int rv3032_clkout_register_clk(struct rv3032_data *rv3032,
				      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(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0);
	if (ret < 0)
		return ret;

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, RV3032_CTRL2_CLKIE, 0);
	if (ret < 0)
		return ret;

	ret = regmap_write(rv3032->regmap, RV3032_CLK_IRQ, 0);
	if (ret < 0)
		return ret;

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

	of_property_read_string(node, "clock-output-names", &init.name);

	clk = devm_clk_register(&client->dev, &rv3032->clkout_hw);
	if (!IS_ERR(clk))
		of_clk_add_provider(node, of_clk_src_simple_get, clk);

	return 0;
}
#endif

static int rv3032_hwmon_read_temp(struct device *dev, long *mC)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);
	u8 buf[2];
	int temp, prev = 0;
	int ret;

	ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf));
	if (ret)
		return ret;

	temp = sign_extend32(buf[1], 7) << 4;
	temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]);

	/* No blocking or shadowing on RV3032_TLSB and RV3032_TMSB */
	do {
		prev = temp;

		ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf));
		if (ret)
			return ret;

		temp = sign_extend32(buf[1], 7) << 4;
		temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]);
	} while (temp != prev);

	*mC = (temp * 1000) / 16;

	return 0;
}

static umode_t rv3032_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
				       u32 attr, int channel)
{
	if (type != hwmon_temp)
		return 0;

	switch (attr) {
	case hwmon_temp_input:
		return 0444;
	default:
		return 0;
	}
}

static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			     u32 attr, int channel, long *temp)
{
	int err;

	switch (attr) {
	case hwmon_temp_input:
		err = rv3032_hwmon_read_temp(dev, temp);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static const struct hwmon_channel_info *rv3032_hwmon_info[] = {
	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
	NULL
};

static const struct hwmon_ops rv3032_hwmon_hwmon_ops = {
	.is_visible = rv3032_hwmon_is_visible,
	.read = rv3032_hwmon_read,
};

static const struct hwmon_chip_info rv3032_hwmon_chip_info = {
	.ops = &rv3032_hwmon_hwmon_ops,
	.info = rv3032_hwmon_info,
};

static void rv3032_hwmon_register(struct device *dev)
{
	struct rv3032_data *rv3032 = dev_get_drvdata(dev);

	if (!IS_REACHABLE(CONFIG_HWMON))
		return;

	devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL);
}

static const struct rtc_class_ops rv3032_rtc_ops = {
	.read_time = rv3032_get_time,
	.set_time = rv3032_set_time,
	.read_offset = rv3032_read_offset,
	.set_offset = rv3032_set_offset,
	.ioctl = rv3032_ioctl,
	.read_alarm = rv3032_get_alarm,
	.set_alarm = rv3032_set_alarm,
	.alarm_irq_enable = rv3032_alarm_irq_enable,
};

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

static int rv3032_probe(struct i2c_client *client)
{
	struct rv3032_data *rv3032;
	int ret, status;
	struct nvmem_config nvmem_cfg = {
		.name = "rv3032_nvram",
		.word_size = 1,
		.stride = 1,
		.size = 16,
		.type = NVMEM_TYPE_BATTERY_BACKED,
		.reg_read = rv3032_nvram_read,
		.reg_write = rv3032_nvram_write,
	};
	struct nvmem_config eeprom_cfg = {
		.name = "rv3032_eeprom",
		.word_size = 1,
		.stride = 1,
		.size = 32,
		.type = NVMEM_TYPE_EEPROM,
		.reg_read = rv3032_eeprom_read,
		.reg_write = rv3032_eeprom_write,
	};

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

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

	i2c_set_clientdata(client, rv3032);

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

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

	if (client->irq > 0) {
		ret = devm_request_threaded_irq(&client->dev, client->irq,
						NULL, rv3032_handle_irq,
						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
						"rv3032", rv3032);
		if (ret) {
			dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
			client->irq = 0;
		}
	}
	if (!client->irq)
		clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features);

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
				 RV3032_CTRL1_WADA, RV3032_CTRL1_WADA);
	if (ret)
		return ret;

	rv3032_trickle_charger_setup(&client->dev, rv3032);

	rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
	rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099;
	rv3032->rtc->ops = &rv3032_rtc_ops;
	ret = devm_rtc_register_device(rv3032->rtc);
	if (ret)
		return ret;

	nvmem_cfg.priv = rv3032->regmap;
	devm_rtc_nvmem_register(rv3032->rtc, &nvmem_cfg);
	eeprom_cfg.priv = rv3032;
	devm_rtc_nvmem_register(rv3032->rtc, &eeprom_cfg);

	rv3032->rtc->max_user_freq = 1;

#ifdef CONFIG_COMMON_CLK
	rv3032_clkout_register_clk(rv3032, client);
#endif

	rv3032_hwmon_register(&client->dev);

	return 0;
}

static const __maybe_unused struct of_device_id rv3032_of_match[] = {
	{ .compatible = "microcrystal,rv3032", },
	{ }
};
MODULE_DEVICE_TABLE(of, rv3032_of_match);

static struct i2c_driver rv3032_driver = {
	.driver = {
		.name = "rtc-rv3032",
		.of_match_table = of_match_ptr(rv3032_of_match),
	},
	.probe_new	= rv3032_probe,
};
module_i2c_driver(rv3032_driver);

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