// SPDX-License-Identifier: GPL-2.0-only
/*
 * TI LP8788 MFD - rtc driver
 *
 * Copyright 2012 Texas Instruments
 *
 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
 */

#include <linux/err.h>
#include <linux/irqdomain.h>
#include <linux/mfd/lp8788.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/slab.h>

/* register address */
#define LP8788_INTEN_3			0x05
#define LP8788_RTC_UNLOCK		0x64
#define LP8788_RTC_SEC			0x70
#define LP8788_ALM1_SEC			0x77
#define LP8788_ALM1_EN			0x7D
#define LP8788_ALM2_SEC			0x7E
#define LP8788_ALM2_EN			0x84

/* mask/shift bits */
#define LP8788_INT_RTC_ALM1_M		BIT(1)	/* Addr 05h */
#define LP8788_INT_RTC_ALM1_S		1
#define LP8788_INT_RTC_ALM2_M		BIT(2)	/* Addr 05h */
#define LP8788_INT_RTC_ALM2_S		2
#define LP8788_ALM_EN_M			BIT(7)	/* Addr 7Dh or 84h */
#define LP8788_ALM_EN_S			7

#define DEFAULT_ALARM_SEL		LP8788_ALARM_1
#define LP8788_MONTH_OFFSET		1
#define LP8788_BASE_YEAR		2000
#define MAX_WDAY_BITS			7
#define LP8788_WDAY_SET			1
#define RTC_UNLOCK			0x1
#define RTC_LATCH			0x2
#define ALARM_IRQ_FLAG			(RTC_IRQF | RTC_AF)

enum lp8788_time {
	LPTIME_SEC,
	LPTIME_MIN,
	LPTIME_HOUR,
	LPTIME_MDAY,
	LPTIME_MON,
	LPTIME_YEAR,
	LPTIME_WDAY,
	LPTIME_MAX,
};

struct lp8788_rtc {
	struct lp8788 *lp;
	struct rtc_device *rdev;
	enum lp8788_alarm_sel alarm;
	int irq;
};

static const u8 addr_alarm_sec[LP8788_ALARM_MAX] = {
	LP8788_ALM1_SEC,
	LP8788_ALM2_SEC,
};

static const u8 addr_alarm_en[LP8788_ALARM_MAX] = {
	LP8788_ALM1_EN,
	LP8788_ALM2_EN,
};

static const u8 mask_alarm_en[LP8788_ALARM_MAX] = {
	LP8788_INT_RTC_ALM1_M,
	LP8788_INT_RTC_ALM2_M,
};

static const u8 shift_alarm_en[LP8788_ALARM_MAX] = {
	LP8788_INT_RTC_ALM1_S,
	LP8788_INT_RTC_ALM2_S,
};

static int _to_tm_wday(u8 lp8788_wday)
{
	int i;

	if (lp8788_wday == 0)
		return 0;

	/* lookup defined weekday from read register value */
	for (i = 0; i < MAX_WDAY_BITS; i++) {
		if ((lp8788_wday >> i) == LP8788_WDAY_SET)
			break;
	}

	return i + 1;
}

static inline int _to_lp8788_wday(int tm_wday)
{
	return LP8788_WDAY_SET << (tm_wday - 1);
}

static void lp8788_rtc_unlock(struct lp8788 *lp)
{
	lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_UNLOCK);
	lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_LATCH);
}

static int lp8788_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct lp8788_rtc *rtc = dev_get_drvdata(dev);
	struct lp8788 *lp = rtc->lp;
	u8 data[LPTIME_MAX];
	int ret;

	lp8788_rtc_unlock(lp);

	ret = lp8788_read_multi_bytes(lp, LP8788_RTC_SEC, data,	LPTIME_MAX);
	if (ret)
		return ret;

	tm->tm_sec  = data[LPTIME_SEC];
	tm->tm_min  = data[LPTIME_MIN];
	tm->tm_hour = data[LPTIME_HOUR];
	tm->tm_mday = data[LPTIME_MDAY];
	tm->tm_mon  = data[LPTIME_MON] - LP8788_MONTH_OFFSET;
	tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900;
	tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]);

	return 0;
}

static int lp8788_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct lp8788_rtc *rtc = dev_get_drvdata(dev);
	struct lp8788 *lp = rtc->lp;
	u8 data[LPTIME_MAX - 1];
	int ret, i, year;

	year = tm->tm_year + 1900 - LP8788_BASE_YEAR;
	if (year < 0) {
		dev_err(lp->dev, "invalid year: %d\n", year);
		return -EINVAL;
	}

	/* because rtc weekday is a readonly register, do not update */
	data[LPTIME_SEC]  = tm->tm_sec;
	data[LPTIME_MIN]  = tm->tm_min;
	data[LPTIME_HOUR] = tm->tm_hour;
	data[LPTIME_MDAY] = tm->tm_mday;
	data[LPTIME_MON]  = tm->tm_mon + LP8788_MONTH_OFFSET;
	data[LPTIME_YEAR] = year;

	for (i = 0; i < ARRAY_SIZE(data); i++) {
		ret = lp8788_write_byte(lp, LP8788_RTC_SEC + i, data[i]);
		if (ret)
			return ret;
	}

	return 0;
}

