// SPDX-License-Identifier: GPL-2.0-only
/*
 * An I2C driver for Ricoh RS5C372, R2025S/D and RV5C38[67] RTCs
 *
 * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net>
 * Copyright (C) 2006 Tower Technologies
 * Copyright (C) 2008 Paul Mundt
 */

#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of_device.h>

/*
 * Ricoh has a family of I2C based RTCs, which differ only slightly from
 * each other.  Differences center on pinout (e.g. how many interrupts,
 * output clock, etc) and how the control registers are used.  The '372
 * is significant only because that's the one this driver first supported.
 */
#define RS5C372_REG_SECS	0
#define RS5C372_REG_MINS	1
#define RS5C372_REG_HOURS	2
#define RS5C372_REG_WDAY	3
#define RS5C372_REG_DAY		4
#define RS5C372_REG_MONTH	5
#define RS5C372_REG_YEAR	6
#define RS5C372_REG_TRIM	7
#	define RS5C372_TRIM_XSL		0x80		/* only if RS5C372[a|b] */
#	define RS5C372_TRIM_MASK	0x7F
#	define R2221TL_TRIM_DEV		(1 << 7)	/* only if R2221TL */
#	define RS5C372_TRIM_DECR	(1 << 6)

#define RS5C_REG_ALARM_A_MIN	8			/* or ALARM_W */
#define RS5C_REG_ALARM_A_HOURS	9
#define RS5C_REG_ALARM_A_WDAY	10

#define RS5C_REG_ALARM_B_MIN	11			/* or ALARM_D */
#define RS5C_REG_ALARM_B_HOURS	12
#define RS5C_REG_ALARM_B_WDAY	13			/* (ALARM_B only) */

#define RS5C_REG_CTRL1		14
#	define RS5C_CTRL1_AALE		(1 << 7)	/* or WALE */
#	define RS5C_CTRL1_BALE		(1 << 6)	/* or DALE */
#	define RV5C387_CTRL1_24		(1 << 5)
#	define RS5C372A_CTRL1_SL1	(1 << 5)
#	define RS5C_CTRL1_CT_MASK	(7 << 0)
#	define RS5C_CTRL1_CT0		(0 << 0)	/* no periodic irq */
#	define RS5C_CTRL1_CT4		(4 << 0)	/* 1 Hz level irq */
#define RS5C_REG_CTRL2		15
#	define RS5C372_CTRL2_24		(1 << 5)
#	define RS5C_CTRL2_XSTP		(1 << 4)	/* only if !R2x2x */
#	define R2x2x_CTRL2_VDET		(1 << 6)	/* only if  R2x2x */
#	define R2x2x_CTRL2_XSTP		(1 << 5)	/* only if  R2x2x */
#	define R2x2x_CTRL2_PON		(1 << 4)	/* only if  R2x2x */
#	define RS5C_CTRL2_CTFG		(1 << 2)
#	define RS5C_CTRL2_AAFG		(1 << 1)	/* or WAFG */
#	define RS5C_CTRL2_BAFG		(1 << 0)	/* or DAFG */


/* to read (style 1) or write registers starting at R */
#define RS5C_ADDR(R)		(((R) << 4) | 0)


enum rtc_type {
	rtc_undef = 0,
	rtc_r2025sd,
	rtc_r2221tl,
	rtc_rs5c372a,
	rtc_rs5c372b,
	rtc_rv5c386,
	rtc_rv5c387a,
};

static const struct i2c_device_id rs5c372_id[] = {
	{ "r2025sd", rtc_r2025sd },
	{ "r2221tl", rtc_r2221tl },
	{ "rs5c372a", rtc_rs5c372a },
	{ "rs5c372b", rtc_rs5c372b },
	{ "rv5c386", rtc_rv5c386 },
	{ "rv5c387a", rtc_rv5c387a },
	{ }
};
MODULE_DEVICE_TABLE(i2c, rs5c372_id);

