/*
 *  linux/drivers/i2c/chips/ds1337.c
 *
 *  Copyright (C) 2005 James Chapman <jchapman@katalix.com>
 *
 *	based on linux/drivers/acorn/char/pcf8583.c
 *  Copyright (C) 2000 Russell King
 *
 * 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 Dallas Semiconductor DS1337 and DS1339 real time clock chip
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/string.h>
#include <linux/rtc.h>		/* get the user-level API */
#include <linux/bcd.h>
#include <linux/list.h>

/* Device registers */
#define DS1337_REG_HOUR		2
#define DS1337_REG_DAY		3
#define DS1337_REG_DATE		4
#define DS1337_REG_MONTH	5
#define DS1337_REG_CONTROL	14
#define DS1337_REG_STATUS	15

/* FIXME - how do we export these interface constants? */
#define DS1337_GET_DATE		0
#define DS1337_SET_DATE		1

/*
 * Functions declaration
 */
static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };

I2C_CLIENT_INSMOD_1(ds1337);

static int ds1337_attach_adapter(struct i2c_adapter *adapter);
static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind);
static void ds1337_init_client(struct i2c_client *client);
static int ds1337_detach_client(struct i2c_client *client);
static int ds1337_command(struct i2c_client *client, unsigned int cmd,
			  void *arg);

/*
 * Driver data (common to all clients)
 */
static struct i2c_driver ds1337_driver = {
	.owner		= THIS_MODULE,
	.name		= "ds1337",
	.flags		= I2C_DF_NOTIFY,
	.attach_adapter	= ds1337_attach_adapter,
	.detach_client	= ds1337_detach_client,
	.command	= ds1337_command,
};

/*
 * Client data (each client gets its own)
 */
struct ds1337_data {
	struct i2c_client client;
	struct list_head list;
};

/*
 * Internal variables
 */
static LIST_HEAD(ds1337_clients);

static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
{
	s32 tmp = i2c_smbus_read_byte_data(client, reg);

	if (tmp < 0)
		return -EIO;

	*value = tmp;

	return 0;
}

/*
 * Chip access functions
 */
static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
{
	int result;
	u8 buf[7];
	u8 val;
	struct i2c_msg msg[2];
	u8 offs = 0;

	if (!dt) {
		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
		return -EINVAL;
	}

	msg[0].addr = client->addr;
	msg[0].flags = 0;
	msg[0].len = 1;
	msg[0].buf = &offs;

	msg[1].addr = client->addr;
	msg[1].flags = I2C_M_RD;
	msg[1].len = sizeof(buf);
	msg[1].buf = &buf[0];

	result = i2c_transfer(client->adapter, msg, 2);

	dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
		__FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
		buf[4], buf[5], buf[6]);

	if (result == 2) {
		dt->tm_sec = BCD2BIN(buf[0]);
		dt->tm_min = BCD2BIN(buf[1]);
		val = buf[2] & 0x3f;
		dt->tm_hour = BCD2BIN(val);
		dt->tm_wday = BCD2BIN(buf[3]) - 1;
		dt->tm_mday = BCD2BIN(buf[4]);
		val = buf[5] & 0x7f;
		dt->tm_mon = BCD2BIN(val) - 1;
		dt->tm_year = BCD2BIN(buf[6]);
		if (buf[5] & 0x80)
			dt->tm_year += 100;

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

		return 0;
	}

	dev_err(&client->dev, "error reading data! %d\n", result);
	return -EIO;
}

static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
{
	int result;
	u8 buf[8];
	u8 val;
	struct i2c_msg msg[1];

	if (!dt) {
		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
		return -EINVAL;
	}

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

	buf[0] = 0;		/* reg offset */
	buf[1] = BIN2BCD(dt->tm_sec);
	buf[2] = BIN2BCD(dt->tm_min);
	buf[3] = BIN2BCD(dt->tm_hour);
	buf[4] = BIN2BCD(dt->tm_wday) + 1;
	buf[5] = BIN2BCD(dt->tm_mday);
	buf[6] = BIN2BCD(dt->tm_mon) + 1;
	val = dt->tm_year;
	if (val >= 100) {
		val -= 100;
		buf[6] |= (1 << 7);
	}
	buf[7] = BIN2BCD(val);

	msg[0].addr = client->addr;
	msg[0].flags = 0;
	msg[0].len = sizeof(buf);
	msg[0].buf = &buf[0];

	result = i2c_transfer(client->adapter, msg, 1);
	if (result == 1)
		return 0;

	dev_err(&client->dev, "error writing data! %d\n", result);
	return -EIO;
}

