/*
 * drivers/i2c/chips/ds1374.c
 *
 * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock
 *
 * Author: Randy Vinson <rvinson@mvista.com>
 *
 * Based on the m41t00.c by Mark Greer <mgreer@mvista.com>
 *
 * 2005 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */
/*
 * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
 * interface and the SMBus interface of the i2c subsystem.
 * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
 * recommened in .../Documentation/i2c/writing-clients section
 * "Sending and receiving", using SMBus level communication is preferred.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mutex.h>

#define DS1374_REG_TOD0		0x00
#define DS1374_REG_TOD1		0x01
#define DS1374_REG_TOD2		0x02
#define DS1374_REG_TOD3		0x03
#define DS1374_REG_WDALM0	0x04
#define DS1374_REG_WDALM1	0x05
#define DS1374_REG_WDALM2	0x06
#define DS1374_REG_CR		0x07
#define DS1374_REG_SR		0x08
#define DS1374_REG_SR_OSF	0x80
#define DS1374_REG_TCR		0x09

#define	DS1374_DRV_NAME		"ds1374"

static DEFINE_MUTEX(ds1374_mutex);

static struct i2c_driver ds1374_driver;
static struct i2c_client *save_client;

static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };

static struct i2c_client_address_data addr_data = {
	.normal_i2c = normal_addr,
	.probe = ignore,
	.ignore = ignore,
};

static ulong ds1374_read_rtc(void)
{
	ulong time = 0;
	int reg = DS1374_REG_WDALM0;

	while (reg--) {
		s32 tmp;
		if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) {
			dev_warn(&save_client->dev,
				 "can't read from rtc chip\n");
			return 0;
		}
		time = (time << 8) | (tmp & 0xff);
	}
	return time;
}

static void ds1374_write_rtc(ulong time)
{
	int reg;

	for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) {
		if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff)
		    < 0) {
			dev_warn(&save_client->dev,
				 "can't write to rtc chip\n");
			break;
		}
		time = time >> 8;
	}
}

static void ds1374_check_rtc_status(void)
{
	s32 tmp;

	tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR);
	if (tmp < 0) {
		dev_warn(&save_client->dev,
			 "can't read status from rtc chip\n");
		return;
	}
	if (tmp & DS1374_REG_SR_OSF) {
		dev_warn(&save_client->dev,
			 "oscillator discontinuity flagged, time unreliable\n");
		tmp &= ~DS1374_REG_SR_OSF;
		tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR,
						tmp & 0xff);
		if (tmp < 0)
			dev_warn(&save_client->dev,
				 "can't clear discontinuity notification\n");
	}
}

ulong ds1374_get_rtc_time(void)
{
	ulong t1, t2;
	int limit = 10;		/* arbitrary retry limit */

	mutex_lock(&ds1374_mutex);

	/*
	 * Since the reads are being performed one byte at a time using
	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
	 * carry will occur during the read. To detect this, 2 reads are
	 * performed and compared.
	 */
	do {
		t1 = ds1374_read_rtc();
		t2 = ds1374_read_rtc();
	} while (t1 != t2 && limit--);

	mutex_unlock(&ds1374_mutex);

	if (t1 != t2) {
		dev_warn(&save_client->dev,
			 "can't get consistent time from rtc chip\n");
		t1 = 0;
	}

	return t1;
}

static void ds1374_set_tlet(ulong arg)
{
	ulong t1, t2;
	int limit = 10;		/* arbitrary retry limit */

	t1 = *(ulong *) arg;

	mutex_lock(&ds1374_mutex);

	/*
	 * Since the writes are being performed one byte at a time using
	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
	 * carry will occur during the write. To detect this, the write
	 * value is read back and compared.
	 */
	do {
		ds1374_write_rtc(t1);
		t2 = ds1374_read_rtc();
	} while (t1 != t2 && limit--);

	mutex_unlock(&ds1374_mutex);

	if (t1 != t2)
		dev_warn(&save_client->dev,
			 "can't confirm time set from rtc chip\n");
}

static ulong new_time;

static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet,
				(ulong) & new_time);

int ds1374_set_rtc_time(ulong nowtime)
{
	new_time = nowtime;

	if (in_interrupt())
		tasklet_schedule(&ds1374_tasklet);
	else
		ds1374_set_tlet((ulong) & new_time);

	return 0;
}

/*
 *****************************************************************************
 *
 *	Driver Interface
 *
 *****************************************************************************
 */
static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
{
	struct i2c_client *client;
	int rc;

	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
	if (!client)
		return -ENOMEM;

	strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
	client->addr = addr;
	client->adapter = adap;
	client->driver = &ds1374_driver;

	if ((rc = i2c_attach_client(client)) != 0) {
		kfree(client);
		return rc;
	}

	save_client = client;

	ds1374_check_rtc_status();

	return 0;
}

static int ds1374_attach(struct i2c_adapter *adap)
{
	return i2c_probe(adap, &addr_data, ds1374_probe);
}

static int ds1374_detach(struct i2c_client *client)
{
	int rc;

	if ((rc = i2c_detach_client(client)) == 0) {
		kfree(i2c_get_clientdata(client));
		tasklet_kill(&ds1374_tasklet);
	}
	return rc;
}

static struct i2c_driver ds1374_driver = {
	.driver = {
		.name	= DS1374_DRV_NAME,
	},
	.id = I2C_DRIVERID_DS1374,
	.attach_adapter = ds1374_attach,
	.detach_client = ds1374_detach,
};

static int __init ds1374_init(void)
{
	return i2c_add_driver(&ds1374_driver);
}

static void __exit ds1374_exit(void)
{
	i2c_del_driver(&ds1374_driver);
}

module_init(ds1374_init);
module_exit(ds1374_exit);

MODULE_AUTHOR("Randy Vinson <rvinson@mvista.com>");
MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver");
MODULE_LICENSE("GPL");
