/*
 * An rtc driver for the Dallas DS1511
 *
 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.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.
 *
 * Real time clock driver for the Dallas 1511 chip, which also
 * contains a watchdog timer.  There is a tiny amount of code that
 * platform code could use to mess with the watchdog device a little
 * bit, but not a full watchdog driver.
 */

#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/io.h>

#define DRV_VERSION "0.6"

enum ds1511reg {
	DS1511_SEC = 0x0,
	DS1511_MIN = 0x1,
	DS1511_HOUR = 0x2,
	DS1511_DOW = 0x3,
	DS1511_DOM = 0x4,
	DS1511_MONTH = 0x5,
	DS1511_YEAR = 0x6,
	DS1511_CENTURY = 0x7,
	DS1511_AM1_SEC = 0x8,
	DS1511_AM2_MIN = 0x9,
	DS1511_AM3_HOUR = 0xa,
	DS1511_AM4_DATE = 0xb,
	DS1511_WD_MSEC = 0xc,
	DS1511_WD_SEC = 0xd,
	DS1511_CONTROL_A = 0xe,
	DS1511_CONTROL_B = 0xf,
	DS1511_RAMADDR_LSB = 0x10,
	DS1511_RAMDATA = 0x13
};

#define DS1511_BLF1	0x80
#define DS1511_BLF2	0x40
#define DS1511_PRS	0x20
#define DS1511_PAB	0x10
#define DS1511_TDF	0x08
#define DS1511_KSF	0x04
#define DS1511_WDF	0x02
#define DS1511_IRQF	0x01
#define DS1511_TE	0x80
#define DS1511_CS	0x40
#define DS1511_BME	0x20
#define DS1511_TPE	0x10
#define DS1511_TIE	0x08
#define DS1511_KIE	0x04
#define DS1511_WDE	0x02
#define DS1511_WDS	0x01
#define DS1511_RAM_MAX	0xff

#define RTC_CMD		DS1511_CONTROL_B
#define RTC_CMD1	DS1511_CONTROL_A

#define RTC_ALARM_SEC	DS1511_AM1_SEC
#define RTC_ALARM_MIN	DS1511_AM2_MIN
#define RTC_ALARM_HOUR	DS1511_AM3_HOUR
#define RTC_ALARM_DATE	DS1511_AM4_DATE

#define RTC_SEC		DS1511_SEC
#define RTC_MIN		DS1511_MIN
#define RTC_HOUR	DS1511_HOUR
#define RTC_DOW		DS1511_DOW
#define RTC_DOM		DS1511_DOM
#define RTC_MON		DS1511_MONTH
#define RTC_YEAR	DS1511_YEAR
#define RTC_CENTURY	DS1511_CENTURY

#define RTC_TIE	DS1511_TIE
#define RTC_TE	DS1511_TE

struct rtc_plat_data {
	struct rtc_device *rtc;
	void __iomem *ioaddr;		/* virtual base address */
	unsigned long baseaddr;		/* physical base address */
	int size;				/* amount of memory mapped */
	int irq;
	unsigned int irqen;
	int alrm_sec;
	int alrm_min;
	int alrm_hour;
	int alrm_mday;
};

static DEFINE_SPINLOCK(ds1511_lock);

static __iomem char *ds1511_base;
static u32 reg_spacing = 1;

 static noinline void
rtc_write(uint8_t val, uint32_t reg)
{
	writeb(val, ds1511_base + (reg * reg_spacing));
}

 static inline void
rtc_write_alarm(uint8_t val, enum ds1511reg reg)
{
	rtc_write((val | 0x80), reg);
}

 static noinline uint8_t
rtc_read(enum ds1511reg reg)
{
	return readb(ds1511_base + (reg * reg_spacing));
}

 static inline void
rtc_disable_update(void)
{
	rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD);
}

 static void
rtc_enable_update(void)
{
	rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD);
}

/*
 * #define DS1511_WDOG_RESET_SUPPORT
 *
 * Uncomment this if you want to use these routines in
 * some platform code.
 */
#ifdef DS1511_WDOG_RESET_SUPPORT
/*
 * just enough code to set the watchdog timer so that it
 * will reboot the system
 */
 void
ds1511_wdog_set(unsigned long deciseconds)
{
	/*
	 * the wdog timer can take 99.99 seconds
	 */
	deciseconds %= 10000;
	/*
	 * set the wdog values in the wdog registers
	 */
	rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC);
	rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC);
	/*
	 * set wdog enable and wdog 'steering' bit to issue a reset
	 */
	rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD);
}

 void