static int ds1337_command(struct i2c_client *client, unsigned int cmd,
			  void *arg)
{
	dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);

	switch (cmd) {
	case DS1337_GET_DATE:
		return ds1337_get_datetime(client, arg);

	case DS1337_SET_DATE:
		return ds1337_set_datetime(client, arg);

	default:
		return -EINVAL;
	}
}

/*
 * Public API for access to specific device. Useful for low-level
 * RTC access from kernel code.
 */
int ds1337_do_command(int bus, int cmd, void *arg)
{
	struct list_head *walk;
	struct list_head *tmp;
	struct ds1337_data *data;

	list_for_each_safe(walk, tmp, &ds1337_clients) {
		data = list_entry(walk, struct ds1337_data, list);
		if (data->client.adapter->nr == bus)
			return ds1337_command(&data->client, cmd, arg);
	}

	return -ENODEV;
}

static int ds1337_attach_adapter(struct i2c_adapter *adapter)
{
	return i2c_probe(adapter, &addr_data, ds1337_detect);
}

/*
 * The following function does more than just detection. If detection
 * succeeds, it also registers the new chip.
 */
static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
{
	struct i2c_client *new_client;
	struct ds1337_data *data;
	int err = 0;
	const char *name = "";

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
				     I2C_FUNC_I2C))
		goto exit;

	if (!(data = kmalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}
	memset(data, 0, sizeof(struct ds1337_data));
	INIT_LIST_HEAD(&data->list);

	/* The common I2C client data is placed right before the
	 * DS1337-specific data. 
	 */
	new_client = &data->client;
	i2c_set_clientdata(new_client, data);
	new_client->addr = address;
	new_client->adapter = adapter;
	new_client->driver = &ds1337_driver;
	new_client->flags = 0;

	/*
	 * Now we do the remaining detection. A negative kind means that
	 * the driver was loaded with no force parameter (default), so we
	 * must both detect and identify the chip. A zero kind means that
	 * the driver was loaded with the force parameter, the detection
	 * step shall be skipped. A positive kind means that the driver
	 * was loaded with the force parameter and a given kind of chip is
	 * requested, so both the detection and the identification steps
	 * are skipped.
	 *
	 * For detection, we read registers that are most likely to cause
	 * detection failure, i.e. those that have more bits with fixed
	 * or reserved values.
	 */

	/* Default to an DS1337 if forced */
	if (kind == 0)
		kind = ds1337;

	if (kind < 0) {		/* detection and identification */
		u8 data;

		/* Check that status register bits 6-2 are zero */
		if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) ||
		    (data & 0x7c))
			goto exit_free;

		/* Check for a valid day register value */
		if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) ||
		    (data == 0) || (data & 0xf8))
			goto exit_free;

		/* Check for a valid date register value */
		if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) ||
		    (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) ||
		    (data >= 0x32))
			goto exit_free;

		/* Check for a valid month register value */
		if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) ||
		    (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) ||
		    ((data >= 0x13) && (data <= 0x19)))
			goto exit_free;

		/* Check that control register bits 6-5 are zero */
		if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) ||
		    (data & 0x60))
			goto exit_free;

		kind = ds1337;
	}

	if (kind == ds1337)
		name = "ds1337";

	/* We can fill in the remaining client fields */
	strlcpy(new_client->name, name, I2C_NAME_SIZE);

	/* Tell the I2C layer a new client has arrived */
	if ((err = i2c_attach_client(new_client)))
		goto exit_free;

	/* Initialize the DS1337 chip */
	ds1337_init_client(new_client);

	/* Add client to local list */
	list_add(&data->list, &ds1337_clients);

	return 0;

exit_free:
	kfree(data);
exit:
	return err;
}

static void ds1337_init_client(struct i2c_client *client)
{
	s32 val;

	/* Ensure that device is set in 24-hour mode */
	val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
	if ((val >= 0) && (val & (1 << 6)))
		i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
					  val & 0x3f);
}

static int ds1337_detach_client(struct i2c_client *client)
{
	int err;
	struct ds1337_data *data = i2c_get_clientdata(client);

	if ((err = i2c_detach_client(client)))
		return err;

	list_del(&data->list);
	kfree(data);
	return 0;
}

static int __init ds1337_init(void)
{
	return i2c_add_driver(&ds1337_driver);
}

static void __exit ds1337_exit(void)
{
	i2c_del_driver(&ds1337_driver);
}

MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
MODULE_DESCRIPTION("DS1337 RTC driver");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL_GPL(ds1337_do_command);

module_init(ds1337_init);
module_exit(ds1337_exit);