static const __maybe_unused struct of_device_id rs5c372_of_match[] = {
	{
		.compatible = "ricoh,r2025sd",
		.data = (void *)rtc_r2025sd
	},
	{
		.compatible = "ricoh,r2221tl",
		.data = (void *)rtc_r2221tl
	},
	{
		.compatible = "ricoh,rs5c372a",
		.data = (void *)rtc_rs5c372a
	},
	{
		.compatible = "ricoh,rs5c372b",
		.data = (void *)rtc_rs5c372b
	},
	{
		.compatible = "ricoh,rv5c386",
		.data = (void *)rtc_rv5c386
	},
	{
		.compatible = "ricoh,rv5c387a",
		.data = (void *)rtc_rv5c387a
	},
	{ }
};
MODULE_DEVICE_TABLE(of, rs5c372_of_match);

/* REVISIT:  this assumes that:
 *  - we're in the 21st century, so it's safe to ignore the century
 *    bit for rv5c38[67] (REG_MONTH bit 7);
 *  - we should use ALARM_A not ALARM_B (may be wrong on some boards)
 */
struct rs5c372 {
	struct i2c_client	*client;
	struct rtc_device	*rtc;
	enum rtc_type		type;
	unsigned		time24:1;
	unsigned		has_irq:1;
	unsigned		smbus:1;
	char			buf[17];
	char			*regs;
};

static int rs5c_get_regs(struct rs5c372 *rs5c)
{
	struct i2c_client	*client = rs5c->client;
	struct i2c_msg		msgs[] = {
		{
			.addr = client->addr,
			.flags = I2C_M_RD,
			.len = sizeof(rs5c->buf),
			.buf = rs5c->buf
		},
	};

	/* This implements the third reading method from the datasheet, using
	 * an internal address that's reset after each transaction (by STOP)
	 * to 0x0f ... so we read extra registers, and skip the first one.
	 *
	 * The first method doesn't work with the iop3xx adapter driver, on at
	 * least 80219 chips; this works around that bug.
	 *
	 * The third method on the other hand doesn't work for the SMBus-only
	 * configurations, so we use the first method there, stripping off
	 * the extra register in the process.
	 */
	if (rs5c->smbus) {
		int addr = RS5C_ADDR(RS5C372_REG_SECS);
		int size = sizeof(rs5c->buf) - 1;

		if (i2c_smbus_read_i2c_block_data(client, addr, size,
						  rs5c->buf + 1) != size) {
			dev_warn(&client->dev, "can't read registers\n");
			return -EIO;
		}
	} else {
		if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
			dev_warn(&client->dev, "can't read registers\n");
			return -EIO;
		}
	}

	dev_dbg(&client->dev,
		"%3ph (%02x) %3ph (%02x), %3ph, %3ph; %02x %02x\n",
		rs5c->regs + 0, rs5c->regs[3],
		rs5c->regs + 4, rs5c->regs[7],
		rs5c->regs + 8, rs5c->regs + 11,
		rs5c->regs[14], rs5c->regs[15]);

	return 0;
}

static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg)
{
	unsigned	hour;

	if (rs5c->time24)
		return bcd2bin(reg & 0x3f);

	hour = bcd2bin(reg & 0x1f);
	if (hour == 12)
		hour = 0;
	if (reg & 0x20)
		hour += 12;
	return hour;
}

static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour)
{
	if (rs5c->time24)
		return bin2bcd(hour);

	if (hour > 12)
		return 0x20 | bin2bcd(hour - 12);
	if (hour == 12)
		return 0x20 | bin2bcd(12);
	if (hour == 0)
		return bin2bcd(12);
	return bin2bcd(hour);
}

static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rs5c372	*rs5c = i2c_get_clientdata(client);
	int		status = rs5c_get_regs(rs5c);
	unsigned char ctrl2 = rs5c->regs[RS5C_REG_CTRL2];

	if (status < 0)
		return status;

	switch (rs5c->type) {
	case rtc_r2025sd:
	case rtc_r2221tl:
		if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) ||
		    (rs5c->type == rtc_r2221tl &&  (ctrl2 & R2x2x_CTRL2_XSTP))) {
			dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
			return -EINVAL;
		}
		break;
	default:
		if (ctrl2 & RS5C_CTRL2_XSTP) {
			dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
			return -EINVAL;
		}
	}

	tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f);
	tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f);
	tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]);

	tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07);
	tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f);

	/* tm->tm_mon is zero-based */
	tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1;

	/* year is 1900 + tm->tm_year */
	tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100;

	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	return 0;
}

