/*
 * Copyright (C) 2016 by NXP Semiconductors Inc.
 * Date & Time support for PCF2127 RTC
 */

/*	#define	DEBUG	*/

#include <common.h>
#include <command.h>
#include <dm.h>
#include <i2c.h>
#include <rtc.h>

#define PCF2127_REG_CTRL1	0x00
#define PCF2127_REG_CTRL2	0x01
#define PCF2127_REG_CTRL3	0x02
#define PCF2127_REG_SC		0x03
#define PCF2127_REG_MN		0x04
#define PCF2127_REG_HR		0x05
#define PCF2127_REG_DM		0x06
#define PCF2127_REG_DW		0x07
#define PCF2127_REG_MO		0x08
#define PCF2127_REG_YR		0x09

static int pcf2127_read_reg(struct udevice *dev, uint offset,
			    u8 *buffer, int len)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
	struct i2c_msg msg;
	int ret;

	/* Set the address of the start register to be read */
	ret = dm_i2c_write(dev, offset, NULL, 0);
	if (ret < 0)
		return ret;

	/* Read register's data */
	msg.addr = chip->chip_addr;
	msg.flags |= I2C_M_RD;
	msg.len = len;
	msg.buf = buffer;

	return dm_i2c_xfer(dev, &msg, 1);
}

static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm)
{
	uchar buf[7] = {0};
	int i = 0, ret;

	/* hours, minutes and seconds */
	buf[i++] = bin2bcd(tm->tm_sec);
	buf[i++] = bin2bcd(tm->tm_min);
	buf[i++] = bin2bcd(tm->tm_hour);
	buf[i++] = bin2bcd(tm->tm_mday);
	buf[i++] = tm->tm_wday & 0x07;

	/* month, 1 - 12 */
	buf[i++] = bin2bcd(tm->tm_mon);

	/* year */
	buf[i++] = bin2bcd(tm->tm_year % 100);

	/* write register's data */
	ret = dm_i2c_write(dev, PCF2127_REG_SC, buf, i);

	return ret;
}

static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm)
{
	int ret = 0;
	uchar buf[10] = { PCF2127_REG_CTRL1 };

	ret = pcf2127_read_reg(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
	if (ret < 0)
		return ret;

	if (buf[PCF2127_REG_CTRL3] & 0x04)
		puts("### Warning: RTC Low Voltage - date/time not reliable\n");

	tm->tm_sec  = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
	tm->tm_min  = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
	tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F);
	tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
	tm->tm_mon  = bcd2bin(buf[PCF2127_REG_MO] & 0x1F);
	tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]) + 1900;
	if (tm->tm_year < 1970)
		tm->tm_year += 100;	/* assume we are in 1970...2069 */
	tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
	tm->tm_yday = 0;
	tm->tm_isdst = 0;

	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
	      tm->tm_hour, tm->tm_min, tm->tm_sec);

	return ret;
}

static int pcf2127_rtc_reset(struct udevice *dev)
{
	/*Doing nothing here*/

	return 0;
}

static const struct rtc_ops pcf2127_rtc_ops = {
	.get = pcf2127_rtc_get,
	.set = pcf2127_rtc_set,
	.reset = pcf2127_rtc_reset,
};

static const struct udevice_id pcf2127_rtc_ids[] = {
	{ .compatible = "pcf2127-rtc" },
	{ }
};

U_BOOT_DRIVER(rtc_pcf2127) = {
	.name	= "rtc-pcf2127",
	.id	= UCLASS_RTC,
	.of_match = pcf2127_rtc_ids,
	.ops	= &pcf2127_rtc_ops,
};
