/*
 * rtc-as3722.c - Real Time Clock driver for ams AS3722 PMICs
 *
 * Copyright (C) 2013 ams AG
 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
 *
 * Author: Florian Lobmaier <florian.lobmaier@ams.com>
 * Author: Laxman Dewangan <ldewangan@nvidia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/bcd.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/as3722.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/time.h>

#define AS3722_RTC_START_YEAR	  2000
struct as3722_rtc {
	struct rtc_device	*rtc;
	struct device		*dev;
	struct as3722		*as3722;
	int			alarm_irq;
	bool			irq_enable;
};

static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm)
{
	rbuff[0] = bin2bcd(tm->tm_sec);
	rbuff[1] = bin2bcd(tm->tm_min);
	rbuff[2] = bin2bcd(tm->tm_hour);
	rbuff[3] = bin2bcd(tm->tm_mday);
	rbuff[4] = bin2bcd(tm->tm_mon);
	rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900));
}

static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm)
{
	tm->tm_sec = bcd2bin(rbuff[0] & 0x7F);
	tm->tm_min = bcd2bin(rbuff[1] & 0x7F);
	tm->tm_hour = bcd2bin(rbuff[2] & 0x3F);
	tm->tm_mday = bcd2bin(rbuff[3] & 0x3F);
	tm->tm_mon = bcd2bin(rbuff[4] & 0x1F);
	tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F);
	return;
}

static int as3722_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
	struct as3722 *as3722 = as3722_rtc->as3722;
	u8 as_time_array[6];
	int ret;

	ret = as3722_block_read(as3722, AS3722_RTC_SECOND_REG,
			6, as_time_array);
	if (ret < 0) {
		dev_err(dev, "RTC_SECOND reg block read failed %d\n", ret);
		return ret;
	}
	as3722_reg_to_time(as_time_array, tm);
	return 0;
}

static int as3722_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
	struct as3722 *as3722 = as3722_rtc->as3722;
	u8 as_time_array[6];
	int ret;

	if (tm->tm_year < (AS3722_RTC_START_YEAR - 1900))
		return -EINVAL;

	as3722_time_to_reg(as_time_array, tm);
	ret = as3722_block_write(as3722, AS3722_RTC_SECOND_REG, 6,
			as_time_array);
	if (ret < 0)
		dev_err(dev, "RTC_SECOND reg block write failed %d\n", ret);
	return ret;
}

static int as3722_rtc_alarm_irq_enable(struct device *dev,
		unsigned int enabled)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);

	if (enabled && !as3722_rtc->irq_enable) {
		enable_irq(as3722_rtc->alarm_irq);
		as3722_rtc->irq_enable = true;
	} else if (!enabled && as3722_rtc->irq_enable)  {
		disable_irq(as3722_rtc->alarm_irq);
		as3722_rtc->irq_enable = false;
	}
	return 0;
}

static int as3722_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
	struct as3722 *as3722 = as3722_rtc->as3722;
	u8 as_time_array[6];
	int ret;

	ret = as3722_block_read(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
			as_time_array);
	if (ret < 0) {
		dev_err(dev, "RTC_ALARM_SECOND block read failed %d\n", ret);
		return ret;
	}

	as3722_reg_to_time(as_time_array, &alrm->time);
	return 0;
}

static int as3722_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
	struct as3722 *as3722 = as3722_rtc->as3722;
	u8 as_time_array[6];
	int ret;

	if (alrm->time.tm_year < (AS3722_RTC_START_YEAR - 1900))
		return -EINVAL;

	ret = as3722_rtc_alarm_irq_enable(dev, 0);
	if (ret < 0) {
		dev_err(dev, "Disable RTC alarm failed\n");
		return ret;
	}

	as3722_time_to_reg(as_time_array, &alrm->time);
	ret = as3722_block_write(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
			as_time_array);
	if (ret < 0) {
		dev_err(dev, "RTC_ALARM_SECOND block write failed %d\n", ret);
		return ret;
	}

	if (alrm->enabled)
		ret = as3722_rtc_alarm_irq_enable(dev, alrm->enabled);
	return ret;
}

static irqreturn_t as3722_alarm_irq(int irq, void *data)
{
	struct as3722_rtc *as3722_rtc = data;

	rtc_update_irq(as3722_rtc->rtc, 1, RTC_IRQF | RTC_AF);
	return IRQ_HANDLED;
}

static const struct rtc_class_ops as3722_rtc_ops = {
	.read_time = as3722_rtc_read_time,
	.set_time = as3722_rtc_set_time,
	.read_alarm = as3722_rtc_read_alarm,
	.set_alarm = as3722_rtc_set_alarm,
	.alarm_irq_enable = as3722_rtc_alarm_irq_enable,
};

static int as3722_rtc_probe(struct platform_device *pdev)
{
	struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
	struct as3722_rtc *as3722_rtc;
	int ret;

	as3722_rtc = devm_kzalloc(&pdev->dev, sizeof(*as3722_rtc), GFP_KERNEL);
	if (!as3722_rtc)
		return -ENOMEM;

	as3722_rtc->as3722 = as3722;
	as3722_rtc->dev = &pdev->dev;
	platform_set_drvdata(pdev, as3722_rtc);

	/* Enable the RTC to make sure it is running. */
	ret = as3722_update_bits(as3722, AS3722_RTC_CONTROL_REG,
			AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN,
			AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN);
	if (ret < 0) {
		dev_err(&pdev->dev, "RTC_CONTROL reg write failed: %d\n", ret);
		return ret;
	}

	device_init_wakeup(&pdev->dev, 1);

	as3722_rtc->rtc = devm_rtc_device_register(&pdev->dev, "as3722-rtc",
				&as3722_rtc_ops, THIS_MODULE);
	if (IS_ERR(as3722_rtc->rtc)) {
		ret = PTR_ERR(as3722_rtc->rtc);
		dev_err(&pdev->dev, "RTC register failed: %d\n", ret);
		return ret;
	}

	as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
	dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);

	ret = devm_request_threaded_irq(&pdev->dev, as3722_rtc->alarm_irq, NULL,
			as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
			"rtc-alarm", as3722_rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
				as3722_rtc->alarm_irq, ret);
		return ret;
	}
	disable_irq(as3722_rtc->alarm_irq);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int as3722_rtc_suspend(struct device *dev)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);

	if (device_may_wakeup(dev))
		enable_irq_wake(as3722_rtc->alarm_irq);

	return 0;
}

static int as3722_rtc_resume(struct device *dev)
{
	struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);

	if (device_may_wakeup(dev))
		disable_irq_wake(as3722_rtc->alarm_irq);
	return 0;
}
#endif

static const struct dev_pm_ops as3722_rtc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(as3722_rtc_suspend, as3722_rtc_resume)
};

static struct platform_driver as3722_rtc_driver = {
	.probe = as3722_rtc_probe,
	.driver = {
		.name = "as3722-rtc",
		.pm = &as3722_rtc_pm_ops,
	},
};
module_platform_driver(as3722_rtc_driver);

MODULE_DESCRIPTION("RTC driver for AS3722 PMICs");
MODULE_ALIAS("platform:as3722-rtc");
MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_LICENSE("GPL");