static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rs5c372	*rs5c = i2c_get_clientdata(client);
	unsigned char	buf[7];
	unsigned char	ctrl2;
	int		addr;

	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	addr   = RS5C_ADDR(RS5C372_REG_SECS);
	buf[0] = bin2bcd(tm->tm_sec);
	buf[1] = bin2bcd(tm->tm_min);
	buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour);
	buf[3] = bin2bcd(tm->tm_wday);
	buf[4] = bin2bcd(tm->tm_mday);
	buf[5] = bin2bcd(tm->tm_mon + 1);
	buf[6] = bin2bcd(tm->tm_year - 100);

	if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
		dev_dbg(&client->dev, "%s: write error in line %i\n",
			__func__, __LINE__);
		return -EIO;
	}

	addr = RS5C_ADDR(RS5C_REG_CTRL2);
	ctrl2 = i2c_smbus_read_byte_data(client, addr);

	/* clear rtc warning bits */
	switch (rs5c->type) {
	case rtc_r2025sd:
	case rtc_r2221tl:
		ctrl2 &= ~(R2x2x_CTRL2_VDET | R2x2x_CTRL2_PON);
		if (rs5c->type == rtc_r2025sd)
			ctrl2 |= R2x2x_CTRL2_XSTP;
		else
			ctrl2 &= ~R2x2x_CTRL2_XSTP;
		break;
	default:
		ctrl2 &= ~RS5C_CTRL2_XSTP;
		break;
	}

	if (i2c_smbus_write_byte_data(client, addr, ctrl2) < 0) {
		dev_dbg(&client->dev, "%s: write error in line %i\n",
			__func__, __LINE__);
		return -EIO;
	}

	return 0;
}

#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
#define	NEED_TRIM
#endif

#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)
#define	NEED_TRIM
#endif

#ifdef	NEED_TRIM
static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
{
	struct rs5c372 *rs5c372 = i2c_get_clientdata(client);
	u8 tmp = rs5c372->regs[RS5C372_REG_TRIM];

	if (osc) {
		if (rs5c372->type == rtc_rs5c372a || rs5c372->type == rtc_rs5c372b)
			*osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768;
		else
			*osc = 32768;
	}

	if (trim) {
		dev_dbg(&client->dev, "%s: raw trim=%x\n", __func__, tmp);
		tmp &= RS5C372_TRIM_MASK;
		if (tmp & 0x3e) {
			int t = tmp & 0x3f;

			if (tmp & 0x40)
				t = (~t | (s8)0xc0) + 1;
			else
				t = t - 1;

			tmp = t * 2;
		} else
			tmp = 0;
		*trim = tmp;
	}

	return 0;
}
#endif

static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct i2c_client	*client = to_i2c_client(dev);
	struct rs5c372		*rs5c = i2c_get_clientdata(client);
	unsigned char		buf;
	int			status, addr;

	buf = rs5c->regs[RS5C_REG_CTRL1];

	if (!rs5c->has_irq)
		return -EINVAL;

	status = rs5c_get_regs(rs5c);
	if (status < 0)
		return status;

	addr = RS5C_ADDR(RS5C_REG_CTRL1);
	if (enabled)
		buf |= RS5C_CTRL1_AALE;
	else
		buf &= ~RS5C_CTRL1_AALE;

	if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
		dev_warn(dev, "can't update alarm\n");
		status = -EIO;
	} else
		rs5c->regs[RS5C_REG_CTRL1] = buf;

	return status;
}


