/*
 *  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 PCF8583 RTC & RAM chip
 */
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/bcd.h>

#include "pcf8583.h"

static struct i2c_driver pcf8583_driver;

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

static struct i2c_client_address_data addr_data = {
	.normal_i2c		= normal_addr,
	.normal_i2c_range	= ignore,
	.probe			= ignore,
	.probe_range		= ignore,
	.ignore			= ignore,
	.ignore_range		= ignore,
	.force			= ignore,
};

#define DAT(x) ((unsigned int)(x->dev.driver_data))

static int
pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
{
	struct i2c_client *c;
	unsigned char buf[1], ad[1] = { 0 };
	struct i2c_msg msgs[2] = {
		{ addr, 0,        1, ad  },
		{ addr, I2C_M_RD, 1, buf }
	};

	c = kmalloc(sizeof(*c), GFP_KERNEL);
	if (!c)
		return -ENOMEM;

	memset(c, 0, sizeof(*c));
	c->addr		= addr;
	c->adapter	= adap;
	c->driver	= &pcf8583_driver;

	if (i2c_transfer(c->adapter, msgs, 2) == 2)
		DAT(c) = buf[0];

	return i2c_attach_client(c);
}

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

static int
pcf8583_detach(struct i2c_client *client)
{
	i2c_detach_client(client);
	kfree(client);
	return 0;
}

static int
pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
{
	unsigned char buf[8], addr[1] = { 1 };
	struct i2c_msg msgs[2] = {
		{ client->addr, 0,        1, addr },
		{ client->addr, I2C_M_RD, 6, buf  }
	};
	int ret = -EIO;

	memset(buf, 0, sizeof(buf));

	ret = i2c_transfer(client->adapter, msgs, 2);
	if (ret == 2) {
		dt->year_off = buf[4] >> 6;
		dt->wday     = buf[5] >> 5;

		buf[4] &= 0x3f;
		buf[5] &= 0x1f;

		dt->cs       = BCD_TO_BIN(buf[0]);
		dt->secs     = BCD_TO_BIN(buf[1]);
		dt->mins     = BCD_TO_BIN(buf[2]);
		dt->hours    = BCD_TO_BIN(buf[3]);
		dt->mday     = BCD_TO_BIN(buf[4]);
		dt->mon      = BCD_TO_BIN(buf[5]);

		ret = 0;
	}

	return ret;
}

static int
pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
{
	unsigned char buf[8];
	int ret, len = 6;

	buf[0] = 0;
	buf[1] = DAT(client) | 0x80;
	buf[2] = BIN_TO_BCD(dt->cs);
	buf[3] = BIN_TO_BCD(dt->secs);
	buf[4] = BIN_TO_BCD(dt->mins);
	buf[5] = BIN_TO_BCD(dt->hours);

	if (datetoo) {
		len = 8;
		buf[6] = BIN_TO_BCD(dt->mday) | (dt->year_off << 6);
		buf[7] = BIN_TO_BCD(dt->mon)  | (dt->wday << 5);
	}

	ret = i2c_master_send(client, (char *)buf, len);
	if (ret == len)
		ret = 0;

	buf[1] = DAT(client);
	i2c_master_send(client, (char *)buf, 2);

	return ret;
}

static int
pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
{
	*ctrl = DAT(client);
	return 0;
}

static int
pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
{
	unsigned char buf[2];

	buf[0] = 0;
	buf[1] = *ctrl;
	DAT(client) = *ctrl;

	return i2c_master_send(client, (char *)buf, 2);
}

static int
pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
{
	unsigned char addr[1];
	struct i2c_msg msgs[2] = {
		{ client->addr, 0,        1, addr },
		{ client->addr, I2C_M_RD, 0, mem->data }
	};

	if (mem->loc < 8)
		return -EINVAL;

	addr[0] = mem->loc;
	msgs[1].len = mem->nr;

	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}

static int
pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
{
	unsigned char addr[1];
	struct i2c_msg msgs[2] = {
		{ client->addr, 0, 1, addr },
		{ client->addr, 0, 0, mem->data }
	};

	if (mem->loc < 8)
		return -EINVAL;

	addr[0] = mem->loc;
	msgs[1].len = mem->nr;

	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}

static int
pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
	switch (cmd) {
	case RTC_GETDATETIME:
		return pcf8583_get_datetime(client, arg);
		
	case RTC_SETTIME:
		return pcf8583_set_datetime(client, arg, 0);

	case RTC_SETDATETIME:
		return pcf8583_set_datetime(client, arg, 1);

	case RTC_GETCTRL:
		return pcf8583_get_ctrl(client, arg);

	case RTC_SETCTRL:
		return pcf8583_set_ctrl(client, arg);

	case MEM_READ:
		return pcf8583_read_mem(client, arg);

	case MEM_WRITE:
		return pcf8583_write_mem(client, arg);

	default:
		return -EINVAL;
	}
}

static struct i2c_driver pcf8583_driver = {
	.name		= "PCF8583",
	.id		= I2C_DRIVERID_PCF8583,
	.flags		= I2C_DF_NOTIFY,
	.attach_adapter	= pcf8583_probe,
	.detach_client	= pcf8583_detach,
	.command	= pcf8583_command
};

static __init int pcf8583_init(void)
{
	return i2c_add_driver(&pcf8583_driver);
}

__initcall(pcf8583_init);