static int lp8788_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
	struct lp8788_rtc *rtc = dev_get_drvdata(dev);
	struct lp8788 *lp = rtc->lp;
	struct rtc_time *tm = &alarm->time;
	u8 addr, data[LPTIME_MAX];
	int ret;

	addr = addr_alarm_sec[rtc->alarm];
	ret = lp8788_read_multi_bytes(lp, addr, data, LPTIME_MAX);
	if (ret)
		return ret;

	tm->tm_sec  = data[LPTIME_SEC];
	tm->tm_min  = data[LPTIME_MIN];
	tm->tm_hour = data[LPTIME_HOUR];
	tm->tm_mday = data[LPTIME_MDAY];
	tm->tm_mon  = data[LPTIME_MON] - LP8788_MONTH_OFFSET;
	tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900;
	tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]);
	alarm->enabled = data[LPTIME_WDAY] & LP8788_ALM_EN_M;

	return 0;
}

static int lp8788_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
	struct lp8788_rtc *rtc = dev_get_drvdata(dev);
	struct lp8788 *lp = rtc->lp;
	struct rtc_time *tm = &alarm->time;
	u8 addr, data[LPTIME_MAX];
	int ret, i, year;

	year = tm->tm_year + 1900 - LP8788_BASE_YEAR;
	if (year < 0) {
		dev_err(lp->dev, "invalid year: %d\n", year);
		return -EINVAL;
	}

	data[LPTIME_SEC]  = tm->tm_sec;
	data[LPTIME_MIN]  = tm->tm_min;
	data[LPTIME_HOUR] = tm->tm_hour;
	data[LPTIME_MDAY] = tm->tm_mday;
	data[LPTIME_MON]  = tm->tm_mon + LP8788_MONTH_OFFSET;
	data[LPTIME_YEAR] = year;
	data[LPTIME_WDAY] = _to_lp8788_wday(tm->tm_wday);

	for (i = 0; i < ARRAY_SIZE(data); i++) {
		addr = addr_alarm_sec[rtc->alarm] + i;
		ret = lp8788_write_byte(lp, addr, data[i]);
		if (ret)
			return ret;
	}

	alarm->enabled = 1;
	addr = addr_alarm_en[rtc->alarm];

	return lp8788_update_bits(lp, addr, LP8788_ALM_EN_M,
				alarm->enabled << LP8788_ALM_EN_S);
}

static int lp8788_alarm_irq_enable(struct device *dev, unsigned int enable)
{
	struct lp8788_rtc *rtc = dev_get_drvdata(dev);
	struct lp8788 *lp = rtc->lp;
	u8 mask, shift;

	if (!rtc->irq)
		return -EIO;

	mask = mask_alarm_en[rtc->alarm];
	shift = shift_alarm_en[rtc->alarm];

	return lp8788_update_bits(lp, LP8788_INTEN_3, mask, enable << shift);
}

static const struct rtc_class_ops lp8788_rtc_ops = {
	.read_time = lp8788_rtc_read_time,
	.set_time = lp8788_rtc_set_time,
	.read_alarm = lp8788_read_alarm,
	.set_alarm = lp8788_set_alarm,
	.alarm_irq_enable = lp8788_alarm_irq_enable,
};

static irqreturn_t lp8788_alarm_irq_handler(int irq, void *ptr)
{
	struct lp8788_rtc *rtc = ptr;

	rtc_update_irq(rtc->rdev, 1, ALARM_IRQ_FLAG);
	return IRQ_HANDLED;
}

static int lp8788_alarm_irq_register(struct platform_device *pdev,
				struct lp8788_rtc *rtc)
{
	struct resource *r;
	struct lp8788 *lp = rtc->lp;
	struct irq_domain *irqdm = lp->irqdm;
	int irq;

	rtc->irq = 0;

	/* even the alarm IRQ number is not specified, rtc time should work */
	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, LP8788_ALM_IRQ);
	if (!r)
		return 0;

	if (rtc->alarm == LP8788_ALARM_1)
		irq = r->start;
	else
		irq = r->end;

	rtc->irq = irq_create_mapping(irqdm, irq);

	return devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
				lp8788_alarm_irq_handler,
				0, LP8788_ALM_IRQ, rtc);
}

static int lp8788_rtc_probe(struct platform_device *pdev)
{
	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
	struct lp8788_rtc *rtc;
	struct device *dev = &pdev->dev;

	rtc = devm_kzalloc(dev, sizeof(struct lp8788_rtc), GFP_KERNEL);
	if (!rtc)
		return -ENOMEM;

	rtc->lp = lp;
	rtc->alarm = lp->pdata ? lp->pdata->alarm_sel : DEFAULT_ALARM_SEL;
	platform_set_drvdata(pdev, rtc);

	device_init_wakeup(dev, 1);

	rtc->rdev = devm_rtc_device_register(dev, "lp8788_rtc",
					&lp8788_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc->rdev)) {
		dev_err(dev, "can not register rtc device\n");
		return PTR_ERR(rtc->rdev);
	}

	if (lp8788_alarm_irq_register(pdev, rtc))
		dev_warn(lp->dev, "no rtc irq handler\n");

	return 0;
}

static struct platform_driver lp8788_rtc_driver = {
	.probe = lp8788_rtc_probe,
	.driver = {
		.name = LP8788_DEV_RTC,
	},
};
module_platform_driver(lp8788_rtc_driver);

MODULE_DESCRIPTION("Texas Instruments LP8788 RTC Driver");
MODULE_AUTHOR("Milo Kim");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:lp8788-rtc");