/* NOTE:  Since RTC_WKALM_{RD,SET} were originally defined for EFI,
 * which only exposes a polled programming interface; and since
 * these calls map directly to those EFI requests; we don't demand
 * we have an IRQ for this chip when we go through this API.
 *
 * The older x86_pc derived RTC_ALM_{READ,SET} calls require irqs
 * though, managed through RTC_AIE_{ON,OFF} requests.
 */

static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
	struct i2c_client	*client = to_i2c_client(dev);
	struct rs5c372		*rs5c = i2c_get_clientdata(client);
	int			status;

	status = rs5c_get_regs(rs5c);
	if (status < 0)
		return status;

	/* report alarm time */
	t->time.tm_sec = 0;
	t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
	t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);

	/* ... and status */
	t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
	t->pending = !!(rs5c->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_AAFG);

	return 0;
}

static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
	struct i2c_client	*client = to_i2c_client(dev);
	struct rs5c372		*rs5c = i2c_get_clientdata(client);
	int			status, addr, i;
	unsigned char		buf[3];

	/* only handle up to 24 hours in the future, like RTC_ALM_SET */
	if (t->time.tm_mday != -1
			|| t->time.tm_mon != -1
			|| t->time.tm_year != -1)
		return -EINVAL;

	/* REVISIT: round up tm_sec */

	/* if needed, disable irq (clears pending status) */
	status = rs5c_get_regs(rs5c);
	if (status < 0)
		return status;
	if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) {
		addr = RS5C_ADDR(RS5C_REG_CTRL1);
		buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
		if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) {
			dev_dbg(dev, "can't disable alarm\n");
			return -EIO;
		}
		rs5c->regs[RS5C_REG_CTRL1] = buf[0];
	}

	/* set alarm */
	buf[0] = bin2bcd(t->time.tm_min);
	buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
	buf[2] = 0x7f;	/* any/all days */

	for (i = 0; i < sizeof(buf); i++) {
		addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
		if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) {
			dev_dbg(dev, "can't set alarm time\n");
			return -EIO;
		}
	}

	/* ... and maybe enable its irq */
	if (t->enabled) {
		addr = RS5C_ADDR(RS5C_REG_CTRL1);
		buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
		if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0)
			dev_warn(dev, "can't enable alarm\n");
		rs5c->regs[RS5C_REG_CTRL1] = buf[0];
	}

	return 0;
}

#if IS_ENABLED(CONFIG_RTC_INTF_PROC)

static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
{
	int err, osc, trim;

	err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim);
	if (err == 0) {
		seq_printf(seq, "crystal\t\t: %d.%03d KHz\n",
				osc / 1000, osc % 1000);
		seq_printf(seq, "trim\t\t: %d\n", trim);
	}

	return 0;
}

#else
#define	rs5c372_rtc_proc	NULL
#endif

#ifdef CONFIG_RTC_INTF_DEV
static int rs5c372_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	struct rs5c372	*rs5c = i2c_get_clientdata(to_i2c_client(dev));
	unsigned char	ctrl2;
	int		addr;
	unsigned int	flags;

	dev_dbg(dev, "%s: cmd=%x\n", __func__, cmd);

	addr = RS5C_ADDR(RS5C_REG_CTRL2);
	ctrl2 = i2c_smbus_read_byte_data(rs5c->client, addr);

	switch (cmd) {
	case RTC_VL_READ:
		flags = 0;

		switch (rs5c->type) {
		case rtc_r2025sd:
		case rtc_r2221tl:
			if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) ||
				(rs5c->type == rtc_r2221tl &&  (ctrl2 & R2x2x_CTRL2_XSTP))) {
				flags |= RTC_VL_DATA_INVALID;
			}
			if (ctrl2 & R2x2x_CTRL2_VDET)
				flags |= RTC_VL_BACKUP_LOW;
			break;
		default:
			if (ctrl2 & RS5C_CTRL2_XSTP)
				flags |= RTC_VL_DATA_INVALID;
			break;
		}

		return put_user(flags, (unsigned int __user *)arg);
	case RTC_VL_CLR:
		/* clear VDET bit */
		if (rs5c->type == rtc_r2025sd || rs5c->type == rtc_r2221tl) {
			ctrl2 &= ~R2x2x_CTRL2_VDET;
			if (i2c_smbus_write_byte_data(rs5c->client, addr, ctrl2) < 0) {
				dev_dbg(&rs5c->client->dev, "%s: write error in line %i\n",
						__func__, __LINE__);
				return -EIO;
			}
		}
		return 0;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}