ds1511_wdog_disable(void)
{
	/*
	 * clear wdog enable and wdog 'steering' bits
	 */
	rtc_write(rtc_read(RTC_CMD) & ~(DS1511_WDE | DS1511_WDS), RTC_CMD);
	/*
	 * clear the wdog counter
	 */
	rtc_write(0, DS1511_WD_MSEC);
	rtc_write(0, DS1511_WD_SEC);
}
#endif

/*
 * set the rtc chip's idea of the time.
 * stupidly, some callers call with year unmolested;
 * and some call with  year = year - 1900.  thanks.
 */
 int
ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
{
	u8 mon, day, dow, hrs, min, sec, yrs, cen;
	unsigned int flags;

	/*
	 * won't have to change this for a while
	 */
	if (rtc_tm->tm_year < 1900) {
		rtc_tm->tm_year += 1900;
	}

	if (rtc_tm->tm_year < 1970) {
		return -EINVAL;
	}
	yrs = rtc_tm->tm_year % 100;
	cen = rtc_tm->tm_year / 100;
	mon = rtc_tm->tm_mon + 1;   /* tm_mon starts at zero */
	day = rtc_tm->tm_mday;
	dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */
	hrs = rtc_tm->tm_hour;
	min = rtc_tm->tm_min;
	sec = rtc_tm->tm_sec;

	if ((mon > 12) || (day == 0)) {
		return -EINVAL;
	}

	if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) {
		return -EINVAL;
	}

	if ((hrs >= 24) || (min >= 60) || (sec >= 60)) {
		return -EINVAL;
	}

	/*
	 * each register is a different number of valid bits
	 */
	sec = BIN2BCD(sec) & 0x7f;
	min = BIN2BCD(min) & 0x7f;
	hrs = BIN2BCD(hrs) & 0x3f;
	day = BIN2BCD(day) & 0x3f;
	mon = BIN2BCD(mon) & 0x1f;
	yrs = BIN2BCD(yrs) & 0xff;
	cen = BIN2BCD(cen) & 0xff;

	spin_lock_irqsave(&ds1511_lock, flags);
	rtc_disable_update();
	rtc_write(cen, RTC_CENTURY);
	rtc_write(yrs, RTC_YEAR);
	rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON);
	rtc_write(day, RTC_DOM);
	rtc_write(hrs, RTC_HOUR);
	rtc_write(min, RTC_MIN);
	rtc_write(sec, RTC_SEC);
	rtc_write(dow, RTC_DOW);
	rtc_enable_update();
	spin_unlock_irqrestore(&ds1511_lock, flags);

	return 0;
}

 int
ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
{
	unsigned int century;
	unsigned int flags;

	spin_lock_irqsave(&ds1511_lock, flags);
	rtc_disable_update();

	rtc_tm->tm_sec = rtc_read(RTC_SEC) & 0x7f;
	rtc_tm->tm_min = rtc_read(RTC_MIN) & 0x7f;
	rtc_tm->tm_hour = rtc_read(RTC_HOUR) & 0x3f;
	rtc_tm->tm_mday = rtc_read(RTC_DOM) & 0x3f;
	rtc_tm->tm_wday = rtc_read(RTC_DOW) & 0x7;
	rtc_tm->tm_mon = rtc_read(RTC_MON) & 0x1f;
	rtc_tm->tm_year = rtc_read(RTC_YEAR) & 0x7f;
	century = rtc_read(RTC_CENTURY);

	rtc_enable_update();
	spin_unlock_irqrestore(&ds1511_lock, flags);

	rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec);
	rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min);
	rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour);
	rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday);
	rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday);
	rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon);
	rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year);
	century = BCD2BIN(century) * 100;

	/*
	 * Account for differences between how the RTC uses the values
	 * and how they are defined in a struct rtc_time;
	 */
	century += rtc_tm->tm_year;
	rtc_tm->tm_year = century - 1900;

	rtc_tm->tm_mon--;

	if (rtc_valid_tm(rtc_tm) < 0) {
		dev_err(dev, "retrieved date/time is not valid.\n");
		rtc_time_to_tm(0, rtc_tm);
	}
	return 0;
}

