/*
 * An I2C driver for the PCF85063 RTC
 * Copyright 2014 Rose Technology
 *
 * Author: Søren Andersen <san@rosetechnology.dk>
 * Maintainers: http://www.nslu2-linux.org/
 *
 * based on the other drivers in this same directory.
 *
 * 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/module.h>

#define DRV_VERSION "0.0.1"

#define PCF85063_REG_CTRL1		0x00 /* status */
#define PCF85063_REG_CTRL2		0x01

#define PCF85063_REG_SC			0x04 /* datetime */
#define PCF85063_REG_MN			0x05
#define PCF85063_REG_HR			0x06
#define PCF85063_REG_DM			0x07
#define PCF85063_REG_DW			0x08
#define PCF85063_REG_MO			0x09
#define PCF85063_REG_YR			0x0A

#define PCF85063_MO_C			0x80 /* century */

static struct i2c_driver pcf85063_driver;

struct pcf85063 {
	struct rtc_device *rtc;
	int c_polarity;	/* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
	int voltage_low; /* indicates if a low_voltage was detected */
};

/*
 * In the routines that deal directly with the pcf85063 hardware, we use
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
 */
static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	struct pcf85063 *pcf85063 = i2c_get_clientdata(client);
	unsigned char buf[13] = { PCF85063_REG_CTRL1 };
	struct i2c_msg msgs[] = {
		{/* setup read ptr */
			.addr = client->addr,
			.len = 1,
			.buf = buf
		},
		{/* read status + date */
			.addr = client->addr,
			.flags = I2C_M_RD,
			.len = 13,
			.buf = buf
		},
	};

	/* read registers */
	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
		dev_err(&client->dev, "%s: read error\n", __func__);
		return -EIO;
	}

	tm->tm_sec = bcd2bin(buf[PCF85063_REG_SC] & 0x7F);
	tm->tm_min = bcd2bin(buf[PCF85063_REG_MN] & 0x7F);
	tm->tm_hour = bcd2bin(buf[PCF85063_REG_HR] & 0x3F); /* rtc hr 0-23 */
	tm->tm_mday = bcd2bin(buf[PCF85063_REG_DM] & 0x3F);
	tm->tm_wday = buf[PCF85063_REG_DW] & 0x07;
	tm->tm_mon = bcd2bin(buf[PCF85063_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
	tm->tm_year = bcd2bin(buf[PCF85063_REG_YR]);
	if (tm->tm_year < 70)
		tm->tm_year += 100;	/* assume we are in 1970...2069 */
	/* detect the polarity heuristically. see note above. */
	pcf85063->c_polarity = (buf[PCF85063_REG_MO] & PCF85063_MO_C) ?
		(tm->tm_year >= 100) : (tm->tm_year < 100);

	return rtc_valid_tm(tm);
}

static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	int i = 0, err = 0;
	unsigned char buf[11];

	/* Control & status */
	buf[PCF85063_REG_CTRL1] = 0;
	buf[PCF85063_REG_CTRL2] = 5;

	/* hours, minutes and seconds */
	buf[PCF85063_REG_SC] = bin2bcd(tm->tm_sec) & 0x7F;

	buf[PCF85063_REG_MN] = bin2bcd(tm->tm_min);
	buf[PCF85063_REG_HR] = bin2bcd(tm->tm_hour);

	/* Day of month, 1 - 31 */
	buf[PCF85063_REG_DM] = bin2bcd(tm->tm_mday);

	/* Day, 0 - 6 */
	buf[PCF85063_REG_DW] = tm->tm_wday & 0x07;

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

	/* year and century */
	buf[PCF85063_REG_YR] = bin2bcd(tm->tm_year % 100);

	/* write register's data */
	for (i = 0; i < sizeof(buf); i++) {
		unsigned char data[2] = { i, buf[i] };

		err = i2c_master_send(client, data, sizeof(data));
		if (err != sizeof(data)) {
			dev_err(&client->dev, "%s: err=%d addr=%02x, data=%02x\n",
					__func__, err, data[0], data[1]);
			return -EIO;
		}
	}

	return 0;
}

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

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

static const struct rtc_class_ops pcf85063_rtc_ops = {
	.read_time	= pcf85063_rtc_read_time,
	.set_time	= pcf85063_rtc_set_time
};

static int pcf85063_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct pcf85063 *pcf85063;

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

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

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

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

	i2c_set_clientdata(client, pcf85063);

	pcf85063->rtc = devm_rtc_device_register(&client->dev,
				pcf85063_driver.driver.name,
				&pcf85063_rtc_ops, THIS_MODULE);

	return PTR_ERR_OR_ZERO(pcf85063->rtc);
}

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

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

static struct i2c_driver pcf85063_driver = {
	.driver		= {
		.name	= "rtc-pcf85063",
		.of_match_table = of_match_ptr(pcf85063_of_match),
	},
	.probe		= pcf85063_probe,
	.id_table	= pcf85063_id,
};

module_i2c_driver(pcf85063_driver);

MODULE_AUTHOR("Søren Andersen <san@rosetechnology.dk>");
MODULE_DESCRIPTION("PCF85063 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