#else
#define rs5c372_ioctl	NULL
#endif

static int rs5c372_read_offset(struct device *dev, long *offset)
{
	struct rs5c372 *rs5c = i2c_get_clientdata(to_i2c_client(dev));
	u8 val = rs5c->regs[RS5C372_REG_TRIM];
	long ppb_per_step = 0;
	bool decr = val & RS5C372_TRIM_DECR;

	switch (rs5c->type) {
	case rtc_r2221tl:
		ppb_per_step = val & R2221TL_TRIM_DEV ? 1017 : 3051;
		break;
	case rtc_rs5c372a:
	case rtc_rs5c372b:
		ppb_per_step = val & RS5C372_TRIM_XSL ? 3125 : 3051;
		break;
	default:
		ppb_per_step = 3051;
		break;
	}

	/* Only bits[0:5] repsents the time counts */
	val &= 0x3F;

	/* If bits[1:5] are all 0, it means no increment or decrement */
	if (!(val & 0x3E)) {
		*offset = 0;
	} else {
		if (decr)
			*offset = -(((~val) & 0x3F) + 1) * ppb_per_step;
		else
			*offset = (val - 1) * ppb_per_step;
	}

	return 0;
}

static int rs5c372_set_offset(struct device *dev, long offset)
{
	struct rs5c372 *rs5c = i2c_get_clientdata(to_i2c_client(dev));
	int addr = RS5C_ADDR(RS5C372_REG_TRIM);
	u8 val = 0;
	u8 tmp = 0;
	long ppb_per_step = 3051;
	long steps = LONG_MIN;

	switch (rs5c->type) {
	case rtc_rs5c372a:
	case rtc_rs5c372b:
		tmp = rs5c->regs[RS5C372_REG_TRIM];
		if (tmp & RS5C372_TRIM_XSL) {
			ppb_per_step = 3125;
			val |= RS5C372_TRIM_XSL;
		}
		break;
	case rtc_r2221tl:
		/*
		 * Check if it is possible to use high resolution mode (DEV=1).
		 * In this mode, the minimum resolution is 2 / (32768 * 20 * 3),
		 * which is about 1017 ppb.
		 */
		steps = DIV_ROUND_CLOSEST(offset, 1017);
		if (steps >= -0x3E && steps <= 0x3E) {
			ppb_per_step = 1017;
			val |= R2221TL_TRIM_DEV;
		} else {
			/*
			 * offset is out of the range of high resolution mode.
			 * Try to use low resolution mode (DEV=0). In this mode,
			 * the minimum resolution is 2 / (32768 * 20), which is
			 * about 3051 ppb.
			 */
			steps = LONG_MIN;
		}
		break;
	default:
		break;
	}

	if (steps == LONG_MIN) {
		steps = DIV_ROUND_CLOSEST(offset, ppb_per_step);
		if (steps > 0x3E || steps < -0x3E)
			return -ERANGE;
	}

	if (steps > 0) {
		val |= steps + 1;
	} else {
		val |= RS5C372_TRIM_DECR;
		val |= (~(-steps - 1)) & 0x3F;
	}

	if (!steps || !(val & 0x3E)) {
		/*
		 * if offset is too small, set oscillation adjustment register
		 * or time trimming register with its default value whic means
		 * no increment or decrement. But for rs5c372[a|b], the XSL bit
		 * should be kept unchanged.
		 */
		if (rs5c->type == rtc_rs5c372a || rs5c->type == rtc_rs5c372b)
			val &= RS5C372_TRIM_XSL;
		else
			val = 0;
	}

	dev_dbg(&rs5c->client->dev, "write 0x%x for offset %ld\n", val, offset);

	if (i2c_smbus_write_byte_data(rs5c->client, addr, val) < 0) {
		dev_err(&rs5c->client->dev, "failed to write 0x%x to reg %d\n", val, addr);
		return -EIO;
	}

	rs5c->regs[RS5C372_REG_TRIM] = val;

	return 0;
}

