/* drivers/rtc/rtc-max6902.c
 *
 * Copyright (C) 2006 8D Technologies inc.
 * Copyright (C) 2004 Compulab Ltd.
 *
 * 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.
 *
 * Driver for MAX6902 spi RTC
 *
 * Changelog:
 *
 * 24-May-2006: Raphael Assenat <raph@8d.com>
 *                - Major rework
 *   				Converted to rtc_device and uses the SPI layer.
 *
 * ??-???-2005: Someone at Compulab
 *                - Initial driver creation.
 */

#include <linux/module.h>
#include <linux/version.h>

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

#define MAX6902_REG_SECONDS		0x01
#define MAX6902_REG_MINUTES		0x03
#define MAX6902_REG_HOURS		0x05
#define MAX6902_REG_DATE		0x07
#define MAX6902_REG_MONTH		0x09
#define MAX6902_REG_DAY			0x0B
#define MAX6902_REG_YEAR		0x0D
#define MAX6902_REG_CONTROL		0x0F
#define MAX6902_REG_CENTURY		0x13

#undef MAX6902_DEBUG

struct max6902 {
	struct rtc_device *rtc;
	u8 buf[9]; /* Burst read cmd + 8 registers */
	u8 tx_buf[2];
	u8 rx_buf[2];
};

static void max6902_set_reg(struct device *dev, unsigned char address,
				unsigned char data)
{
	struct spi_device *spi = to_spi_device(dev);
	unsigned char buf[2];

	/* MSB must be '0' to write */
	buf[0] = address & 0x7f;
	buf[1] = data;

	spi_write(spi, buf, 2);
}

static int max6902_get_reg(struct device *dev, unsigned char address,
				unsigned char *data)
{
	struct spi_device *spi = to_spi_device(dev);
	struct max6902 *chip = dev_get_drvdata(dev);
	struct spi_message message;
	struct spi_transfer xfer;
	int status;

	if (!data)
		return -EINVAL;

	/* Build our spi message */
	spi_message_init(&message);
	memset(&xfer, 0, sizeof(xfer));
	xfer.len = 2;
	/* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */
	xfer.tx_buf = chip->tx_buf;
	xfer.rx_buf = chip->rx_buf;

	/* Set MSB to indicate read */
	chip->tx_buf[0] = address | 0x80;

	spi_message_add_tail(&xfer, &message);

	/* do the i/o */
	status = spi_sync(spi, &message);
	if (status == 0)
		status = message.status;
	else
		return status;

	*data = chip->rx_buf[1];

	return status;
}

static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
{
	unsigned char tmp;
	int century;
	int err;
	struct spi_device *spi = to_spi_device(dev);
	struct max6902 *chip = dev_get_drvdata(dev);
	struct spi_message message;
	struct spi_transfer xfer;
	int status;

	err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp);
	if (err)
		return err;

	/* build the message */
	spi_message_init(&message);
	memset(&xfer, 0, sizeof(xfer));
	xfer.len = 1 + 7;	/* Burst read command + 7 registers */
	xfer.tx_buf = chip->buf;
	xfer.rx_buf = chip->buf;
	chip->buf[0] = 0xbf;	/* Burst read */
	spi_message_add_tail(&xfer, &message);

	/* do the i/o */
	status = spi_sync(spi, &message);
	if (status == 0)
		status = message.status;
	else
		return status;

	/* The chip sends data in this order:
	 * Seconds, Minutes, Hours, Date, Month, Day, Year */
	dt->tm_sec	= BCD2BIN(chip->buf[1]);
	dt->tm_min	= BCD2BIN(chip->buf[2]);
	dt->tm_hour	= BCD2BIN(chip->buf[3]);
	dt->tm_mday	= BCD2BIN(chip->buf[4]);
	dt->tm_mon	= BCD2BIN(chip->buf[5] - 1);
	dt->tm_wday	= BCD2BIN(chip->buf[6]);
	dt->tm_year = BCD2BIN(chip->buf[7]);

	century = BCD2BIN(tmp) * 100;

	dt->tm_year += century;
	dt->tm_year -= 1900;