/*
 * write the alarm register settings
 *
 * we only have the use to interrupt every second, otherwise
 * known as the update interrupt, or the interrupt if the whole
 * date/hours/mins/secs matches.  the ds1511 has many more
 * permutations, but the kernel doesn't.
 */
 static void
ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
{
	unsigned long flags;

	spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
	rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
	       0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f,
	       RTC_ALARM_DATE);
	rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
	       0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f,
	       RTC_ALARM_HOUR);
	rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
	       0x80 : BIN2BCD(pdata->alrm_min) & 0x7f,
	       RTC_ALARM_MIN);
	rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
	       0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f,
	       RTC_ALARM_SEC);
	rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD);
	rtc_read(RTC_CMD1);	/* clear interrupts */
	spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
}

 static int
ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);

	if (pdata->irq < 0) {
		return -EINVAL;
	}
	pdata->alrm_mday = alrm->time.tm_mday;
	pdata->alrm_hour = alrm->time.tm_hour;
	pdata->alrm_min = alrm->time.tm_min;
	pdata->alrm_sec = alrm->time.tm_sec;
	if (alrm->enabled) {
		pdata->irqen |= RTC_AF;
	}
	ds1511_rtc_update_alarm(pdata);
	return 0;
}

 static int
ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);

	if (pdata->irq < 0) {
		return -EINVAL;
	}
	alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
	alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
	alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
	alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
	alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
	return 0;
}

 static irqreturn_t
ds1511_interrupt(int irq, void *dev_id)
{
	struct platform_device *pdev = dev_id;
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
	unsigned long events = RTC_IRQF;

	/*
	 * read and clear interrupt
	 */
	if (!(rtc_read(RTC_CMD1) & DS1511_IRQF)) {
		return IRQ_NONE;
	}
	if (rtc_read(RTC_ALARM_SEC) & 0x80) {
		events |= RTC_UF;
	} else {
		events |= RTC_AF;
	}
	rtc_update_irq(pdata->rtc, 1, events);
	return IRQ_HANDLED;
}

 static void
ds1511_rtc_release(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);

	if (pdata->irq >= 0) {
		pdata->irqen = 0;
		ds1511_rtc_update_alarm(pdata);
	}
}

 static int
ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);

	if (pdata->irq < 0) {
		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
	}
	switch (cmd) {
	case RTC_AIE_OFF:
		pdata->irqen &= ~RTC_AF;
		ds1511_rtc_update_alarm(pdata);
		break;
	case RTC_AIE_ON:
		pdata->irqen |= RTC_AF;
		ds1511_rtc_update_alarm(pdata);
		break;
	case RTC_UIE_OFF:
		pdata->irqen &= ~RTC_UF;
		ds1511_rtc_update_alarm(pdata);
		break;
	case RTC_UIE_ON:
		pdata->irqen |= RTC_UF;
		ds1511_rtc_update_alarm(pdata);
		break;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static const struct rtc_class_ops ds1511_rtc_ops = {
	.read_time	= ds1511_rtc_read_time,
	.set_time	= ds1511_rtc_set_time,
	.read_alarm	= ds1511_rtc_read_alarm,
	.set_alarm	= ds1511_rtc_set_alarm,
	.release	= ds1511_rtc_release,
	.ioctl		= ds1511_rtc_ioctl,
};

 static ssize_t
ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba,
				char *buf, loff_t pos, size_t size)
{
	ssize_t count;

	/*
	 * if count is more than one, turn on "burst" mode
	 * turn it off when you're done
	 */
	if (size > 1) {
		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
	}
	if (pos > DS1511_RAM_MAX) {
		pos = DS1511_RAM_MAX;
	}
	if (size + pos > DS1511_RAM_MAX + 1) {
		size = DS1511_RAM_MAX - pos + 1;
	}
	rtc_write(pos, DS1511_RAMADDR_LSB);
	for (count = 0; size > 0; count++, size--) {
		*buf++ = rtc_read(DS1511_RAMDATA);
	}
	if (count > 1) {
		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
	}
	return count;
}

 static ssize_t
ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr,
				char *buf, loff_t pos, size_t size)
{
	ssize_t count;

	/*
	 * if count is more than one, turn on "burst" mode
	 * turn it off when you're done
	 */
	if (size > 1) {
		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
	}
	if (pos > DS1511_RAM_MAX) {
		pos = DS1511_RAM_MAX;
	}
	if (size + pos > DS1511_RAM_MAX + 1) {
		size = DS1511_RAM_MAX - pos + 1;
	}
	rtc_write(pos, DS1511_RAMADDR_LSB);
	for (count = 0; size > 0; count++, size--) {
		rtc_write(*buf++, DS1511_RAMDATA);
	}
	if (count > 1) {
		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
	}
	return count;
}