static const struct rtc_class_ops rs5c372_rtc_ops = {
	.proc		= rs5c372_rtc_proc,
	.read_time	= rs5c372_rtc_read_time,
	.set_time	= rs5c372_rtc_set_time,
	.read_alarm	= rs5c_read_alarm,
	.set_alarm	= rs5c_set_alarm,
	.alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
	.ioctl		= rs5c372_ioctl,
	.read_offset    = rs5c372_read_offset,
	.set_offset     = rs5c372_set_offset,
};

#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)

static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	int err, trim;

	err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim);
	if (err)
		return err;

	return sprintf(buf, "%d\n", trim);
}
static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL);

static ssize_t rs5c372_sysfs_show_osc(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	int err, osc;

	err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL);
	if (err)
		return err;

	return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000);
}
static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL);

static int rs5c_sysfs_register(struct device *dev)
{
	int err;

	err = device_create_file(dev, &dev_attr_trim);
	if (err)
		return err;
	err = device_create_file(dev, &dev_attr_osc);
	if (err)
		device_remove_file(dev, &dev_attr_trim);

	return err;
}

static void rs5c_sysfs_unregister(struct device *dev)
{
	device_remove_file(dev, &dev_attr_trim);
	device_remove_file(dev, &dev_attr_osc);
}

#else
static int rs5c_sysfs_register(struct device *dev)
{
	return 0;
}

static void rs5c_sysfs_unregister(struct device *dev)
{
	/* nothing */
}
#endif	/* SYSFS */

static struct i2c_driver rs5c372_driver;

static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
{
	unsigned char buf[2];
	int addr, i, ret = 0;

	addr   = RS5C_ADDR(RS5C_REG_CTRL1);
	buf[0] = rs5c372->regs[RS5C_REG_CTRL1];
	buf[1] = rs5c372->regs[RS5C_REG_CTRL2];

	switch (rs5c372->type) {
	case rtc_r2025sd:
		if (buf[1] & R2x2x_CTRL2_XSTP)
			return ret;
		break;
	case rtc_r2221tl:
		if (!(buf[1] & R2x2x_CTRL2_XSTP))
			return ret;
		break;
	default:
		if (!(buf[1] & RS5C_CTRL2_XSTP))
			return ret;
		break;
	}

	/* use 24hr mode */
	switch (rs5c372->type) {
	case rtc_rs5c372a:
	case rtc_rs5c372b:
		buf[1] |= RS5C372_CTRL2_24;
		rs5c372->time24 = 1;
		break;
	case rtc_r2025sd:
	case rtc_r2221tl:
	case rtc_rv5c386:
	case rtc_rv5c387a:
		buf[0] |= RV5C387_CTRL1_24;
		rs5c372->time24 = 1;
		break;
	default:
		/* impossible */
		break;
	}

	for (i = 0; i < sizeof(buf); i++) {
		addr = RS5C_ADDR(RS5C_REG_CTRL1 + i);
		ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]);
		if (unlikely(ret < 0))
			return ret;
	}

	rs5c372->regs[RS5C_REG_CTRL1] = buf[0];
	rs5c372->regs[RS5C_REG_CTRL2] = buf[1];

	return 0;
}

