/*
 * An I2C driver for the NXP PCF2127 RTC
 * Copyright 2013 Til-Technologies
 *
 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
 *
 * based on the other drivers in this same directory.
 *
 * http://www.nxp.com/documents/data_sheet/PCF2127AT.pdf
 *
 * 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/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of.h>

#define DRV_VERSION "0.0.1"

#define PCF2127_REG_CTRL1       (0x00)  /* Control Register 1 */
#define PCF2127_REG_CTRL2       (0x01)  /* Control Register 2 */
#define PCF2127_REG_CTRL3       (0x02)  /* Control Register 3 */
#define PCF2127_REG_SC          (0x03)  /* datetime */
#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)

#define PCF2127_OSF             BIT(7)  /* Oscillator Fail flag */

static struct i2c_driver pcf2127_driver;

struct pcf2127 {
	struct rtc_device *rtc;
	int voltage_low; /* indicates if a low_voltage was detected */
	int oscillator_failed; /* OSF was detected and date is unreliable */
};

/*
 * In the routines that deal directly with the pcf2127 hardware, we use
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
 */
static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	struct pcf2127 *pcf2127 = i2c_get_clientdata(client);
	unsigned char buf[10] = { PCF2127_REG_CTRL1 };

	/* read registers */
	if (i2c_master_send(client, buf, 1) != 1 ||
		i2c_master_recv(client, buf, sizeof(buf)) != sizeof(buf)) {
		dev_err(&client->dev, "%s: read error\n", __func__);
		return -EIO;
	}

	if (buf[PCF2127_REG_CTRL3] & 0x04) {
		pcf2127->voltage_low = 1;
		dev_info(&client->dev,
			"low voltage detected, check/replace RTC battery.\n");
	}

	if (buf[PCF2127_REG_SC] & PCF2127_OSF) {
		/*
		 * no need clear the flag here,
		 * it will be cleared once the new date is saved
		 */
		pcf2127->oscillator_failed = 1;
		dev_warn(&client->dev,
			 "oscillator stop detected, date/time is not reliable\n");
		return -EINVAL;
	}

	dev_dbg(&client->dev,
		"%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, "
		"sec=%02x, min=%02x, hr=%02x, "
		"mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
		__func__,
		buf[0], buf[1], buf[2],
		buf[3], buf[4], buf[5],
		buf[6], buf[7], buf[8], buf[9]);


	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); /* rtc hr 0-23 */
	tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
	tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
	tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
	tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
	if (tm->tm_year < 70)
		tm->tm_year += 100;	/* assume we are in 1970...2069 */

	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	return rtc_valid_tm(tm);
}

static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	struct pcf2127 *pcf2127 = i2c_get_clientdata(client);
	unsigned char buf[8];
	int i = 0, err;

	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	/* start register address */
	buf[i++] = PCF2127_REG_SC;

	/* hours, minutes and seconds */
	buf[i++] = bin2bcd(tm->tm_sec);	/* this will also clear OSF flag */
	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 + 1);

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

	/* write register's data */
	err = i2c_master_send(client, buf, i);
	if (err != i) {
		dev_err(&client->dev,
			"%s: err=%d", __func__, err);
		return -EIO;
	}

	/* clear OSF flag in client data */
	pcf2127->oscillator_failed = 0;

	return 0;
}

#ifdef CONFIG_RTC_INTF_DEV
static int pcf2127_rtc_ioctl(struct device *dev,
				unsigned int cmd, unsigned long arg)
{
	struct pcf2127 *pcf2127 = i2c_get_clientdata(to_i2c_client(dev));

	switch (cmd) {
	case RTC_VL_READ:
		if (pcf2127->voltage_low)
			dev_info(dev, "low voltage detected, check/replace battery\n");
		if (pcf2127->oscillator_failed)
			dev_info(dev, "oscillator stop detected, date/time is not reliable\n");

		if (copy_to_user((void __user *)arg, &pcf2127->voltage_low,
					sizeof(int)))
			return -EFAULT;
		return 0;
	default:
		return -ENOIOCTLCMD;
	}
}
#else
#define pcf2127_rtc_ioctl NULL
#endif

static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	return pcf2127_get_datetime(to_i2c_client(dev), tm);
}

static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	return pcf2127_set_datetime(to_i2c_client(dev), tm);
}

static const struct rtc_class_ops pcf2127_rtc_ops = {
	.ioctl		= pcf2127_rtc_ioctl,
	.read_time	= pcf2127_rtc_read_time,
	.set_time	= pcf2127_rtc_set_time,
};

static int pcf2127_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct pcf2127 *pcf2127;

	dev_dbg(&client->dev, "%s\n", __func__);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -ENODEV;

	pcf2127 = devm_kzalloc(&client->dev, sizeof(struct pcf2127),
				GFP_KERNEL);
	if (!pcf2127)
		return -ENOMEM;

	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");

	i2c_set_clientdata(client, pcf2127);

	pcf2127->rtc = devm_rtc_device_register(&client->dev,
				pcf2127_driver.driver.name,
				&pcf2127_rtc_ops, THIS_MODULE);

	return PTR_ERR_OR_ZERO(pcf2127->rtc);
}

static const struct i2c_device_id pcf2127_id[] = {
	{ "pcf2127", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, pcf2127_id);

#ifdef CONFIG_OF
static const struct of_device_id pcf2127_of_match[] = {
	{ .compatible = "nxp,pcf2127" },
	{}
};
MODULE_DEVICE_TABLE(of, pcf2127_of_match);
#endif

static struct i2c_driver pcf2127_driver = {
	.driver		= {
		.name	= "rtc-pcf2127",
		.of_match_table = of_match_ptr(pcf2127_of_match),
	},
	.probe		= pcf2127_probe,
	.id_table	= pcf2127_id,
};

module_i2c_driver(pcf2127_driver);

MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");
MODULE_DESCRIPTION("NXP PCF2127 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
