/*
 * 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>
#include <linux/workqueue.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 ulong new_time;

static void ds1374_set_work(struct work_struct *work)
{
	ulong t1, t2;
	int limit = 10;		/* arbitrary retry limit */

	t1 = new_time;

	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 struct workqueue_struct *ds1374_workqueue;

static DECLARE_WORK(ds1374_work, ds1374_set_work);

int ds1374_set_rtc_time(ulong nowtime)
{
	new_time = nowtime;

	if (in_interrupt())
		queue_work(ds1374_workqueue, &ds1374_work);
	else
		ds1374_set_work(NULL);

	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;

	ds1374_workqueue = create_singlethread_workqueue("ds1374");

	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));
		destroy_workqueue(ds1374_workqueue);
	}
	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");