#ifdef MAX6902_DEBUG
	printk("\n%s : Read RTC values\n",__FUNCTION__);
	printk("tm_hour: %i\n",dt->tm_hour);
	printk("tm_min : %i\n",dt->tm_min);
	printk("tm_sec : %i\n",dt->tm_sec);
	printk("tm_year: %i\n",dt->tm_year);
	printk("tm_mon : %i\n",dt->tm_mon);
	printk("tm_mday: %i\n",dt->tm_mday);
	printk("tm_wday: %i\n",dt->tm_wday);
#endif

	return 0;
}

static int max6902_set_datetime(struct device *dev, struct rtc_time *dt)
{
	dt->tm_year = dt->tm_year+1900;

#ifdef MAX6902_DEBUG
	printk("\n%s : Setting RTC values\n",__FUNCTION__);
	printk("tm_sec : %i\n",dt->tm_sec);
	printk("tm_min : %i\n",dt->tm_min);
	printk("tm_hour: %i\n",dt->tm_hour);
	printk("tm_mday: %i\n",dt->tm_mday);
	printk("tm_wday: %i\n",dt->tm_wday);
	printk("tm_year: %i\n",dt->tm_year);
#endif

	/* Remove write protection */
	max6902_set_reg(dev, 0xF, 0);

	max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec));
	max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min));
	max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour));

	max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday));
	max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1));
	max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday));
	max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100));
	max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100));

	/* Compulab used a delay here. However, the datasheet
	 * does not mention a delay being required anywhere... */
	/* delay(2000); */

	/* Write protect */
	max6902_set_reg(dev, 0xF, 0x80);

	return 0;
}

static int max6902_read_time(struct device *dev, struct rtc_time *tm)
{
	return max6902_get_datetime(dev, tm);
}

static int max6902_set_time(struct device *dev, struct rtc_time *tm)
{
	return max6902_set_datetime(dev, tm);
}

static const struct rtc_class_ops max6902_rtc_ops = {
	.read_time	= max6902_read_time,
	.set_time	= max6902_set_time,
};

static int __devinit max6902_probe(struct spi_device *spi)
{
	struct rtc_device *rtc;
	unsigned char tmp;
	struct max6902 *chip;
	int res;

	rtc = rtc_device_register("max6902",
				&spi->dev, &max6902_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc))
		return PTR_ERR(rtc);

	spi->mode = SPI_MODE_3;
	spi->bits_per_word = 8;
	spi_setup(spi);

	chip = kzalloc(sizeof *chip, GFP_KERNEL);
	if (!chip) {
		rtc_device_unregister(rtc);
		return -ENOMEM;
	}
	chip->rtc = rtc;
	dev_set_drvdata(&spi->dev, chip);

	res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp);
	if (res) {
		rtc_device_unregister(rtc);
		return res;
	}

	return 0;
}

static int __devexit max6902_remove(struct spi_device *spi)
{
	struct max6902 *chip = platform_get_drvdata(spi);
	struct rtc_device *rtc = chip->rtc;

	if (rtc)
		rtc_device_unregister(rtc);

	kfree(chip);

	return 0;
}

static struct spi_driver max6902_driver = {
	.driver = {
		.name 	= "max6902",
		.bus	= &spi_bus_type,
		.owner	= THIS_MODULE,
	},
	.probe 	= max6902_probe,
	.remove = __devexit_p(max6902_remove),
};

static __init int max6902_init(void)
{
	printk("max6902 spi driver\n");
	return spi_register_driver(&max6902_driver);
}
module_init(max6902_init);

static __exit void max6902_exit(void)
{
	spi_unregister_driver(&max6902_driver);
}
module_exit(max6902_exit);

MODULE_DESCRIPTION ("max6902 spi RTC driver");
MODULE_AUTHOR ("Raphael Assenat");
MODULE_LICENSE ("GPL");
