/*
 * TI LP8788 MFD - rtc driver
 *
 * Copyright 2012 Texas Instruments
 *
 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#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");