static int rs5c372_probe(struct i2c_client *client)
{
	int err = 0;
	int smbus_mode = 0;
	struct rs5c372 *rs5c372;

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

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) {
		/*
		 * If we don't have any master mode adapter, try breaking
		 * it down in to the barest of capabilities.
		 */
		if (i2c_check_functionality(client->adapter,
				I2C_FUNC_SMBUS_BYTE_DATA |
				I2C_FUNC_SMBUS_I2C_BLOCK))
			smbus_mode = 1;
		else {
			/* Still no good, give up */
			err = -ENODEV;
			goto exit;
		}
	}

	rs5c372 = devm_kzalloc(&client->dev, sizeof(struct rs5c372),
				GFP_KERNEL);
	if (!rs5c372) {
		err = -ENOMEM;
		goto exit;
	}

	rs5c372->client = client;
	i2c_set_clientdata(client, rs5c372);
	if (client->dev.of_node) {
		rs5c372->type = (enum rtc_type)
			of_device_get_match_data(&client->dev);
	} else {
		const struct i2c_device_id *id = i2c_match_id(rs5c372_id, client);
		rs5c372->type = id->driver_data;
	}

	/* we read registers 0x0f then 0x00-0x0f; skip the first one */
	rs5c372->regs = &rs5c372->buf[1];
	rs5c372->smbus = smbus_mode;

	err = rs5c_get_regs(rs5c372);
	if (err < 0)
		goto exit;

	/* clock may be set for am/pm or 24 hr time */
	switch (rs5c372->type) {
	case rtc_rs5c372a:
	case rtc_rs5c372b:
		/* alarm uses ALARM_A; and nINTRA on 372a, nINTR on 372b.
		 * so does periodic irq, except some 327a modes.
		 */
		if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24)
			rs5c372->time24 = 1;
		break;
	case rtc_r2025sd:
	case rtc_r2221tl:
	case rtc_rv5c386:
	case rtc_rv5c387a:
		if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24)
			rs5c372->time24 = 1;
		/* alarm uses ALARM_W; and nINTRB for alarm and periodic
		 * irq, on both 386 and 387
		 */
		break;
	default:
		dev_err(&client->dev, "unknown RTC type\n");
		goto exit;
	}

	/* if the oscillator lost power and no other software (like
	 * the bootloader) set it up, do it here.
	 *
	 * The R2025S/D does this a little differently than the other
	 * parts, so we special case that..
	 */
	err = rs5c_oscillator_setup(rs5c372);
	if (unlikely(err < 0)) {
		dev_err(&client->dev, "setup error\n");
		goto exit;
	}

	dev_info(&client->dev, "%s found, %s\n",
			({ char *s; switch (rs5c372->type) {
			case rtc_r2025sd:	s = "r2025sd"; break;
			case rtc_r2221tl:	s = "r2221tl"; break;
			case rtc_rs5c372a:	s = "rs5c372a"; break;
			case rtc_rs5c372b:	s = "rs5c372b"; break;
			case rtc_rv5c386:	s = "rv5c386"; break;
			case rtc_rv5c387a:	s = "rv5c387a"; break;
			default:		s = "chip"; break;
			}; s;}),
			rs5c372->time24 ? "24hr" : "am/pm"
			);

	/* REVISIT use client->irq to register alarm irq ... */
	rs5c372->rtc = devm_rtc_device_register(&client->dev,
					rs5c372_driver.driver.name,
					&rs5c372_rtc_ops, THIS_MODULE);

	if (IS_ERR(rs5c372->rtc)) {
		err = PTR_ERR(rs5c372->rtc);
		goto exit;
	}

	err = rs5c_sysfs_register(&client->dev);
	if (err)
		goto exit;

	return 0;

exit:
	return err;
}

static void rs5c372_remove(struct i2c_client *client)
{
	rs5c_sysfs_unregister(&client->dev);
}

static struct i2c_driver rs5c372_driver = {
	.driver		= {
		.name	= "rtc-rs5c372",
		.of_match_table = of_match_ptr(rs5c372_of_match),
	},
	.probe_new	= rs5c372_probe,
	.remove		= rs5c372_remove,
	.id_table	= rs5c372_id,
};

module_i2c_driver(rs5c372_driver);

MODULE_AUTHOR(
		"Pavel Mironchik <pmironchik@optifacio.net>, "
		"Alessandro Zummo <a.zummo@towertech.it>, "
		"Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
MODULE_LICENSE("GPL");