static struct bin_attribute ds1511_nvram_attr = {
	.attr = {
		.name = "nvram",
		.mode = S_IRUGO | S_IWUGO,
		.owner = THIS_MODULE,
	},
	.size = DS1511_RAM_MAX,
	.read = ds1511_nvram_read,
	.write = ds1511_nvram_write,
};

 static int __devinit
ds1511_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	struct rtc_plat_data *pdata = NULL;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		return -ENODEV;
	}
	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		return -ENOMEM;
	}
	pdata->irq = -1;
	pdata->size = res->end - res->start + 1;
	if (!request_mem_region(res->start, pdata->size, pdev->name)) {
		ret = -EBUSY;
		goto out;
	}
	pdata->baseaddr = res->start;
	pdata->size = pdata->size;
	ds1511_base = ioremap(pdata->baseaddr, pdata->size);
	if (!ds1511_base) {
		ret = -ENOMEM;
		goto out;
	}
	pdata->ioaddr = ds1511_base;
	pdata->irq = platform_get_irq(pdev, 0);

	/*
	 * turn on the clock and the crystal, etc.
	 */
	rtc_write(0, RTC_CMD);
	rtc_write(0, RTC_CMD1);
	/*
	 * clear the wdog counter
	 */
	rtc_write(0, DS1511_WD_MSEC);
	rtc_write(0, DS1511_WD_SEC);
	/*
	 * start the clock
	 */
	rtc_enable_update();

	/*
	 * check for a dying bat-tree
	 */
	if (rtc_read(RTC_CMD1) & DS1511_BLF1) {
		dev_warn(&pdev->dev, "voltage-low detected.\n");
	}

	/*
	 * if the platform has an interrupt in mind for this device,
	 * then by all means, set it
	 */
	if (pdata->irq >= 0) {
		rtc_read(RTC_CMD1);
		if (request_irq(pdata->irq, ds1511_interrupt,
			IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) {

			dev_warn(&pdev->dev, "interrupt not available.\n");
			pdata->irq = -1;
		}
	}

	rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops,
		THIS_MODULE);
	if (IS_ERR(rtc)) {
		ret = PTR_ERR(rtc);
		goto out;
	}
	pdata->rtc = rtc;
	platform_set_drvdata(pdev, pdata);
	ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
	if (ret) {
		goto out;
	}
	return 0;
 out:
	if (pdata->rtc) {
		rtc_device_unregister(pdata->rtc);
	}
	if (pdata->irq >= 0) {
		free_irq(pdata->irq, pdev);
	}
	if (ds1511_base) {
		iounmap(ds1511_base);
		ds1511_base = NULL;
	}
	if (pdata->baseaddr) {
		release_mem_region(pdata->baseaddr, pdata->size);
	}

	kfree(pdata);
	return ret;
}

 static int __devexit
ds1511_rtc_remove(struct platform_device *pdev)
{
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);

	sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
	rtc_device_unregister(pdata->rtc);
	pdata->rtc = NULL;
	if (pdata->irq >= 0) {
		/*
		 * disable the alarm interrupt
		 */
		rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD);
		rtc_read(RTC_CMD1);
		free_irq(pdata->irq, pdev);
	}
	iounmap(pdata->ioaddr);
	ds1511_base = NULL;
	release_mem_region(pdata->baseaddr, pdata->size);
	kfree(pdata);
	return 0;
}

/* work with hotplug and coldplug */
MODULE_ALIAS("platform:ds1511");

static struct platform_driver ds1511_rtc_driver = {
	.probe		= ds1511_rtc_probe,
	.remove		= __devexit_p(ds1511_rtc_remove),
	.driver		= {
		.name	= "ds1511",
		.owner	= THIS_MODULE,
	},
};

 static int __init
ds1511_rtc_init(void)
{
	return platform_driver_register(&ds1511_rtc_driver);
}

 static void __exit
ds1511_rtc_exit(void)
{
	return platform_driver_unregister(&ds1511_rtc_driver);
}

module_init(ds1511_rtc_init);
module_exit(ds1511_rtc_exit);

MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
